github.com/eagleql/xray-core@v1.4.4/transport/internet/tcp/hub.go (about) 1 package tcp 2 3 import ( 4 "context" 5 gotls "crypto/tls" 6 "strings" 7 "time" 8 9 goxtls "github.com/xtls/go" 10 11 "github.com/eagleql/xray-core/common" 12 "github.com/eagleql/xray-core/common/net" 13 "github.com/eagleql/xray-core/common/session" 14 "github.com/eagleql/xray-core/transport/internet" 15 "github.com/eagleql/xray-core/transport/internet/tls" 16 "github.com/eagleql/xray-core/transport/internet/xtls" 17 ) 18 19 // Listener is an internet.Listener that listens for TCP connections. 20 type Listener struct { 21 listener net.Listener 22 tlsConfig *gotls.Config 23 xtlsConfig *goxtls.Config 24 authConfig internet.ConnectionAuthenticator 25 config *Config 26 addConn internet.ConnHandler 27 locker *internet.FileLocker // for unix domain socket 28 } 29 30 // ListenTCP creates a new Listener based on configurations. 31 func ListenTCP(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) { 32 l := &Listener{ 33 addConn: handler, 34 } 35 tcpSettings := streamSettings.ProtocolSettings.(*Config) 36 l.config = tcpSettings 37 if l.config != nil { 38 if streamSettings.SocketSettings == nil { 39 streamSettings.SocketSettings = &internet.SocketConfig{} 40 } 41 streamSettings.SocketSettings.AcceptProxyProtocol = 42 l.config.AcceptProxyProtocol || streamSettings.SocketSettings.AcceptProxyProtocol 43 } 44 var listener net.Listener 45 var err error 46 if port == net.Port(0) { //unix 47 listener, err = internet.ListenSystem(ctx, &net.UnixAddr{ 48 Name: address.Domain(), 49 Net: "unix", 50 }, streamSettings.SocketSettings) 51 if err != nil { 52 return nil, newError("failed to listen Unix Domain Socket on ", address).Base(err) 53 } 54 newError("listening Unix Domain Socket on ", address).WriteToLog(session.ExportIDToError(ctx)) 55 locker := ctx.Value(address.Domain()) 56 if locker != nil { 57 l.locker = locker.(*internet.FileLocker) 58 } 59 } else { 60 listener, err = internet.ListenSystem(ctx, &net.TCPAddr{ 61 IP: address.IP(), 62 Port: int(port), 63 }, streamSettings.SocketSettings) 64 if err != nil { 65 return nil, newError("failed to listen TCP on ", address, ":", port).Base(err) 66 } 67 newError("listening TCP on ", address, ":", port).WriteToLog(session.ExportIDToError(ctx)) 68 } 69 70 if streamSettings.SocketSettings != nil && streamSettings.SocketSettings.AcceptProxyProtocol { 71 newError("accepting PROXY protocol").AtWarning().WriteToLog(session.ExportIDToError(ctx)) 72 } 73 74 l.listener = listener 75 76 if config := tls.ConfigFromStreamSettings(streamSettings); config != nil { 77 l.tlsConfig = config.GetTLSConfig() 78 } 79 if config := xtls.ConfigFromStreamSettings(streamSettings); config != nil { 80 l.xtlsConfig = config.GetXTLSConfig() 81 } 82 83 if tcpSettings.HeaderSettings != nil { 84 headerConfig, err := tcpSettings.HeaderSettings.GetInstance() 85 if err != nil { 86 return nil, newError("invalid header settings").Base(err).AtError() 87 } 88 auth, err := internet.CreateConnectionAuthenticator(headerConfig) 89 if err != nil { 90 return nil, newError("invalid header settings.").Base(err).AtError() 91 } 92 l.authConfig = auth 93 } 94 95 go l.keepAccepting() 96 return l, nil 97 } 98 99 func (v *Listener) keepAccepting() { 100 for { 101 conn, err := v.listener.Accept() 102 if err != nil { 103 errStr := err.Error() 104 if strings.Contains(errStr, "closed") { 105 break 106 } 107 newError("failed to accepted raw connections").Base(err).AtWarning().WriteToLog() 108 if strings.Contains(errStr, "too many") { 109 time.Sleep(time.Millisecond * 500) 110 } 111 continue 112 } 113 114 if v.tlsConfig != nil { 115 conn = tls.Server(conn, v.tlsConfig) 116 } else if v.xtlsConfig != nil { 117 conn = xtls.Server(conn, v.xtlsConfig) 118 } 119 if v.authConfig != nil { 120 conn = v.authConfig.Server(conn) 121 } 122 123 v.addConn(internet.Connection(conn)) 124 } 125 } 126 127 // Addr implements internet.Listener.Addr. 128 func (v *Listener) Addr() net.Addr { 129 return v.listener.Addr() 130 } 131 132 // Close implements internet.Listener.Close. 133 func (v *Listener) Close() error { 134 if v.locker != nil { 135 v.locker.Release() 136 } 137 return v.listener.Close() 138 } 139 140 func init() { 141 common.Must(internet.RegisterTransportListener(protocolName, ListenTCP)) 142 }