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
ShadowsocksR Proxy: Binding Data Exit IP to Data Entry IP

原文地址: https://www.cveoy.top/t/topic/lL0N 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录