github.com/metacubex/mihomo@v1.18.5/transport/tuic/server.go (about) 1 package tuic 2 3 import ( 4 "bufio" 5 "context" 6 "crypto/tls" 7 "net" 8 "time" 9 10 "github.com/metacubex/mihomo/adapter/inbound" 11 N "github.com/metacubex/mihomo/common/net" 12 "github.com/metacubex/mihomo/common/utils" 13 C "github.com/metacubex/mihomo/constant" 14 "github.com/metacubex/mihomo/transport/socks5" 15 "github.com/metacubex/mihomo/transport/tuic/common" 16 v4 "github.com/metacubex/mihomo/transport/tuic/v4" 17 v5 "github.com/metacubex/mihomo/transport/tuic/v5" 18 19 "github.com/gofrs/uuid/v5" 20 "github.com/metacubex/quic-go" 21 ) 22 23 type ServerOption struct { 24 HandleTcpFn func(conn net.Conn, addr socks5.Addr, additions ...inbound.Addition) error 25 HandleUdpFn func(addr socks5.Addr, packet C.UDPPacket, additions ...inbound.Addition) error 26 27 TlsConfig *tls.Config 28 QuicConfig *quic.Config 29 Tokens [][32]byte // V4 special 30 Users map[[16]byte]string // V5 special 31 CongestionController string 32 AuthenticationTimeout time.Duration 33 MaxUdpRelayPacketSize int 34 CWND int 35 } 36 37 type Server struct { 38 *ServerOption 39 optionV4 *v4.ServerOption 40 optionV5 *v5.ServerOption 41 listener *quic.EarlyListener 42 } 43 44 func (s *Server) Serve() error { 45 for { 46 conn, err := s.listener.Accept(context.Background()) 47 if err != nil { 48 return err 49 } 50 common.SetCongestionController(conn, s.CongestionController, s.CWND) 51 h := &serverHandler{ 52 Server: s, 53 quicConn: conn, 54 uuid: utils.NewUUIDV4(), 55 } 56 if h.optionV4 != nil { 57 h.v4Handler = v4.NewServerHandler(h.optionV4, conn, h.uuid) 58 } 59 if h.optionV5 != nil { 60 h.v5Handler = v5.NewServerHandler(h.optionV5, conn, h.uuid) 61 } 62 go h.handle() 63 } 64 } 65 66 func (s *Server) Close() error { 67 return s.listener.Close() 68 } 69 70 type serverHandler struct { 71 *Server 72 quicConn quic.EarlyConnection 73 uuid uuid.UUID 74 75 v4Handler common.ServerHandler 76 v5Handler common.ServerHandler 77 } 78 79 func (s *serverHandler) handle() { 80 go func() { 81 _ = s.handleUniStream() 82 }() 83 go func() { 84 _ = s.handleStream() 85 }() 86 go func() { 87 _ = s.handleMessage() 88 }() 89 90 <-s.quicConn.HandshakeComplete() 91 time.AfterFunc(s.AuthenticationTimeout, func() { 92 if s.v4Handler != nil { 93 if s.v4Handler.AuthOk() { 94 return 95 } 96 } 97 98 if s.v5Handler != nil { 99 if s.v5Handler.AuthOk() { 100 return 101 } 102 } 103 104 if s.v4Handler != nil { 105 s.v4Handler.HandleTimeout() 106 } 107 108 if s.v5Handler != nil { 109 s.v5Handler.HandleTimeout() 110 } 111 }) 112 } 113 114 func (s *serverHandler) handleMessage() (err error) { 115 for { 116 var message []byte 117 message, err = s.quicConn.ReceiveDatagram(context.Background()) 118 if err != nil { 119 return err 120 } 121 go func() (err error) { 122 if len(message) > 0 { 123 switch message[0] { 124 case v4.VER: 125 if s.v4Handler != nil { 126 return s.v4Handler.HandleMessage(message) 127 } 128 case v5.VER: 129 if s.v5Handler != nil { 130 return s.v5Handler.HandleMessage(message) 131 } 132 } 133 } 134 return 135 }() 136 } 137 } 138 139 func (s *serverHandler) handleStream() (err error) { 140 for { 141 var quicStream quic.Stream 142 quicStream, err = s.quicConn.AcceptStream(context.Background()) 143 if err != nil { 144 return err 145 } 146 go func() (err error) { 147 stream := common.NewQuicStreamConn( 148 quicStream, 149 s.quicConn.LocalAddr(), 150 s.quicConn.RemoteAddr(), 151 nil, 152 ) 153 conn := N.NewBufferedConn(stream) 154 155 verBytes, err := conn.Peek(1) 156 if err != nil { 157 _ = conn.Close() 158 return err 159 } 160 161 switch verBytes[0] { 162 case v4.VER: 163 if s.v4Handler != nil { 164 return s.v4Handler.HandleStream(conn) 165 } 166 case v5.VER: 167 if s.v5Handler != nil { 168 return s.v5Handler.HandleStream(conn) 169 } 170 } 171 return 172 }() 173 } 174 } 175 176 func (s *serverHandler) handleUniStream() (err error) { 177 for { 178 var stream quic.ReceiveStream 179 stream, err = s.quicConn.AcceptUniStream(context.Background()) 180 if err != nil { 181 return err 182 } 183 go func() (err error) { 184 defer func() { 185 stream.CancelRead(0) 186 }() 187 reader := bufio.NewReader(stream) 188 verBytes, err := reader.Peek(1) 189 if err != nil { 190 return err 191 } 192 193 switch verBytes[0] { 194 case v4.VER: 195 if s.v4Handler != nil { 196 return s.v4Handler.HandleUniStream(reader) 197 } 198 case v5.VER: 199 if s.v5Handler != nil { 200 return s.v5Handler.HandleUniStream(reader) 201 } 202 } 203 return 204 }() 205 } 206 } 207 208 func NewServer(option *ServerOption, pc net.PacketConn) (*Server, error) { 209 listener, err := quic.ListenEarly(pc, option.TlsConfig, option.QuicConfig) 210 if err != nil { 211 return nil, err 212 } 213 server := &Server{ 214 ServerOption: option, 215 listener: listener, 216 } 217 if len(option.Tokens) > 0 { 218 server.optionV4 = &v4.ServerOption{ 219 HandleTcpFn: option.HandleTcpFn, 220 HandleUdpFn: option.HandleUdpFn, 221 Tokens: option.Tokens, 222 MaxUdpRelayPacketSize: option.MaxUdpRelayPacketSize, 223 } 224 } 225 if len(option.Users) > 0 { 226 maxUdpRelayPacketSize := option.MaxUdpRelayPacketSize 227 if maxUdpRelayPacketSize > MaxFragSizeV5 { 228 maxUdpRelayPacketSize = MaxFragSizeV5 229 } 230 server.optionV5 = &v5.ServerOption{ 231 HandleTcpFn: option.HandleTcpFn, 232 HandleUdpFn: option.HandleUdpFn, 233 Users: option.Users, 234 MaxUdpRelayPacketSize: option.MaxUdpRelayPacketSize, 235 } 236 } 237 return server, nil 238 }