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 }