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