github.com/v2fly/v2ray-core/v4@v4.45.2/proxy/shadowsocks/server.go (about) 1 //go:build !confonly 2 // +build !confonly 3 4 package shadowsocks 5 6 import ( 7 "context" 8 "time" 9 10 core "github.com/v2fly/v2ray-core/v4" 11 "github.com/v2fly/v2ray-core/v4/common" 12 "github.com/v2fly/v2ray-core/v4/common/buf" 13 "github.com/v2fly/v2ray-core/v4/common/log" 14 "github.com/v2fly/v2ray-core/v4/common/net" 15 "github.com/v2fly/v2ray-core/v4/common/protocol" 16 udp_proto "github.com/v2fly/v2ray-core/v4/common/protocol/udp" 17 "github.com/v2fly/v2ray-core/v4/common/session" 18 "github.com/v2fly/v2ray-core/v4/common/signal" 19 "github.com/v2fly/v2ray-core/v4/common/task" 20 "github.com/v2fly/v2ray-core/v4/features/policy" 21 "github.com/v2fly/v2ray-core/v4/features/routing" 22 "github.com/v2fly/v2ray-core/v4/transport/internet" 23 "github.com/v2fly/v2ray-core/v4/transport/internet/udp" 24 ) 25 26 type Server struct { 27 config *ServerConfig 28 user *protocol.MemoryUser 29 policyManager policy.Manager 30 } 31 32 // NewServer create a new Shadowsocks server. 33 func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { 34 if config.GetUser() == nil { 35 return nil, newError("user is not specified") 36 } 37 38 mUser, err := config.User.ToMemoryUser() 39 if err != nil { 40 return nil, newError("failed to parse user account").Base(err) 41 } 42 43 v := core.MustFromContext(ctx) 44 s := &Server{ 45 config: config, 46 user: mUser, 47 policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), 48 } 49 50 return s, nil 51 } 52 53 func (s *Server) Network() []net.Network { 54 list := s.config.Network 55 if len(list) == 0 { 56 list = append(list, net.Network_TCP) 57 } 58 if s.config.UdpEnabled { 59 list = append(list, net.Network_UDP) 60 } 61 return list 62 } 63 64 func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error { 65 switch network { 66 case net.Network_TCP: 67 return s.handleConnection(ctx, conn, dispatcher) 68 case net.Network_UDP: 69 return s.handlerUDPPayload(ctx, conn, dispatcher) 70 default: 71 return newError("unknown network: ", network) 72 } 73 } 74 75 func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection, dispatcher routing.Dispatcher) error { 76 udpServer := udp.NewDispatcher(dispatcher, func(ctx context.Context, packet *udp_proto.Packet) { 77 request := protocol.RequestHeaderFromContext(ctx) 78 if request == nil { 79 return 80 } 81 82 payload := packet.Payload 83 data, err := EncodeUDPPacket(request, payload.Bytes()) 84 payload.Release() 85 if err != nil { 86 newError("failed to encode UDP packet").Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx)) 87 return 88 } 89 defer data.Release() 90 91 conn.Write(data.Bytes()) 92 }) 93 94 inbound := session.InboundFromContext(ctx) 95 if inbound == nil { 96 panic("no inbound metadata") 97 } 98 inbound.User = s.user 99 100 reader := buf.NewPacketReader(conn) 101 for { 102 mpayload, err := reader.ReadMultiBuffer() 103 if err != nil { 104 break 105 } 106 107 for _, payload := range mpayload { 108 request, data, err := DecodeUDPPacket(s.user, payload) 109 if err != nil { 110 if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() { 111 newError("dropping invalid UDP packet from: ", inbound.Source).Base(err).WriteToLog(session.ExportIDToError(ctx)) 112 log.Record(&log.AccessMessage{ 113 From: inbound.Source, 114 To: "", 115 Status: log.AccessRejected, 116 Reason: err, 117 }) 118 } 119 payload.Release() 120 continue 121 } 122 123 currentPacketCtx := ctx 124 dest := request.Destination() 125 if inbound.Source.IsValid() { 126 currentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 127 From: inbound.Source, 128 To: dest, 129 Status: log.AccessAccepted, 130 Reason: "", 131 Email: request.User.Email, 132 }) 133 } 134 newError("tunnelling request to ", dest).WriteToLog(session.ExportIDToError(currentPacketCtx)) 135 136 currentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request) 137 udpServer.Dispatch(currentPacketCtx, dest, data) 138 } 139 } 140 141 return nil 142 } 143 144 func (s *Server) handleConnection(ctx context.Context, conn internet.Connection, dispatcher routing.Dispatcher) error { 145 sessionPolicy := s.policyManager.ForLevel(s.user.Level) 146 conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)) 147 148 bufferedReader := buf.BufferedReader{Reader: buf.NewReader(conn)} 149 request, bodyReader, err := ReadTCPSession(s.user, &bufferedReader) 150 if err != nil { 151 log.Record(&log.AccessMessage{ 152 From: conn.RemoteAddr(), 153 To: "", 154 Status: log.AccessRejected, 155 Reason: err, 156 }) 157 return newError("failed to create request from: ", conn.RemoteAddr()).Base(err) 158 } 159 conn.SetReadDeadline(time.Time{}) 160 161 inbound := session.InboundFromContext(ctx) 162 if inbound == nil { 163 panic("no inbound metadata") 164 } 165 inbound.User = s.user 166 167 dest := request.Destination() 168 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 169 From: conn.RemoteAddr(), 170 To: dest, 171 Status: log.AccessAccepted, 172 Reason: "", 173 Email: request.User.Email, 174 }) 175 newError("tunnelling request to ", dest).WriteToLog(session.ExportIDToError(ctx)) 176 177 ctx, cancel := context.WithCancel(ctx) 178 timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) 179 180 ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) 181 link, err := dispatcher.Dispatch(ctx, dest) 182 if err != nil { 183 return err 184 } 185 186 responseDone := func() error { 187 defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) 188 189 bufferedWriter := buf.NewBufferedWriter(buf.NewWriter(conn)) 190 responseWriter, err := WriteTCPResponse(request, bufferedWriter) 191 if err != nil { 192 return newError("failed to write response").Base(err) 193 } 194 195 { 196 payload, err := link.Reader.ReadMultiBuffer() 197 if err != nil { 198 return err 199 } 200 if err := responseWriter.WriteMultiBuffer(payload); err != nil { 201 return err 202 } 203 } 204 205 if err := bufferedWriter.SetBuffered(false); err != nil { 206 return err 207 } 208 209 if err := buf.Copy(link.Reader, responseWriter, buf.UpdateActivity(timer)); err != nil { 210 return newError("failed to transport all TCP response").Base(err) 211 } 212 213 return nil 214 } 215 216 requestDone := func() error { 217 defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) 218 219 if err := buf.Copy(bodyReader, link.Writer, buf.UpdateActivity(timer)); err != nil { 220 return newError("failed to transport all TCP request").Base(err) 221 } 222 223 return nil 224 } 225 226 requestDoneAndCloseWriter := task.OnSuccess(requestDone, task.Close(link.Writer)) 227 if err := task.Run(ctx, requestDoneAndCloseWriter, responseDone); err != nil { 228 common.Interrupt(link.Reader) 229 common.Interrupt(link.Writer) 230 return newError("connection ends").Base(err) 231 } 232 233 return nil 234 } 235 236 func init() { 237 common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 238 return NewServer(ctx, config.(*ServerConfig)) 239 })) 240 }