github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/proxy/shadowsocks_2022/inbound.go (about) 1 package shadowsocks_2022 2 3 import ( 4 "context" 5 6 shadowsocks "github.com/sagernet/sing-shadowsocks" 7 "github.com/sagernet/sing-shadowsocks/shadowaead_2022" 8 C "github.com/sagernet/sing/common" 9 B "github.com/sagernet/sing/common/buf" 10 "github.com/sagernet/sing/common/bufio" 11 E "github.com/sagernet/sing/common/exceptions" 12 M "github.com/sagernet/sing/common/metadata" 13 N "github.com/sagernet/sing/common/network" 14 "github.com/xmplusdev/xmcore/common" 15 "github.com/xmplusdev/xmcore/common/buf" 16 "github.com/xmplusdev/xmcore/common/log" 17 "github.com/xmplusdev/xmcore/common/net" 18 "github.com/xmplusdev/xmcore/common/protocol" 19 "github.com/xmplusdev/xmcore/common/session" 20 "github.com/xmplusdev/xmcore/common/singbridge" 21 "github.com/xmplusdev/xmcore/features/routing" 22 "github.com/xmplusdev/xmcore/transport/internet/stat" 23 ) 24 25 func init() { 26 common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 27 return NewServer(ctx, config.(*ServerConfig)) 28 })) 29 } 30 31 type Inbound struct { 32 networks []net.Network 33 service shadowsocks.Service 34 email string 35 level int 36 } 37 38 func NewServer(ctx context.Context, config *ServerConfig) (*Inbound, error) { 39 networks := config.Network 40 if len(networks) == 0 { 41 networks = []net.Network{ 42 net.Network_TCP, 43 net.Network_UDP, 44 } 45 } 46 inbound := &Inbound{ 47 networks: networks, 48 email: config.Email, 49 level: int(config.Level), 50 } 51 if !C.Contains(shadowaead_2022.List, config.Method) { 52 return nil, newError("unsupported method ", config.Method) 53 } 54 service, err := shadowaead_2022.NewServiceWithPassword(config.Method, config.Key, 500, inbound, nil) 55 if err != nil { 56 return nil, newError("create service").Base(err) 57 } 58 inbound.service = service 59 return inbound, nil 60 } 61 62 func (i *Inbound) Network() []net.Network { 63 return i.networks 64 } 65 66 func (i *Inbound) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error { 67 inbound := session.InboundFromContext(ctx) 68 inbound.Name = "shadowsocks-2022" 69 inbound.SetCanSpliceCopy(3) 70 71 var metadata M.Metadata 72 if inbound.Source.IsValid() { 73 metadata.Source = M.ParseSocksaddr(inbound.Source.NetAddr()) 74 } 75 76 ctx = session.ContextWithDispatcher(ctx, dispatcher) 77 78 if network == net.Network_TCP { 79 return singbridge.ReturnError(i.service.NewConnection(ctx, connection, metadata)) 80 } else { 81 reader := buf.NewReader(connection) 82 pc := &natPacketConn{connection} 83 for { 84 mb, err := reader.ReadMultiBuffer() 85 if err != nil { 86 buf.ReleaseMulti(mb) 87 return singbridge.ReturnError(err) 88 } 89 for _, buffer := range mb { 90 packet := B.As(buffer.Bytes()).ToOwned() 91 buffer.Release() 92 err = i.service.NewPacket(ctx, pc, packet, metadata) 93 if err != nil { 94 packet.Release() 95 buf.ReleaseMulti(mb) 96 return err 97 } 98 } 99 } 100 } 101 } 102 103 func (i *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { 104 inbound := session.InboundFromContext(ctx) 105 inbound.User = &protocol.MemoryUser{ 106 Email: i.email, 107 Level: uint32(i.level), 108 } 109 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 110 From: metadata.Source, 111 To: metadata.Destination, 112 Status: log.AccessAccepted, 113 Email: i.email, 114 }) 115 newError("tunnelling request to tcp:", metadata.Destination).WriteToLog(session.ExportIDToError(ctx)) 116 dispatcher := session.DispatcherFromContext(ctx) 117 link, err := dispatcher.Dispatch(ctx, singbridge.ToDestination(metadata.Destination, net.Network_TCP)) 118 if err != nil { 119 return err 120 } 121 return singbridge.CopyConn(ctx, nil, link, conn) 122 } 123 124 func (i *Inbound) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { 125 inbound := session.InboundFromContext(ctx) 126 inbound.User = &protocol.MemoryUser{ 127 Email: i.email, 128 Level: uint32(i.level), 129 } 130 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 131 From: metadata.Source, 132 To: metadata.Destination, 133 Status: log.AccessAccepted, 134 Email: i.email, 135 }) 136 newError("tunnelling request to udp:", metadata.Destination).WriteToLog(session.ExportIDToError(ctx)) 137 dispatcher := session.DispatcherFromContext(ctx) 138 destination := singbridge.ToDestination(metadata.Destination, net.Network_UDP) 139 link, err := dispatcher.Dispatch(ctx, destination) 140 if err != nil { 141 return err 142 } 143 outConn := &singbridge.PacketConnWrapper{ 144 Reader: link.Reader, 145 Writer: link.Writer, 146 Dest: destination, 147 } 148 return bufio.CopyPacketConn(ctx, conn, outConn) 149 } 150 151 func (i *Inbound) NewError(ctx context.Context, err error) { 152 if E.IsClosed(err) { 153 return 154 } 155 newError(err).AtWarning().WriteToLog() 156 } 157 158 type natPacketConn struct { 159 net.Conn 160 } 161 162 func (c *natPacketConn) ReadPacket(buffer *B.Buffer) (addr M.Socksaddr, err error) { 163 _, err = buffer.ReadFrom(c) 164 return 165 } 166 167 func (c *natPacketConn) WritePacket(buffer *B.Buffer, addr M.Socksaddr) error { 168 _, err := buffer.WriteTo(c) 169 return err 170 }