github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/transport/internet/request/assembly/dialer.go (about) 1 package assembly 2 3 import ( 4 "context" 5 gonet "net" 6 "time" 7 8 "github.com/v2fly/v2ray-core/v5/transport/internet/transportcommon" 9 10 "github.com/v2fly/v2ray-core/v5/common" 11 "github.com/v2fly/v2ray-core/v5/common/net" 12 "github.com/v2fly/v2ray-core/v5/common/serial" 13 "github.com/v2fly/v2ray-core/v5/common/session" 14 "github.com/v2fly/v2ray-core/v5/transport/internet" 15 "github.com/v2fly/v2ray-core/v5/transport/internet/request" 16 ) 17 18 type client struct { 19 tripper request.RoundTripperClient 20 assembler request.SessionAssemblerClient 21 22 streamSettings *internet.MemoryStreamConfig 23 dest net.Destination 24 } 25 26 func (c client) Dial(ctx context.Context) (net.Conn, error) { 27 return transportcommon.DialWithSecuritySettings(ctx, c.dest, c.streamSettings) 28 } 29 30 func (c client) AutoImplDialer() request.Dialer { 31 return c 32 } 33 34 func (c client) Tripper() request.Tripper { 35 return c.tripper 36 } 37 38 func (c client) dialRequestSession(ctx context.Context) (net.Conn, error) { 39 session, err := c.assembler.NewSession(ctx) 40 if err != nil { 41 return nil, newError("failed to create new session").Base(err) 42 } 43 return clientConnection{session}, nil 44 } 45 46 type clientConnection struct { 47 request.Session 48 } 49 50 func (c clientConnection) LocalAddr() gonet.Addr { 51 return &net.UnixAddr{Name: "unimplemented"} 52 } 53 54 func (c clientConnection) RemoteAddr() gonet.Addr { 55 return &net.UnixAddr{Name: "unimplemented"} 56 } 57 58 func (c clientConnection) SetDeadline(t time.Time) error { 59 // Unimplemented 60 return nil 61 } 62 63 func (c clientConnection) SetReadDeadline(t time.Time) error { 64 // Unimplemented 65 return nil 66 } 67 68 func (c clientConnection) SetWriteDeadline(t time.Time) error { 69 // Unimplemented 70 return nil 71 } 72 73 func dialRequest(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (net.Conn, error) { 74 clientAssembly := &client{} 75 transportConfiguration := streamSettings.ProtocolSettings.(*Config) 76 77 assemblerConfigInstance, err := serial.GetInstanceOf(transportConfiguration.Assembler) 78 if err != nil { 79 return nil, newError("failed to get config instance of assembler").Base(err) 80 } 81 assembler, err := common.CreateObject(ctx, assemblerConfigInstance) 82 if err != nil { 83 return nil, newError("failed to create assembler").Base(err) 84 } 85 if typedAssembler, ok := assembler.(request.SessionAssemblerClient); !ok { 86 return nil, newError("failed to type assert assembler to SessionAssemblerClient") 87 } else { 88 clientAssembly.assembler = typedAssembler 89 } 90 91 roundtripperConfigInstance, err := serial.GetInstanceOf(transportConfiguration.Roundtripper) 92 if err != nil { 93 return nil, newError("failed to get config instance of roundtripper").Base(err) 94 } 95 roundtripper, err := common.CreateObject(ctx, roundtripperConfigInstance) 96 if err != nil { 97 return nil, newError("failed to create roundtripper").Base(err) 98 } 99 if typedRoundtripper, ok := roundtripper.(request.RoundTripperClient); !ok { 100 return nil, newError("failed to type assert roundtripper to RoundTripperClient") 101 } else { 102 clientAssembly.tripper = typedRoundtripper 103 } 104 105 clientAssembly.streamSettings = streamSettings 106 clientAssembly.dest = dest 107 108 clientAssembly.assembler.OnTransportClientAssemblyReady(clientAssembly) 109 clientAssembly.tripper.OnTransportClientAssemblyReady(clientAssembly) 110 return clientAssembly.dialRequestSession(ctx) 111 } 112 113 func dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { 114 newError("creating connection to ", dest).WriteToLog(session.ExportIDToError(ctx)) 115 116 conn, err := dialRequest(ctx, dest, streamSettings) 117 if err != nil { 118 return nil, newError("failed to dial request to ", dest).Base(err) 119 } 120 return internet.Connection(conn), nil 121 } 122 123 func init() { 124 common.Must(internet.RegisterTransportDialer(protocolName, dial)) 125 }