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