github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/proxy/trojan/server.go (about) 1 // +build !confonly 2 3 package trojan 4 5 import ( 6 "context" 7 "crypto/tls" 8 "io" 9 "strconv" 10 "time" 11 12 "v2ray.com/core" 13 "v2ray.com/core/common" 14 "v2ray.com/core/common/buf" 15 "v2ray.com/core/common/errors" 16 "v2ray.com/core/common/log" 17 "v2ray.com/core/common/net" 18 "v2ray.com/core/common/protocol" 19 udp_proto "v2ray.com/core/common/protocol/udp" 20 "v2ray.com/core/common/retry" 21 "v2ray.com/core/common/session" 22 "v2ray.com/core/common/signal" 23 "v2ray.com/core/common/task" 24 "v2ray.com/core/features/policy" 25 "v2ray.com/core/features/routing" 26 "v2ray.com/core/transport/internet" 27 "v2ray.com/core/transport/internet/udp" 28 "v2ray.com/core/transport/internet/xtls" 29 ) 30 31 func init() { 32 common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { // nolint: lll 33 return NewServer(ctx, config.(*ServerConfig)) 34 })) 35 } 36 37 // Server is an inbound connection handler that handles messages in trojan protocol. 38 type Server struct { 39 policyManager policy.Manager 40 validator *Validator 41 fallbacks map[string]map[string]*Fallback // or nil 42 } 43 44 // NewServer creates a new trojan inbound handler. 45 func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { 46 validator := new(Validator) 47 for _, user := range config.Users { 48 u, err := user.ToMemoryUser() 49 if err != nil { 50 return nil, newError("failed to get trojan user").Base(err).AtError() 51 } 52 53 if err := validator.Add(u); err != nil { 54 return nil, newError("failed to add user").Base(err).AtError() 55 } 56 } 57 58 v := core.MustFromContext(ctx) 59 server := &Server{ 60 policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), 61 validator: validator, 62 } 63 64 if config.Fallbacks != nil { 65 server.fallbacks = make(map[string]map[string]*Fallback) 66 for _, fb := range config.Fallbacks { 67 if server.fallbacks[fb.Alpn] == nil { 68 server.fallbacks[fb.Alpn] = make(map[string]*Fallback) 69 } 70 server.fallbacks[fb.Alpn][fb.Path] = fb 71 } 72 if server.fallbacks[""] != nil { 73 for alpn, pfb := range server.fallbacks { 74 if alpn != "" { // && alpn != "h2" { 75 for path, fb := range server.fallbacks[""] { 76 if pfb[path] == nil { 77 pfb[path] = fb 78 } 79 } 80 } 81 } 82 } 83 } 84 85 return server, nil 86 } 87 88 // Network implements proxy.Inbound.Network(). 89 func (s *Server) Network() []net.Network { 90 return []net.Network{net.Network_TCP} 91 } 92 93 // Process implements proxy.Inbound.Process(). 94 func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error { // nolint: funlen,lll 95 96 sid := session.ExportIDToError(ctx) 97 98 iConn := conn 99 if statConn, ok := iConn.(*internet.StatCouterConnection); ok { 100 iConn = statConn.Connection 101 } 102 103 sessionPolicy := s.policyManager.ForLevel(0) 104 if err := conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil { 105 return newError("unable to set read deadline").Base(err).AtWarning() 106 } 107 108 first := buf.New() 109 defer first.Release() 110 111 firstLen, err := first.ReadFrom(conn) 112 if err != nil { 113 return newError("failed to read first request").Base(err) 114 } 115 newError("firstLen = ", firstLen).AtInfo().WriteToLog(sid) 116 117 bufferedReader := &buf.BufferedReader{ 118 Reader: buf.NewReader(conn), 119 Buffer: buf.MultiBuffer{first}, 120 } 121 122 var user *protocol.MemoryUser 123 124 apfb := s.fallbacks 125 isfb := apfb != nil 126 127 shouldFallback := false 128 if firstLen < 58 || first.Byte(56) != '\r' { // nolint: gomnd 129 // invalid protocol 130 err = newError("not trojan protocol") 131 log.Record(&log.AccessMessage{ 132 From: conn.RemoteAddr(), 133 To: "", 134 Status: log.AccessRejected, 135 Reason: err, 136 }) 137 138 shouldFallback = true 139 } else { 140 user = s.validator.Get(hexString(first.BytesTo(56))) // nolint: gomnd 141 if user == nil { 142 // invalid user, let's fallback 143 err = newError("not a valid user") 144 log.Record(&log.AccessMessage{ 145 From: conn.RemoteAddr(), 146 To: "", 147 Status: log.AccessRejected, 148 Reason: err, 149 }) 150 151 shouldFallback = true 152 } 153 } 154 155 if isfb && shouldFallback { 156 return s.fallback(ctx, sid, err, sessionPolicy, conn, iConn, apfb, first, firstLen, bufferedReader) 157 } else if shouldFallback { 158 return newError("invalid protocol or invalid user") 159 } 160 161 clientReader := &ConnReader{Reader: bufferedReader} 162 if err := clientReader.ParseHeader(); err != nil { 163 log.Record(&log.AccessMessage{ 164 From: conn.RemoteAddr(), 165 To: "", 166 Status: log.AccessRejected, 167 Reason: err, 168 }) 169 return newError("failed to create request from: ", conn.RemoteAddr()).Base(err) 170 } 171 172 destination := clientReader.Target 173 if err := conn.SetReadDeadline(time.Time{}); err != nil { 174 return newError("unable to set read deadline").Base(err).AtWarning() 175 } 176 177 inbound := session.InboundFromContext(ctx) 178 if inbound == nil { 179 panic("no inbound metadata") 180 } 181 inbound.User = user 182 sessionPolicy = s.policyManager.ForLevel(user.Level) 183 184 if destination.Network == net.Network_UDP { // handle udp request 185 return s.handleUDPPayload(ctx, &PacketReader{Reader: clientReader}, &PacketWriter{Writer: conn}, dispatcher) 186 } 187 188 // handle tcp request 189 190 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 191 From: conn.RemoteAddr(), 192 To: destination, 193 Status: log.AccessAccepted, 194 Reason: "", 195 Email: user.Email, 196 }) 197 198 newError("received request for ", destination).WriteToLog(sid) 199 return s.handleConnection(ctx, sessionPolicy, destination, clientReader, buf.NewWriter(conn), dispatcher) 200 } 201 202 func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReader, clientWriter *PacketWriter, dispatcher routing.Dispatcher) error { // nolint: lll 203 udpServer := udp.NewDispatcher(dispatcher, func(ctx context.Context, packet *udp_proto.Packet) { 204 common.Must(clientWriter.WriteMultiBufferWithMetadata(buf.MultiBuffer{packet.Payload}, packet.Source)) 205 }) 206 207 inbound := session.InboundFromContext(ctx) 208 user := inbound.User 209 210 for { 211 select { 212 case <-ctx.Done(): 213 return nil 214 default: 215 p, err := clientReader.ReadMultiBufferWithMetadata() 216 if err != nil { 217 if errors.Cause(err) != io.EOF { 218 return newError("unexpected EOF").Base(err) 219 } 220 return nil 221 } 222 223 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 224 From: inbound.Source, 225 To: p.Target, 226 Status: log.AccessAccepted, 227 Reason: "", 228 Email: user.Email, 229 }) 230 newError("tunnelling request to ", p.Target).WriteToLog(session.ExportIDToError(ctx)) 231 232 for _, b := range p.Buffer { 233 udpServer.Dispatch(ctx, p.Target, b) 234 } 235 } 236 } 237 } 238 239 func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Session, 240 destination net.Destination, 241 clientReader buf.Reader, 242 clientWriter buf.Writer, dispatcher routing.Dispatcher) error { 243 ctx, cancel := context.WithCancel(ctx) 244 timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) 245 ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) 246 247 link, err := dispatcher.Dispatch(ctx, destination) 248 if err != nil { 249 return newError("failed to dispatch request to ", destination).Base(err) 250 } 251 252 requestDone := func() error { 253 defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) 254 255 if err := buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer)); err != nil { 256 return newError("failed to transfer request").Base(err) 257 } 258 return nil 259 } 260 261 responseDone := func() error { 262 defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) 263 264 if err := buf.Copy(link.Reader, clientWriter, buf.UpdateActivity(timer)); err != nil { 265 return newError("failed to write response").Base(err) 266 } 267 return nil 268 } 269 270 var requestDonePost = task.OnSuccess(requestDone, task.Close(link.Writer)) 271 if err := task.Run(ctx, requestDonePost, responseDone); err != nil { 272 common.Must(common.Interrupt(link.Reader)) 273 common.Must(common.Interrupt(link.Writer)) 274 return newError("connection ends").Base(err) 275 } 276 277 return nil 278 } 279 280 func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err error, sessionPolicy policy.Session, connection internet.Connection, iConn internet.Connection, apfb map[string]map[string]*Fallback, first *buf.Buffer, firstLen int64, reader buf.Reader) error { // nolint: lll 281 if err := connection.SetReadDeadline(time.Time{}); err != nil { 282 newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid) 283 } 284 newError("fallback starts").Base(err).AtInfo().WriteToLog(sid) 285 286 alpn := "" 287 if len(apfb) > 1 || apfb[""] == nil { 288 if tlsConn, ok := iConn.(*tls.Conn); ok { 289 alpn = tlsConn.ConnectionState().NegotiatedProtocol 290 newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid) 291 } else if xtlsConn, ok := iConn.(*xtls.Conn); ok { 292 alpn = xtlsConn.ConnectionState().NegotiatedProtocol 293 newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid) 294 } 295 if apfb[alpn] == nil { 296 alpn = "" 297 } 298 } 299 pfb := apfb[alpn] 300 if pfb == nil { 301 return newError(`failed to find the default "alpn" config`).AtWarning() 302 } 303 304 path := "" 305 if len(pfb) > 1 || pfb[""] == nil { 306 if firstLen >= 18 && first.Byte(4) != '*' { // not h2c 307 firstBytes := first.Bytes() 308 for i := 4; i <= 8; i++ { // 5 -> 9 309 if firstBytes[i] == '/' && firstBytes[i-1] == ' ' { 310 search := len(firstBytes) 311 if search > 64 { 312 search = 64 // up to about 60 313 } 314 for j := i + 1; j < search; j++ { 315 k := firstBytes[j] 316 if k == '\r' || k == '\n' { // avoid logging \r or \n 317 break 318 } 319 if k == ' ' { 320 path = string(firstBytes[i:j]) 321 newError("realPath = " + path).AtInfo().WriteToLog(sid) 322 if pfb[path] == nil { 323 path = "" 324 } 325 break 326 } 327 } 328 break 329 } 330 } 331 } 332 } 333 fb := pfb[path] 334 if fb == nil { 335 return newError(`failed to find the default "path" config`).AtWarning() 336 } 337 338 ctx, cancel := context.WithCancel(ctx) 339 timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) 340 ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) 341 342 var conn net.Conn 343 if err := retry.ExponentialBackoff(5, 100).On(func() error { 344 var dialer net.Dialer 345 conn, err = dialer.DialContext(ctx, fb.Type, fb.Dest) 346 if err != nil { 347 return err 348 } 349 return nil 350 }); err != nil { 351 return newError("failed to dial to " + fb.Dest).Base(err).AtWarning() 352 } 353 defer conn.Close() 354 355 serverReader := buf.NewReader(conn) 356 serverWriter := buf.NewWriter(conn) 357 358 postRequest := func() error { 359 defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) 360 if fb.Xver != 0 { 361 remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String()) 362 if err != nil { 363 return err 364 } 365 localAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String()) 366 if err != nil { 367 return err 368 } 369 ipv4 := true 370 for i := 0; i < len(remoteAddr); i++ { 371 if remoteAddr[i] == ':' { 372 ipv4 = false 373 break 374 } 375 } 376 pro := buf.New() 377 defer pro.Release() 378 switch fb.Xver { 379 case 1: 380 if ipv4 { 381 common.Must2(pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))) 382 } else { 383 common.Must2(pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))) 384 } 385 case 2: 386 common.Must2(pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21"))) // signature + v2 + PROXY 387 if ipv4 { 388 common.Must2(pro.Write([]byte("\x11\x00\x0C"))) // AF_INET + STREAM + 12 bytes 389 common.Must2(pro.Write(net.ParseIP(remoteAddr).To4())) 390 common.Must2(pro.Write(net.ParseIP(localAddr).To4())) 391 } else { 392 common.Must2(pro.Write([]byte("\x21\x00\x24"))) // AF_INET6 + STREAM + 36 bytes 393 common.Must2(pro.Write(net.ParseIP(remoteAddr).To16())) 394 common.Must2(pro.Write(net.ParseIP(localAddr).To16())) 395 } 396 p1, _ := strconv.ParseUint(remotePort, 10, 16) 397 p2, _ := strconv.ParseUint(localPort, 10, 16) 398 common.Must2(pro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)})) 399 } 400 if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil { 401 return newError("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning() 402 } 403 } 404 if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil { 405 return newError("failed to fallback request payload").Base(err).AtInfo() 406 } 407 return nil 408 } 409 410 writer := buf.NewWriter(connection) 411 412 getResponse := func() error { 413 defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) 414 if err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil { 415 return newError("failed to deliver response payload").Base(err).AtInfo() 416 } 417 return nil 418 } 419 420 if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), task.OnSuccess(getResponse, task.Close(writer))); err != nil { 421 common.Must(common.Interrupt(serverReader)) 422 common.Must(common.Interrupt(serverWriter)) 423 return newError("fallback ends").Base(err).AtInfo() 424 } 425 426 return nil 427 }