ShadowsocksR Proxy: Binding Data Exit IP to Data Entry IP
func (ssr *ShadowsocksRProxy) StartTCP() error { return ssr.ListenTCP(func(request *network.Request) { localIP := request.Conn.LocalAddr().(*net.TCPAddr).IP ssrd, err := network.NewShadowsocksRDecorate(request, ssr.Obfs, ssr.Method, ssr.Password, ssr.Protocol, ssr.ObfsParam, ssr.ProtocolParam, localIP, ssr.Port, false, ssr.Single, ssr.Users) if err != nil { logrus.WithFields(logrus.Fields{ 'requestId': request.RequestID, 'error': err, }).Error('shadowsocksr NewShadowsocksRDecorate error') return } ssrd.TrafficReport = ssr.TrafficReport ssrd.SetLimter(ssr.ILimiter) go func() { defer func() { if err := recover(); err != nil { logrus.WithFields(logrus.Fields{ 'requestId': request.RequestID, }).Errorf('shadowsocksr connection read error :%v stack: %s', err, string(debug.Stack())) } }() defer ssrd.Close() addr, err := socksproxy.ReadAddr(ssrd) if err != nil { logrus.WithFields(logrus.Fields{ 'requestId': ssrd.RequestID, }).Errorf('shadowsocksr read address error %s', err) return } ssr.handleStageAddr(ssrd.UID, ssrd.RemoteAddr().String(), ssrd.LocalAddr().String(), addr.String(), 'tcp') log.Info('reslove addr success: %s requestId: %s', addr.String(), ssrd.GetRequestId())
if ssr.HostFirewall != nil && !ssr.HostFirewall.JudgeHostWithReport(addr.GetAddress(), ssrd.UID) {
log.Info('%s is reject', addr.String())
body := fmt.Sprintf('%s is reject', addr.String())
t := &http.Response{
Status: '200 OK',
StatusCode: 200,
Proto: 'HTTP/1.1',
ProtoMajor: 1,
ProtoMinor: 1,
Body: ioutil.NopCloser(bytes.NewBufferString(body)),
ContentLength: int64(len(body)),
Header: make(http.Header, 0),
}
_ = t.Write(ssrd)
return
}
req, err := network.DialTcp(addr.String())
if err != nil {
logrus.WithFields(logrus.Fields{
'requestId': ssrd.RequestID,
}).Errorf('shadowsocksr proxy remote error %s', err)
return
}
defer req.Close()
_ = req.SetKeepAlive(true)
_, _, err = netx.DuplexCopyTcp(ssrd, req)
log.Debug('close %s', ssrd.RequestID)
if err != nil {
logrus.WithFields(logrus.Fields{
'requestId': ssrd.RequestID,
}).Errorf('shadowsocksr proxy process error %s', err)
return
}
}()
})
}
func (ssr *ShadowsocksRProxy) StartUDP() error {
err := ssr.ListenUDP(func(request *network.Request) {
localIP := request.Conn.LocalAddr().(*net.UDPAddr).IP
go func() {
defer func() {
if e := recover(); e != nil {
fmt.Println(e)
logrus.Errorf('shadowsocksr udp listener crashed , err : %s , \ntrace:%s', e, string(debug.Stack()))
}
}()
ssrd, err := network.NewShadowsocksRDecorate(request,
ssr.Obfs, ssr.Method,
ssr.Password, ssr.Protocol,
ssr.ObfsParam, ssr.ProtocolParam,
localIP, ssr.Port,
false,
ssr.Single,
ssr.Users)
ssrd.TrafficReport = ssr.TrafficReport
if err != nil {
logrus.WithFields(logrus.Fields{
'requestId': request.RequestID,
'error': err,
}).Error('shadowsocksr NewShadowsocksRDecorate error')
}
// TODO UDP TIMEOUT
udpMap := NewShadowsocksRUDPMap(30)
for {
data, uid, addr, err := ssrd.ReadFrom()
if err != nil {
if strings.Contains(err.Error(), ' use of closed network connection') {
logrus.WithFields(logrus.Fields{
'port': ssr.Port,
}).Info('udp close')
return
}
logrus.WithFields(logrus.Fields{
'err': err,
}).Error('ShadowsocksRDecrate read udp error')
continue
}
remoteAddr, err := socksproxy.SplitAddr(data)
if err != nil {
logrus.WithFields(logrus.Fields{
'requestId': ssrd.RequestID,
}).Errorf('shadowsocksr read address error %s', err)
continue
}
logrus.WithFields(logrus.Fields{
'remoteAddr': remoteAddr.String(),
'serverAddr': ssrd.PacketConn.LocalAddr().String(),
'clientAddr': addr.String(),
'uid': binaryx.LEBytesToUInt32(uid),
}).Info('recive udp proxy')
data = data[len(remoteAddr.Raw):]
remotePacketConn := udpMap.Get(addr.String())
if remotePacketConn == nil {
remotePacketConn = &ShadowsocksRUDPMapItem{}
remotePacketConn.Uid = uid
remotePacketConn.PacketConn, err = net.ListenPacket('udp', '')
if err != nil {
logrus.WithFields(logrus.Fields{
'remoteAddr': remoteAddr.String(),
'serverAddr': ssrd.PacketConn.LocalAddr().String(),
'clientAddr': addr.String(),
'uid': binaryx.LEBytesToUInt32(uid),
'err': err,
}).Error('shadowoscksr listenPacket udp error')
continue
}
udpMap.Add(addr, ssrd, remotePacketConn)
}
remoteAddrResolve, err := net.ResolveUDPAddr('udp', remoteAddr.String())
if err != nil {
logrus.WithFields(logrus.Fields{
'remoteAddr': remoteAddr.String(),
'serverAddr': ssrd.PacketConn.LocalAddr().String(),
'clientAddr': addr.String(),
'uid': binaryx.LEBytesToUInt32(uid),
'err': err,
}).Error('shadowoscksr listenPacket udp error')
continue
}
ssr.handleStageAddr(int(binaryx.LEBytesToUInt32(uid)), addr.String(), ssrd.PacketConn.LocalAddr().String(), remoteAddr.String(), 'udp')
if ssr.HostFirewall != nil && !ssr.HostFirewall.JudgeHostWithReport(addr.String(), int(binaryx.LEBytesToUInt32(uid))) {
return
}
//udpMap.Add(addr, ssrd, remotePacketConn)
_, err = remotePacketConn.WriteTo(data, remoteAddrResolve)
if err != nil {
if err != nil {
logrus.WithFields(logrus.Fields{
'remoteAddr': remoteAddr.String(),
'serverAddr': ssrd.PacketConn.LocalAddr().String(),
'clientAddr': addr.String(),
'uid': binaryx.LEBytesToUInt32(uid),
'err': err,
}).Error('shadowoscksr listenPacket udp error')
continue
}
//udpMap.Add(addr, ssrd, remotePacketConn)
}
}
}()
})
return err
原文地址: https://www.cveoy.top/t/topic/lL0N 著作权归作者所有。请勿转载和采集!