github.com/metacubex/mihomo@v1.18.5/listener/tuic/server.go (about) 1 package tuic 2 3 import ( 4 "context" 5 "crypto/tls" 6 "net" 7 "strings" 8 "time" 9 10 "github.com/metacubex/mihomo/adapter/inbound" 11 CN "github.com/metacubex/mihomo/common/net" 12 "github.com/metacubex/mihomo/common/sockopt" 13 C "github.com/metacubex/mihomo/constant" 14 LC "github.com/metacubex/mihomo/listener/config" 15 "github.com/metacubex/mihomo/listener/sing" 16 "github.com/metacubex/mihomo/log" 17 "github.com/metacubex/mihomo/transport/socks5" 18 "github.com/metacubex/mihomo/transport/tuic" 19 20 "github.com/gofrs/uuid/v5" 21 "github.com/metacubex/quic-go" 22 "golang.org/x/exp/slices" 23 ) 24 25 const ServerMaxIncomingStreams = (1 << 32) - 1 26 27 type Listener struct { 28 closed bool 29 config LC.TuicServer 30 udpListeners []net.PacketConn 31 servers []*tuic.Server 32 } 33 34 func New(config LC.TuicServer, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) { 35 if len(additions) == 0 { 36 additions = []inbound.Addition{ 37 inbound.WithInName("DEFAULT-TUIC"), 38 inbound.WithSpecialRules(""), 39 } 40 } 41 h, err := sing.NewListenerHandler(sing.ListenerConfig{ 42 Tunnel: tunnel, 43 Type: C.TUIC, 44 Additions: additions, 45 MuxOption: config.MuxOption, 46 }) 47 if err != nil { 48 return nil, err 49 } 50 51 cert, err := CN.ParseCert(config.Certificate, config.PrivateKey, C.Path) 52 if err != nil { 53 return nil, err 54 } 55 tlsConfig := &tls.Config{ 56 MinVersion: tls.VersionTLS13, 57 Certificates: []tls.Certificate{cert}, 58 } 59 if len(config.ALPN) > 0 { 60 tlsConfig.NextProtos = config.ALPN 61 } else { 62 tlsConfig.NextProtos = []string{"h3"} 63 } 64 quicConfig := &quic.Config{ 65 MaxIdleTimeout: time.Duration(config.MaxIdleTime) * time.Millisecond, 66 MaxIncomingStreams: ServerMaxIncomingStreams, 67 MaxIncomingUniStreams: ServerMaxIncomingStreams, 68 EnableDatagrams: true, 69 Allow0RTT: true, 70 } 71 quicConfig.InitialStreamReceiveWindow = tuic.DefaultStreamReceiveWindow / 10 72 quicConfig.MaxStreamReceiveWindow = tuic.DefaultStreamReceiveWindow 73 quicConfig.InitialConnectionReceiveWindow = tuic.DefaultConnectionReceiveWindow / 10 74 quicConfig.MaxConnectionReceiveWindow = tuic.DefaultConnectionReceiveWindow 75 76 packetOverHead := tuic.PacketOverHeadV4 77 if len(config.Token) == 0 { 78 packetOverHead = tuic.PacketOverHeadV5 79 } 80 81 if config.CWND == 0 { 82 config.CWND = 32 83 } 84 85 if config.MaxUdpRelayPacketSize == 0 { 86 config.MaxUdpRelayPacketSize = 1500 87 } 88 maxDatagramFrameSize := config.MaxUdpRelayPacketSize + packetOverHead 89 if maxDatagramFrameSize > 1400 { 90 maxDatagramFrameSize = 1400 91 } 92 config.MaxUdpRelayPacketSize = maxDatagramFrameSize - packetOverHead 93 quicConfig.MaxDatagramFrameSize = int64(maxDatagramFrameSize) 94 95 handleTcpFn := func(conn net.Conn, addr socks5.Addr, _additions ...inbound.Addition) error { 96 newAdditions := additions 97 if len(_additions) > 0 { 98 newAdditions = slices.Clone(additions) 99 newAdditions = append(newAdditions, _additions...) 100 } 101 conn, metadata := inbound.NewSocket(addr, conn, C.TUIC, newAdditions...) 102 if h.IsSpecialFqdn(metadata.Host) { 103 go func() { // ParseSpecialFqdn will block, so open a new goroutine 104 _ = h.ParseSpecialFqdn( 105 sing.WithAdditions(context.Background(), newAdditions...), 106 conn, 107 sing.ConvertMetadata(metadata), 108 ) 109 }() 110 return nil 111 } 112 go tunnel.HandleTCPConn(conn, metadata) 113 return nil 114 } 115 handleUdpFn := func(addr socks5.Addr, packet C.UDPPacket, _additions ...inbound.Addition) error { 116 newAdditions := additions 117 if len(_additions) > 0 { 118 newAdditions = slices.Clone(additions) 119 newAdditions = append(newAdditions, _additions...) 120 } 121 tunnel.HandleUDPPacket(inbound.NewPacket(addr, packet, C.TUIC, newAdditions...)) 122 return nil 123 } 124 125 option := &tuic.ServerOption{ 126 HandleTcpFn: handleTcpFn, 127 HandleUdpFn: handleUdpFn, 128 TlsConfig: tlsConfig, 129 QuicConfig: quicConfig, 130 CongestionController: config.CongestionController, 131 AuthenticationTimeout: time.Duration(config.AuthenticationTimeout) * time.Millisecond, 132 MaxUdpRelayPacketSize: config.MaxUdpRelayPacketSize, 133 CWND: config.CWND, 134 } 135 if len(config.Token) > 0 { 136 tokens := make([][32]byte, len(config.Token)) 137 for i, token := range config.Token { 138 tokens[i] = tuic.GenTKN(token) 139 } 140 option.Tokens = tokens 141 } 142 if len(config.Users) > 0 { 143 users := make(map[[16]byte]string) 144 for _uuid, password := range config.Users { 145 users[uuid.FromStringOrNil(_uuid)] = password 146 } 147 option.Users = users 148 } 149 150 sl := &Listener{false, config, nil, nil} 151 152 for _, addr := range strings.Split(config.Listen, ",") { 153 addr := addr 154 155 ul, err := net.ListenPacket("udp", addr) 156 if err != nil { 157 return nil, err 158 } 159 160 err = sockopt.UDPReuseaddr(ul.(*net.UDPConn)) 161 if err != nil { 162 log.Warnln("Failed to Reuse UDP Address: %s", err) 163 } 164 165 sl.udpListeners = append(sl.udpListeners, ul) 166 167 var server *tuic.Server 168 server, err = tuic.NewServer(option, ul) 169 if err != nil { 170 return nil, err 171 } 172 173 sl.servers = append(sl.servers, server) 174 175 go func() { 176 err := server.Serve() 177 if err != nil { 178 if sl.closed { 179 return 180 } 181 } 182 }() 183 } 184 185 return sl, nil 186 } 187 188 func (l *Listener) Close() error { 189 l.closed = true 190 var retErr error 191 for _, lis := range l.servers { 192 err := lis.Close() 193 if err != nil { 194 retErr = err 195 } 196 } 197 for _, lis := range l.udpListeners { 198 err := lis.Close() 199 if err != nil { 200 retErr = err 201 } 202 } 203 return retErr 204 } 205 206 func (l *Listener) Config() LC.TuicServer { 207 return l.config 208 } 209 210 func (l *Listener) AddrList() (addrList []net.Addr) { 211 for _, lis := range l.udpListeners { 212 addrList = append(addrList, lis.LocalAddr()) 213 } 214 return 215 }