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  }