github.com/xraypb/xray-core@v1.6.6/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) 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 68 var metadata M.Metadata 69 if inbound.Source.IsValid() { 70 metadata.Source = M.ParseSocksaddr(inbound.Source.NetAddr()) 71 } 72 73 ctx = session.ContextWithDispatcher(ctx, dispatcher) 74 75 if network == net.Network_TCP { 76 return returnError(i.service.NewConnection(ctx, connection, metadata)) 77 } else { 78 reader := buf.NewReader(connection) 79 pc := &natPacketConn{connection} 80 for { 81 mb, err := reader.ReadMultiBuffer() 82 if err != nil { 83 buf.ReleaseMulti(mb) 84 return returnError(err) 85 } 86 for _, buffer := range mb { 87 packet := B.As(buffer.Bytes()).ToOwned() 88 err = i.service.NewPacket(ctx, pc, packet, metadata) 89 if err != nil { 90 packet.Release() 91 buf.ReleaseMulti(mb) 92 return err 93 } 94 buffer.Release() 95 } 96 } 97 } 98 } 99 100 func (i *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { 101 inbound := session.InboundFromContext(ctx) 102 inbound.User = &protocol.MemoryUser{ 103 Email: i.email, 104 Level: uint32(i.level), 105 } 106 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 107 From: metadata.Source, 108 To: metadata.Destination, 109 Status: log.AccessAccepted, 110 Email: i.email, 111 }) 112 newError("tunnelling request to tcp:", metadata.Destination).WriteToLog(session.ExportIDToError(ctx)) 113 dispatcher := session.DispatcherFromContext(ctx) 114 link, err := dispatcher.Dispatch(ctx, toDestination(metadata.Destination, net.Network_TCP)) 115 if err != nil { 116 return err 117 } 118 outConn := &pipeConnWrapper{ 119 &buf.BufferedReader{Reader: link.Reader}, 120 link.Writer, 121 conn, 122 } 123 return bufio.CopyConn(ctx, conn, outConn) 124 } 125 126 func (i *Inbound) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { 127 inbound := session.InboundFromContext(ctx) 128 inbound.User = &protocol.MemoryUser{ 129 Email: i.email, 130 Level: uint32(i.level), 131 } 132 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 133 From: metadata.Source, 134 To: metadata.Destination, 135 Status: log.AccessAccepted, 136 Email: i.email, 137 }) 138 newError("tunnelling request to udp:", metadata.Destination).WriteToLog(session.ExportIDToError(ctx)) 139 dispatcher := session.DispatcherFromContext(ctx) 140 destination := toDestination(metadata.Destination, net.Network_UDP) 141 link, err := dispatcher.Dispatch(ctx, destination) 142 if err != nil { 143 return err 144 } 145 outConn := &packetConnWrapper{ 146 Reader: link.Reader, 147 Writer: link.Writer, 148 Dest: destination, 149 } 150 return bufio.CopyPacketConn(ctx, conn, outConn) 151 } 152 153 func (i *Inbound) NewError(ctx context.Context, err error) { 154 if E.IsClosed(err) { 155 return 156 } 157 newError(err).AtWarning().WriteToLog() 158 } 159 160 type natPacketConn struct { 161 net.Conn 162 } 163 164 func (c *natPacketConn) ReadPacket(buffer *B.Buffer) (addr M.Socksaddr, err error) { 165 _, err = buffer.ReadFrom(c) 166 return 167 } 168 169 func (c *natPacketConn) WritePacket(buffer *B.Buffer, addr M.Socksaddr) error { 170 _, err := buffer.WriteTo(c) 171 return err 172 }