github.com/sagernet/sing-box@v1.9.0-rc.20/inbound/vless.go (about)

     1  package inbound
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"os"
     7  
     8  	"github.com/sagernet/sing-box/adapter"
     9  	"github.com/sagernet/sing-box/common/mux"
    10  	"github.com/sagernet/sing-box/common/tls"
    11  	"github.com/sagernet/sing-box/common/uot"
    12  	C "github.com/sagernet/sing-box/constant"
    13  	"github.com/sagernet/sing-box/log"
    14  	"github.com/sagernet/sing-box/option"
    15  	"github.com/sagernet/sing-box/transport/v2ray"
    16  	"github.com/sagernet/sing-box/transport/vless"
    17  	"github.com/sagernet/sing-vmess"
    18  	"github.com/sagernet/sing-vmess/packetaddr"
    19  	"github.com/sagernet/sing/common"
    20  	"github.com/sagernet/sing/common/auth"
    21  	E "github.com/sagernet/sing/common/exceptions"
    22  	F "github.com/sagernet/sing/common/format"
    23  	M "github.com/sagernet/sing/common/metadata"
    24  	N "github.com/sagernet/sing/common/network"
    25  )
    26  
    27  var (
    28  	_ adapter.Inbound           = (*VLESS)(nil)
    29  	_ adapter.InjectableInbound = (*VLESS)(nil)
    30  )
    31  
    32  type VLESS struct {
    33  	myInboundAdapter
    34  	ctx       context.Context
    35  	users     []option.VLESSUser
    36  	service   *vless.Service[int]
    37  	tlsConfig tls.ServerConfig
    38  	transport adapter.V2RayServerTransport
    39  }
    40  
    41  func NewVLESS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VLESSInboundOptions) (*VLESS, error) {
    42  	inbound := &VLESS{
    43  		myInboundAdapter: myInboundAdapter{
    44  			protocol:      C.TypeVLESS,
    45  			network:       []string{N.NetworkTCP},
    46  			ctx:           ctx,
    47  			router:        uot.NewRouter(router, logger),
    48  			logger:        logger,
    49  			tag:           tag,
    50  			listenOptions: options.ListenOptions,
    51  		},
    52  		ctx:   ctx,
    53  		users: options.Users,
    54  	}
    55  	var err error
    56  	inbound.router, err = mux.NewRouterWithOptions(inbound.router, logger, common.PtrValueOrDefault(options.Multiplex))
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	service := vless.NewService[int](logger, adapter.NewUpstreamContextHandler(inbound.newConnection, inbound.newPacketConnection, inbound))
    61  	service.UpdateUsers(common.MapIndexed(inbound.users, func(index int, _ option.VLESSUser) int {
    62  		return index
    63  	}), common.Map(inbound.users, func(it option.VLESSUser) string {
    64  		return it.UUID
    65  	}), common.Map(inbound.users, func(it option.VLESSUser) string {
    66  		return it.Flow
    67  	}))
    68  	inbound.service = service
    69  	if options.TLS != nil {
    70  		inbound.tlsConfig, err = tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS))
    71  		if err != nil {
    72  			return nil, err
    73  		}
    74  	}
    75  	if options.Transport != nil {
    76  		inbound.transport, err = v2ray.NewServerTransport(ctx, common.PtrValueOrDefault(options.Transport), inbound.tlsConfig, (*vlessTransportHandler)(inbound))
    77  		if err != nil {
    78  			return nil, E.Cause(err, "create server transport: ", options.Transport.Type)
    79  		}
    80  	}
    81  	inbound.connHandler = inbound
    82  	return inbound, nil
    83  }
    84  
    85  func (h *VLESS) Start() error {
    86  	err := common.Start(
    87  		h.service,
    88  		h.tlsConfig,
    89  	)
    90  	if err != nil {
    91  		return err
    92  	}
    93  	if h.transport == nil {
    94  		return h.myInboundAdapter.Start()
    95  	}
    96  	if common.Contains(h.transport.Network(), N.NetworkTCP) {
    97  		tcpListener, err := h.myInboundAdapter.ListenTCP()
    98  		if err != nil {
    99  			return err
   100  		}
   101  		go func() {
   102  			sErr := h.transport.Serve(tcpListener)
   103  			if sErr != nil && !E.IsClosed(sErr) {
   104  				h.logger.Error("transport serve error: ", sErr)
   105  			}
   106  		}()
   107  	}
   108  	if common.Contains(h.transport.Network(), N.NetworkUDP) {
   109  		udpConn, err := h.myInboundAdapter.ListenUDP()
   110  		if err != nil {
   111  			return err
   112  		}
   113  		go func() {
   114  			sErr := h.transport.ServePacket(udpConn)
   115  			if sErr != nil && !E.IsClosed(sErr) {
   116  				h.logger.Error("transport serve error: ", sErr)
   117  			}
   118  		}()
   119  	}
   120  	return nil
   121  }
   122  
   123  func (h *VLESS) Close() error {
   124  	return common.Close(
   125  		h.service,
   126  		&h.myInboundAdapter,
   127  		h.tlsConfig,
   128  		h.transport,
   129  	)
   130  }
   131  
   132  func (h *VLESS) newTransportConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
   133  	h.injectTCP(conn, metadata)
   134  	return nil
   135  }
   136  
   137  func (h *VLESS) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
   138  	var err error
   139  	if h.tlsConfig != nil && h.transport == nil {
   140  		conn, err = tls.ServerHandshake(ctx, conn, h.tlsConfig)
   141  		if err != nil {
   142  			return err
   143  		}
   144  	}
   145  	return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata))
   146  }
   147  
   148  func (h *VLESS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
   149  	return os.ErrInvalid
   150  }
   151  
   152  func (h *VLESS) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
   153  	userIndex, loaded := auth.UserFromContext[int](ctx)
   154  	if !loaded {
   155  		return os.ErrInvalid
   156  	}
   157  	user := h.users[userIndex].Name
   158  	if user == "" {
   159  		user = F.ToString(userIndex)
   160  	} else {
   161  		metadata.User = user
   162  	}
   163  	h.logger.InfoContext(ctx, "[", user, "] inbound connection to ", metadata.Destination)
   164  	return h.router.RouteConnection(ctx, conn, metadata)
   165  }
   166  
   167  func (h *VLESS) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
   168  	userIndex, loaded := auth.UserFromContext[int](ctx)
   169  	if !loaded {
   170  		return os.ErrInvalid
   171  	}
   172  	user := h.users[userIndex].Name
   173  	if user == "" {
   174  		user = F.ToString(userIndex)
   175  	} else {
   176  		metadata.User = user
   177  	}
   178  	if metadata.Destination.Fqdn == packetaddr.SeqPacketMagicAddress {
   179  		metadata.Destination = M.Socksaddr{}
   180  		conn = packetaddr.NewConn(conn.(vmess.PacketConn), metadata.Destination)
   181  		h.logger.InfoContext(ctx, "[", user, "] inbound packet addr connection")
   182  	} else {
   183  		h.logger.InfoContext(ctx, "[", user, "] inbound packet connection to ", metadata.Destination)
   184  	}
   185  	return h.router.RoutePacketConnection(ctx, conn, metadata)
   186  }
   187  
   188  var _ adapter.V2RayServerTransportHandler = (*vlessTransportHandler)(nil)
   189  
   190  type vlessTransportHandler VLESS
   191  
   192  func (t *vlessTransportHandler) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
   193  	return (*VLESS)(t).newTransportConnection(ctx, conn, adapter.InboundContext{
   194  		Source:      metadata.Source,
   195  		Destination: metadata.Destination,
   196  	})
   197  }