github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/inbound/vless.go (about)

     1  package inbound
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"os"
     7  
     8  	"github.com/inazumav/sing-box/adapter"
     9  	"github.com/inazumav/sing-box/common/tls"
    10  	C "github.com/inazumav/sing-box/constant"
    11  	"github.com/inazumav/sing-box/log"
    12  	"github.com/inazumav/sing-box/option"
    13  	"github.com/inazumav/sing-box/transport/v2ray"
    14  	"github.com/inazumav/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, 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) AddUsers(users []option.VLESSUser) error {
   118  	if cap(h.users)-len(h.users) >= len(users) {
   119  		h.users = append(h.users, users...)
   120  	} else {
   121  		tmp := make([]option.VLESSUser, 0, len(h.users)+len(users)+10)
   122  		tmp = append(tmp, h.users...)
   123  		tmp = append(tmp, users...)
   124  		h.users = tmp
   125  	}
   126  	h.service.UpdateUsers(common.MapIndexed(h.users, func(index int, it option.VLESSUser) int {
   127  		return index
   128  	}), common.Map(h.users, func(it option.VLESSUser) string {
   129  		return it.UUID
   130  	}), common.Map(h.users, func(it option.VLESSUser) string {
   131  		return it.Flow
   132  	}))
   133  	return nil
   134  }
   135  
   136  func (h *VLESS) DelUsers(name []string) error {
   137  	is := make([]int, 0, len(name))
   138  	ulen := len(name)
   139  	for i := range h.users {
   140  		for _, u := range name {
   141  			if h.users[i].Name == u {
   142  				is = append(is, i)
   143  				ulen--
   144  			}
   145  			if ulen == 0 {
   146  				break
   147  			}
   148  		}
   149  	}
   150  	ulen = len(h.users)
   151  	for _, i := range is {
   152  		h.users[i] = h.users[ulen-1]
   153  		h.users[ulen-1] = option.VLESSUser{}
   154  		h.users = h.users[:ulen-1]
   155  		ulen--
   156  	}
   157  	h.service.UpdateUsers(common.MapIndexed(h.users, func(index int, it option.VLESSUser) int {
   158  		return index
   159  	}), common.Map(h.users, func(it option.VLESSUser) string {
   160  		return it.UUID
   161  	}), common.Map(h.users, func(it option.VLESSUser) string {
   162  		return it.Flow
   163  	}))
   164  	return nil
   165  }
   166  
   167  func (h *VLESS) Close() error {
   168  	return common.Close(
   169  		h.service,
   170  		&h.myInboundAdapter,
   171  		h.tlsConfig,
   172  		h.transport,
   173  	)
   174  }
   175  
   176  func (h *VLESS) newTransportConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
   177  	h.injectTCP(conn, metadata)
   178  	return nil
   179  }
   180  
   181  func (h *VLESS) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
   182  	var err error
   183  	if h.tlsConfig != nil && h.transport == nil {
   184  		conn, err = tls.ServerHandshake(ctx, conn, h.tlsConfig)
   185  		if err != nil {
   186  			return err
   187  		}
   188  	}
   189  	return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata))
   190  }
   191  
   192  func (h *VLESS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
   193  	return os.ErrInvalid
   194  }
   195  
   196  func (h *VLESS) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
   197  	userIndex, loaded := auth.UserFromContext[int](ctx)
   198  	if !loaded {
   199  		return os.ErrInvalid
   200  	}
   201  	user := h.users[userIndex].Name
   202  	if user == "" {
   203  		user = F.ToString(userIndex)
   204  	} else {
   205  		metadata.User = user
   206  	}
   207  	h.logger.InfoContext(ctx, "[", user, "] inbound connection to ", metadata.Destination)
   208  	return h.router.RouteConnection(ctx, conn, metadata)
   209  }
   210  
   211  func (h *VLESS) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
   212  	userIndex, loaded := auth.UserFromContext[int](ctx)
   213  	if !loaded {
   214  		return os.ErrInvalid
   215  	}
   216  	user := h.users[userIndex].Name
   217  	if user == "" {
   218  		user = F.ToString(userIndex)
   219  	} else {
   220  		metadata.User = user
   221  	}
   222  	if metadata.Destination.Fqdn == packetaddr.SeqPacketMagicAddress {
   223  		metadata.Destination = M.Socksaddr{}
   224  		conn = packetaddr.NewConn(conn.(vmess.PacketConn), metadata.Destination)
   225  		h.logger.InfoContext(ctx, "[", user, "] inbound packet addr connection")
   226  	} else {
   227  		h.logger.InfoContext(ctx, "[", user, "] inbound packet connection to ", metadata.Destination)
   228  	}
   229  	return h.router.RoutePacketConnection(ctx, conn, metadata)
   230  }
   231  
   232  var _ adapter.V2RayServerTransportHandler = (*vlessTransportHandler)(nil)
   233  
   234  type vlessTransportHandler VLESS
   235  
   236  func (t *vlessTransportHandler) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
   237  	return (*VLESS)(t).newTransportConnection(ctx, conn, adapter.InboundContext{
   238  		Source:      metadata.Source,
   239  		Destination: metadata.Destination,
   240  	})
   241  }
   242  
   243  func (t *vlessTransportHandler) FallbackConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
   244  	return os.ErrInvalid
   245  }