github.com/sagernet/sing-box@v1.9.0-rc.20/inbound/shadowsocks.go (about) 1 package inbound 2 3 import ( 4 "context" 5 "net" 6 "os" 7 "time" 8 9 "github.com/sagernet/sing-box/adapter" 10 "github.com/sagernet/sing-box/common/mux" 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-shadowsocks" 16 "github.com/sagernet/sing-shadowsocks/shadowaead" 17 "github.com/sagernet/sing-shadowsocks/shadowaead_2022" 18 "github.com/sagernet/sing/common" 19 "github.com/sagernet/sing/common/buf" 20 E "github.com/sagernet/sing/common/exceptions" 21 N "github.com/sagernet/sing/common/network" 22 "github.com/sagernet/sing/common/ntp" 23 ) 24 25 func NewShadowsocks(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksInboundOptions) (adapter.Inbound, error) { 26 if len(options.Users) > 0 && len(options.Destinations) > 0 { 27 return nil, E.New("users and destinations options must not be combined") 28 } 29 if len(options.Users) > 0 { 30 return newShadowsocksMulti(ctx, router, logger, tag, options) 31 } else if len(options.Destinations) > 0 { 32 return newShadowsocksRelay(ctx, router, logger, tag, options) 33 } else { 34 return newShadowsocks(ctx, router, logger, tag, options) 35 } 36 } 37 38 var ( 39 _ adapter.Inbound = (*Shadowsocks)(nil) 40 _ adapter.InjectableInbound = (*Shadowsocks)(nil) 41 ) 42 43 type Shadowsocks struct { 44 myInboundAdapter 45 service shadowsocks.Service 46 } 47 48 func newShadowsocks(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksInboundOptions) (*Shadowsocks, error) { 49 inbound := &Shadowsocks{ 50 myInboundAdapter: myInboundAdapter{ 51 protocol: C.TypeShadowsocks, 52 network: options.Network.Build(), 53 ctx: ctx, 54 router: uot.NewRouter(router, logger), 55 logger: logger, 56 tag: tag, 57 listenOptions: options.ListenOptions, 58 }, 59 } 60 61 inbound.connHandler = inbound 62 inbound.packetHandler = inbound 63 var err error 64 inbound.router, err = mux.NewRouterWithOptions(inbound.router, logger, common.PtrValueOrDefault(options.Multiplex)) 65 if err != nil { 66 return nil, err 67 } 68 69 var udpTimeout time.Duration 70 if options.UDPTimeout != 0 { 71 udpTimeout = time.Duration(options.UDPTimeout) 72 } else { 73 udpTimeout = C.UDPTimeout 74 } 75 switch { 76 case options.Method == shadowsocks.MethodNone: 77 inbound.service = shadowsocks.NewNoneService(int64(udpTimeout.Seconds()), inbound.upstreamContextHandler()) 78 case common.Contains(shadowaead.List, options.Method): 79 inbound.service, err = shadowaead.NewService(options.Method, nil, options.Password, int64(udpTimeout.Seconds()), inbound.upstreamContextHandler()) 80 case common.Contains(shadowaead_2022.List, options.Method): 81 inbound.service, err = shadowaead_2022.NewServiceWithPassword(options.Method, options.Password, int64(udpTimeout.Seconds()), inbound.upstreamContextHandler(), ntp.TimeFuncFromContext(ctx)) 82 default: 83 err = E.New("unsupported method: ", options.Method) 84 } 85 inbound.packetUpstream = inbound.service 86 return inbound, err 87 } 88 89 func (h *Shadowsocks) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { 90 return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata)) 91 } 92 93 func (h *Shadowsocks) NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext) error { 94 return h.service.NewPacket(adapter.WithContext(ctx, &metadata), conn, buffer, adapter.UpstreamMetadata(metadata)) 95 } 96 97 func (h *Shadowsocks) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { 98 return os.ErrInvalid 99 }