github.com/xraypb/Xray-core@v1.8.1/transport/internet/tcp/hub.go (about) 1 package tcp 2 3 import ( 4 "context" 5 gotls "crypto/tls" 6 "strings" 7 "time" 8 9 "github.com/xraypb/Xray-core/common" 10 "github.com/xraypb/Xray-core/common/net" 11 "github.com/xraypb/Xray-core/common/session" 12 "github.com/xraypb/Xray-core/transport/internet" 13 "github.com/xraypb/Xray-core/transport/internet/reality" 14 "github.com/xraypb/Xray-core/transport/internet/stat" 15 "github.com/xraypb/Xray-core/transport/internet/tls" 16 goreality "github.com/xtls/reality" 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 realityConfig *goreality.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 = l.config.AcceptProxyProtocol || streamSettings.SocketSettings.AcceptProxyProtocol 42 } 43 var listener net.Listener 44 var err error 45 if port == net.Port(0) { // unix 46 listener, err = internet.ListenSystem(ctx, &net.UnixAddr{ 47 Name: address.Domain(), 48 Net: "unix", 49 }, streamSettings.SocketSettings) 50 if err != nil { 51 return nil, newError("failed to listen Unix Domain Socket on ", address).Base(err) 52 } 53 newError("listening Unix Domain Socket on ", address).WriteToLog(session.ExportIDToError(ctx)) 54 locker := ctx.Value(address.Domain()) 55 if locker != nil { 56 l.locker = locker.(*internet.FileLocker) 57 } 58 } else { 59 listener, err = internet.ListenSystem(ctx, &net.TCPAddr{ 60 IP: address.IP(), 61 Port: int(port), 62 }, streamSettings.SocketSettings) 63 if err != nil { 64 return nil, newError("failed to listen TCP on ", address, ":", port).Base(err) 65 } 66 newError("listening TCP on ", address, ":", port).WriteToLog(session.ExportIDToError(ctx)) 67 } 68 69 if streamSettings.SocketSettings != nil && streamSettings.SocketSettings.AcceptProxyProtocol { 70 newError("accepting PROXY protocol").AtWarning().WriteToLog(session.ExportIDToError(ctx)) 71 } 72 73 l.listener = listener 74 75 if config := tls.ConfigFromStreamSettings(streamSettings); config != nil { 76 l.tlsConfig = config.GetTLSConfig() 77 } 78 if config := reality.ConfigFromStreamSettings(streamSettings); config != nil { 79 l.realityConfig = config.GetREALITYConfig() 80 } 81 82 if tcpSettings.HeaderSettings != nil { 83 headerConfig, err := tcpSettings.HeaderSettings.GetInstance() 84 if err != nil { 85 return nil, newError("invalid header settings").Base(err).AtError() 86 } 87 auth, err := internet.CreateConnectionAuthenticator(headerConfig) 88 if err != nil { 89 return nil, newError("invalid header settings.").Base(err).AtError() 90 } 91 l.authConfig = auth 92 } 93 94 go l.keepAccepting() 95 return l, nil 96 } 97 98 func (v *Listener) keepAccepting() { 99 for { 100 conn, err := v.listener.Accept() 101 if err != nil { 102 errStr := err.Error() 103 if strings.Contains(errStr, "closed") { 104 break 105 } 106 newError("failed to accepted raw connections").Base(err).AtWarning().WriteToLog() 107 if strings.Contains(errStr, "too many") { 108 time.Sleep(time.Millisecond * 500) 109 } 110 continue 111 } 112 go func() { 113 if v.tlsConfig != nil { 114 conn = tls.Server(conn, v.tlsConfig) 115 } else if v.realityConfig != nil { 116 if conn, err = reality.Server(conn, v.realityConfig); err != nil { 117 newError(err).AtInfo().WriteToLog() 118 return 119 } 120 } 121 if v.authConfig != nil { 122 conn = v.authConfig.Server(conn) 123 } 124 v.addConn(stat.Connection(conn)) 125 }() 126 } 127 } 128 129 // Addr implements internet.Listener.Addr. 130 func (v *Listener) Addr() net.Addr { 131 return v.listener.Addr() 132 } 133 134 // Close implements internet.Listener.Close. 135 func (v *Listener) Close() error { 136 if v.locker != nil { 137 v.locker.Release() 138 } 139 return v.listener.Close() 140 } 141 142 func init() { 143 common.Must(internet.RegisterTransportListener(protocolName, ListenTCP)) 144 }