github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/inbound/vmess.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/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 "github.com/sagernet/sing/common/ntp" 23 ) 24 25 var ( 26 _ adapter.Inbound = (*VMess)(nil) 27 _ adapter.InjectableInbound = (*VMess)(nil) 28 ) 29 30 type VMess struct { 31 myInboundAdapter 32 ctx context.Context 33 service *vmess.Service[int] 34 users []option.VMessUser 35 tlsConfig tls.ServerConfig 36 transport adapter.V2RayServerTransport 37 } 38 39 func NewVMess(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VMessInboundOptions) (*VMess, error) { 40 inbound := &VMess{ 41 myInboundAdapter: myInboundAdapter{ 42 protocol: C.TypeVMess, 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 var serviceOptions []vmess.ServiceOption 54 if timeFunc := ntp.TimeFuncFromContext(ctx); timeFunc != nil { 55 serviceOptions = append(serviceOptions, vmess.ServiceWithTimeFunc(timeFunc)) 56 } 57 if options.Transport != nil && options.Transport.Type != "" { 58 serviceOptions = append(serviceOptions, vmess.ServiceWithDisableHeaderProtection()) 59 } 60 service := vmess.NewService[int](adapter.NewUpstreamContextHandler(inbound.newConnection, inbound.newPacketConnection, inbound), serviceOptions...) 61 inbound.service = service 62 err := service.UpdateUsers(common.MapIndexed(options.Users, func(index int, it option.VMessUser) int { 63 return index 64 }), common.Map(options.Users, func(it option.VMessUser) string { 65 return it.UUID 66 }), common.Map(options.Users, func(it option.VMessUser) int { 67 return it.AlterId 68 })) 69 if err != nil { 70 return nil, err 71 } 72 if options.TLS != nil { 73 inbound.tlsConfig, err = tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS)) 74 if err != nil { 75 return nil, err 76 } 77 } 78 if options.Transport != nil { 79 inbound.transport, err = v2ray.NewServerTransport(ctx, common.PtrValueOrDefault(options.Transport), inbound.tlsConfig, (*vmessTransportHandler)(inbound)) 80 if err != nil { 81 return nil, E.Cause(err, "create server transport: ", options.Transport.Type) 82 } 83 } 84 inbound.connHandler = inbound 85 return inbound, nil 86 } 87 88 func (h *VMess) Start() error { 89 err := common.Start( 90 h.service, 91 h.tlsConfig, 92 ) 93 if err != nil { 94 return err 95 } 96 if h.transport == nil { 97 return h.myInboundAdapter.Start() 98 } 99 if common.Contains(h.transport.Network(), N.NetworkTCP) { 100 tcpListener, err := h.myInboundAdapter.ListenTCP() 101 if err != nil { 102 return err 103 } 104 go func() { 105 sErr := h.transport.Serve(tcpListener) 106 if sErr != nil && !E.IsClosed(sErr) { 107 h.logger.Error("transport serve error: ", sErr) 108 } 109 }() 110 } 111 if common.Contains(h.transport.Network(), N.NetworkUDP) { 112 udpConn, err := h.myInboundAdapter.ListenUDP() 113 if err != nil { 114 return err 115 } 116 go func() { 117 sErr := h.transport.ServePacket(udpConn) 118 if sErr != nil && !E.IsClosed(sErr) { 119 h.logger.Error("transport serve error: ", sErr) 120 } 121 }() 122 } 123 return nil 124 } 125 126 func (h *VMess) AddUsers(users []option.VMessUser) error { 127 if cap(h.users)-len(h.users) >= len(users) { 128 h.users = append(h.users, users...) 129 } else { 130 tmp := make([]option.VMessUser, 0, len(h.users)+len(users)+10) 131 tmp = append(tmp, h.users...) 132 tmp = append(tmp, users...) 133 h.users = tmp 134 } 135 err := h.service.UpdateUsers(common.MapIndexed(h.users, func(index int, it option.VMessUser) int { 136 return index 137 }), common.Map(h.users, func(it option.VMessUser) string { 138 return it.UUID 139 }), common.Map(h.users, func(it option.VMessUser) int { 140 return it.AlterId 141 })) 142 if err != nil { 143 return err 144 } 145 return nil 146 } 147 148 func (h *VMess) DelUsers(name []string) error { 149 is := make([]int, 0, len(name)) 150 ulen := len(name) 151 for i := range h.users { 152 for _, u := range name { 153 if h.users[i].Name == u { 154 is = append(is, i) 155 ulen-- 156 } 157 if ulen == 0 { 158 break 159 } 160 } 161 } 162 ulen = len(h.users) 163 for _, i := range is { 164 h.users[i] = h.users[ulen-1] 165 h.users[ulen-1] = option.VMessUser{} 166 h.users = h.users[:ulen-1] 167 ulen-- 168 } 169 err := h.service.UpdateUsers(common.MapIndexed(h.users, func(index int, it option.VMessUser) int { 170 return index 171 }), common.Map(h.users, func(it option.VMessUser) string { 172 return it.UUID 173 }), common.Map(h.users, func(it option.VMessUser) int { 174 return it.AlterId 175 })) 176 if err != nil { 177 return err 178 } 179 return nil 180 } 181 182 func (h *VMess) Close() error { 183 return common.Close( 184 h.service, 185 &h.myInboundAdapter, 186 h.tlsConfig, 187 h.transport, 188 ) 189 } 190 191 func (h *VMess) newTransportConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { 192 h.injectTCP(conn, metadata) 193 return nil 194 } 195 196 func (h *VMess) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { 197 var err error 198 if h.tlsConfig != nil && h.transport == nil { 199 conn, err = tls.ServerHandshake(ctx, conn, h.tlsConfig) 200 if err != nil { 201 return err 202 } 203 } 204 return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata)) 205 } 206 207 func (h *VMess) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { 208 return os.ErrInvalid 209 } 210 211 func (h *VMess) newConnection(ctx context.Context, conn net.Conn, 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 h.logger.InfoContext(ctx, "[", user, "] inbound connection to ", metadata.Destination) 223 return h.router.RouteConnection(ctx, conn, metadata) 224 } 225 226 func (h *VMess) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { 227 userIndex, loaded := auth.UserFromContext[int](ctx) 228 if !loaded { 229 return os.ErrInvalid 230 } 231 user := h.users[userIndex].Name 232 if user == "" { 233 user = F.ToString(userIndex) 234 } else { 235 metadata.User = user 236 } 237 if metadata.Destination.Fqdn == packetaddr.SeqPacketMagicAddress { 238 metadata.Destination = M.Socksaddr{} 239 conn = packetaddr.NewConn(conn.(vmess.PacketConn), metadata.Destination) 240 h.logger.InfoContext(ctx, "[", user, "] inbound packet addr connection") 241 } else { 242 h.logger.InfoContext(ctx, "[", user, "] inbound packet connection to ", metadata.Destination) 243 } 244 return h.router.RoutePacketConnection(ctx, conn, metadata) 245 } 246 247 var _ adapter.V2RayServerTransportHandler = (*vmessTransportHandler)(nil) 248 249 type vmessTransportHandler VMess 250 251 func (t *vmessTransportHandler) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { 252 return (*VMess)(t).newTransportConnection(ctx, conn, adapter.InboundContext{ 253 Source: metadata.Source, 254 Destination: metadata.Destination, 255 }) 256 } 257 258 func (t *vmessTransportHandler) FallbackConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { 259 return os.ErrInvalid 260 }