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 }