github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/transport/internet/quic/hub.go (about) 1 // +build !confonly 2 3 package quic 4 5 import ( 6 "context" 7 "time" 8 9 "github.com/lucas-clemente/quic-go" 10 "v2ray.com/core/common" 11 "v2ray.com/core/common/net" 12 "v2ray.com/core/common/protocol/tls/cert" 13 "v2ray.com/core/common/signal/done" 14 "v2ray.com/core/transport/internet" 15 "v2ray.com/core/transport/internet/tls" 16 ) 17 18 // Listener is an internet.Listener that listens for TCP connections. 19 type Listener struct { 20 rawConn *sysConn 21 listener quic.Listener 22 done *done.Instance 23 addConn internet.ConnHandler 24 } 25 26 func (l *Listener) acceptStreams(session quic.Session) { 27 for { 28 stream, err := session.AcceptStream(context.Background()) 29 if err != nil { 30 newError("failed to accept stream").Base(err).WriteToLog() 31 select { 32 case <-session.Context().Done(): 33 return 34 case <-l.done.Wait(): 35 if err := session.CloseWithError(0, ""); err != nil { 36 newError("failed to close session").Base(err).WriteToLog() 37 } 38 return 39 default: 40 time.Sleep(time.Second) 41 continue 42 } 43 } 44 45 conn := &interConn{ 46 stream: stream, 47 local: session.LocalAddr(), 48 remote: session.RemoteAddr(), 49 } 50 51 l.addConn(conn) 52 } 53 54 } 55 56 func (l *Listener) keepAccepting() { 57 for { 58 conn, err := l.listener.Accept(context.Background()) 59 if err != nil { 60 newError("failed to accept QUIC sessions").Base(err).WriteToLog() 61 if l.done.Done() { 62 break 63 } 64 time.Sleep(time.Second) 65 continue 66 } 67 go l.acceptStreams(conn) 68 } 69 } 70 71 // Addr implements internet.Listener.Addr. 72 func (l *Listener) Addr() net.Addr { 73 return l.listener.Addr() 74 } 75 76 // Close implements internet.Listener.Close. 77 func (l *Listener) Close() error { 78 l.done.Close() 79 l.listener.Close() 80 l.rawConn.Close() 81 return nil 82 } 83 84 // Listen creates a new Listener based on configurations. 85 func Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) { 86 if address.Family().IsDomain() { 87 return nil, newError("domain address is not allows for listening quic") 88 } 89 90 tlsConfig := tls.ConfigFromStreamSettings(streamSettings) 91 if tlsConfig == nil { 92 tlsConfig = &tls.Config{ 93 Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil, cert.DNSNames(internalDomain), cert.CommonName(internalDomain)))}, 94 } 95 } 96 97 config := streamSettings.ProtocolSettings.(*Config) 98 rawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{ 99 IP: address.IP(), 100 Port: int(port), 101 }, streamSettings.SocketSettings) 102 103 if err != nil { 104 return nil, err 105 } 106 107 quicConfig := &quic.Config{ 108 ConnectionIDLength: 12, 109 HandshakeTimeout: time.Second * 8, 110 MaxIdleTimeout: time.Second * 45, 111 MaxIncomingStreams: 32, 112 MaxIncomingUniStreams: -1, 113 } 114 115 conn, err := wrapSysConn(rawConn, config) 116 if err != nil { 117 conn.Close() 118 return nil, err 119 } 120 121 qListener, err := quic.Listen(conn, tlsConfig.GetTLSConfig(), quicConfig) 122 if err != nil { 123 conn.Close() 124 return nil, err 125 } 126 127 listener := &Listener{ 128 done: done.New(), 129 rawConn: conn, 130 listener: qListener, 131 addConn: handler, 132 } 133 134 go listener.keepAccepting() 135 136 return listener, nil 137 } 138 139 func init() { 140 common.Must(internet.RegisterTransportListener(protocolName, Listen)) 141 }