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