github.com/imannamdari/v2ray-core/v5@v5.0.5/proxy/vlite/inbound/inbound.go (about) 1 package inbound 2 3 import ( 4 "context" 5 "io" 6 gonet "net" 7 "strconv" 8 "sync" 9 10 "github.com/mustafaturan/bus" 11 "github.com/xiaokangwang/VLite/interfaces" 12 "github.com/xiaokangwang/VLite/interfaces/ibus" 13 "github.com/xiaokangwang/VLite/transport" 14 udpsctpserver "github.com/xiaokangwang/VLite/transport/packetsctp/sctprelay" 15 "github.com/xiaokangwang/VLite/transport/packetuni/puniServer" 16 "github.com/xiaokangwang/VLite/transport/udp/udpServer" 17 "github.com/xiaokangwang/VLite/transport/udp/udpuni/udpunis" 18 "github.com/xiaokangwang/VLite/transport/uni/uniserver" 19 "github.com/xiaokangwang/VLite/workers/server" 20 21 "github.com/imannamdari/v2ray-core/v5/common" 22 "github.com/imannamdari/v2ray-core/v5/common/environment" 23 "github.com/imannamdari/v2ray-core/v5/common/environment/envctx" 24 "github.com/imannamdari/v2ray-core/v5/common/net" 25 "github.com/imannamdari/v2ray-core/v5/common/session" 26 "github.com/imannamdari/v2ray-core/v5/common/signal/done" 27 "github.com/imannamdari/v2ray-core/v5/features/routing" 28 "github.com/imannamdari/v2ray-core/v5/transport/internet" 29 ) 30 31 //go:generate go run github.com/imannamdari/v2ray-core/v5/common/errors/errorgen 32 33 func NewUDPInboundHandler(ctx context.Context, config *UDPProtocolConfig) (*Handler, error) { 34 proxyEnvironment := envctx.EnvironmentFromContext(ctx).(environment.ProxyEnvironment) 35 statusInstance, err := createStatusFromConfig(config) 36 if err != nil { 37 return nil, newError("unable to initialize vlite").Base(err) 38 } 39 proxyEnvironment.TransientStorage().Put(ctx, "status", statusInstance) 40 return &Handler{ctx: ctx}, nil 41 } 42 43 type Handler struct { 44 ctx context.Context 45 } 46 47 func (h *Handler) Network() []net.Network { 48 list := []net.Network{net.Network_UDP} 49 return list 50 } 51 52 type status struct { 53 config *UDPProtocolConfig 54 55 password []byte 56 msgbus *bus.Bus 57 58 ctx context.Context 59 60 transport transport.UnderlayTransportListener 61 62 access sync.Mutex 63 } 64 65 func (s *status) RelayStream(conn io.ReadWriteCloser, ctx context.Context) { //nolint:revive 66 } 67 68 func (s *status) Connection(conn gonet.Conn, connctx context.Context) context.Context { //nolint:revive,stylecheck 69 S_S2CTraffic := make(chan server.UDPServerTxToClientTraffic, 8) //nolint:revive,stylecheck 70 S_S2CDataTraffic := make(chan server.UDPServerTxToClientDataTraffic, 8) //nolint:revive,stylecheck 71 S_C2STraffic := make(chan server.UDPServerRxFromClientTraffic, 8) //nolint:revive,stylecheck 72 73 S_S2CTraffic2 := make(chan interfaces.TrafficWithChannelTag, 8) //nolint:revive,stylecheck 74 S_S2CDataTraffic2 := make(chan interfaces.TrafficWithChannelTag, 8) //nolint:revive,stylecheck 75 S_C2STraffic2 := make(chan interfaces.TrafficWithChannelTag, 8) //nolint:revive,stylecheck 76 77 go func(ctx context.Context) { 78 for { 79 select { 80 case data := <-S_S2CTraffic: 81 S_S2CTraffic2 <- interfaces.TrafficWithChannelTag(data) 82 case <-ctx.Done(): 83 return 84 } 85 } 86 }(connctx) 87 88 go func(ctx context.Context) { 89 for { 90 select { 91 case data := <-S_S2CDataTraffic: 92 S_S2CDataTraffic2 <- interfaces.TrafficWithChannelTag(data) 93 case <-ctx.Done(): 94 return 95 } 96 } 97 }(connctx) 98 99 go func(ctx context.Context) { 100 for { 101 select { 102 case data := <-S_C2STraffic2: 103 S_C2STraffic <- server.UDPServerRxFromClientTraffic(data) 104 case <-ctx.Done(): 105 return 106 } 107 } 108 }(connctx) 109 110 if !s.config.EnableStabilization || !s.config.EnableRenegotiation { 111 relay := udpsctpserver.NewPacketRelayServer(conn, S_S2CTraffic2, S_S2CDataTraffic2, S_C2STraffic2, s, s.password, connctx) 112 udpserver := server.UDPServer(connctx, S_S2CTraffic, S_S2CDataTraffic, S_C2STraffic, relay) 113 _ = udpserver 114 } else { 115 relay := puniServer.NewPacketUniServer(S_S2CTraffic2, S_S2CDataTraffic2, S_C2STraffic2, s, s.password, connctx) 116 relay.OnAutoCarrier(conn, connctx) 117 udpserver := server.UDPServer(connctx, S_S2CTraffic, S_S2CDataTraffic, S_C2STraffic, relay) 118 _ = udpserver 119 } 120 return connctx 121 } 122 123 func createStatusFromConfig(config *UDPProtocolConfig) (*status, error) { //nolint:unparam 124 s := &status{ctx: context.Background(), config: config} 125 126 s.password = []byte(config.Password) 127 128 s.msgbus = ibus.NewMessageBus() 129 s.ctx = context.WithValue(s.ctx, interfaces.ExtraOptionsMessageBus, s.msgbus) //nolint:revive,staticcheck 130 131 if config.ScramblePacket { 132 s.ctx = context.WithValue(s.ctx, interfaces.ExtraOptionsUDPShouldMask, true) //nolint:revive,staticcheck 133 } 134 135 if s.config.EnableFec { 136 s.ctx = context.WithValue(s.ctx, interfaces.ExtraOptionsUDPFECEnabled, true) //nolint:revive,staticcheck 137 } 138 139 s.ctx = context.WithValue(s.ctx, interfaces.ExtraOptionsUDPMask, string(s.password)) //nolint:revive,staticcheck 140 141 if config.HandshakeMaskingPaddingSize != 0 { 142 ctxv := &interfaces.ExtraOptionsUsePacketArmorValue{PacketArmorPaddingTo: int(config.HandshakeMaskingPaddingSize), UsePacketArmor: true} 143 s.ctx = context.WithValue(s.ctx, interfaces.ExtraOptionsUsePacketArmor, ctxv) //nolint:revive,staticcheck 144 } 145 146 return s, nil 147 } 148 149 func enableInterface(s *status) error { 150 s.transport = s 151 if s.config.EnableStabilization { 152 s.transport = uniserver.NewUnifiedConnectionTransportHub(s, s.ctx) 153 } 154 if s.config.EnableStabilization { 155 s.transport = udpunis.NewUdpUniServer(string(s.password), s.ctx, s.transport) 156 } 157 return nil 158 } 159 160 func (h *Handler) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error { 161 proxyEnvironment := envctx.EnvironmentFromContext(h.ctx).(environment.ProxyEnvironment) 162 statusInstanceIfce, err := proxyEnvironment.TransientStorage().Get(ctx, "status") 163 if err != nil { 164 return newError("uninitialized handler").Base(err) 165 } 166 statusInstance := statusInstanceIfce.(*status) 167 err = h.ensureStarted(statusInstance) 168 if err != nil { 169 return newError("unable to initialize").Base(err) 170 } 171 finish := done.New() 172 conn = newUDPConnAdaptor(conn, finish) 173 var initialData [1600]byte 174 c, err := conn.Read(initialData[:]) 175 if err != nil { 176 return newError("unable to read initial data").Base(err) 177 } 178 connID := session.IDFromContext(ctx) 179 vconn, connctx := udpServer.PrepareIncomingUDPConnection(conn, statusInstance.ctx, initialData[:c], strconv.FormatInt(int64(connID), 10)) 180 connctx = statusInstance.transport.Connection(vconn, connctx) 181 if connctx == nil { 182 return newError("invalid connection discarded") 183 } 184 <-finish.Wait() 185 return nil 186 } 187 188 func (h *Handler) ensureStarted(s *status) error { 189 s.access.Lock() 190 defer s.access.Unlock() 191 if s.transport == nil { 192 err := enableInterface(s) 193 if err != nil { 194 return err 195 } 196 } 197 return nil 198 } 199 200 func init() { 201 common.Must(common.RegisterConfig((*UDPProtocolConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 202 return NewUDPInboundHandler(ctx, config.(*UDPProtocolConfig)) 203 })) 204 }