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