func (v *IPv4Matcher) Apply(ctx context.Context) bool { ips := make([]net.IP, 0, 4) if resolveIPs, ok := proxy.ResolvedIPsFromContext(ctx); ok { for _, rip := range resolveIPs { if !rip.Family().IsIPv4() { continue } ips = append(ips, rip.IP()) } } var dest v2net.Destination if v.onSource { dest = proxy.SourceFromContext(ctx) } else { dest = proxy.DestinationFromContext(ctx) } if dest.IsValid() && dest.Address.Family().IsIPv4() { ips = append(ips, dest.Address.IP()) } for _, ip := range ips { if v.ipv4net.Contains(ip) { return true } } return false }
func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection) error { source := proxy.SourceFromContext(ctx) reader := buf.NewReader(conn) for { payload, err := reader.Read() if err != nil { break } request, data, err := DecodeUDPPacket(v.user, payload) if err != nil { log.Info("Shadowsocks|Server: Skipping invalid UDP packet from: ", source, ": ", err) log.Access(source, "", log.AccessRejected, err) payload.Release() continue } if request.Option.Has(RequestOptionOneTimeAuth) && v.account.OneTimeAuth == Account_Disabled { log.Info("Shadowsocks|Server: Client payload enables OTA but server doesn't allow it.") payload.Release() continue } if !request.Option.Has(RequestOptionOneTimeAuth) && v.account.OneTimeAuth == Account_Enabled { log.Info("Shadowsocks|Server: Client payload disables OTA but server forces it.") payload.Release() continue } dest := request.Destination() log.Access(source, dest, log.AccessAccepted, "") log.Info("Shadowsocks|Server: Tunnelling request to ", dest) ctx = protocol.ContextWithUser(ctx, request.User) v.udpServer.Dispatch(ctx, dest, data, func(payload *buf.Buffer) { defer payload.Release() data, err := EncodeUDPPacket(request, payload) if err != nil { log.Warning("Shadowsocks|Server: Failed to encode UDP packet: ", err) return } defer data.Release() conn.Write(data.Bytes()) }) } return nil }
func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection) error { source := proxy.SourceFromContext(ctx) log.Info("Socks|Server: Client UDP connection from ", source) reader := buf.NewReader(conn) for { payload, err := reader.Read() if err != nil { return err } request, data, err := DecodeUDPPacket(payload.Bytes()) if err != nil { log.Info("Socks|Server: Failed to parse UDP request: ", err) continue } if len(data) == 0 { continue } log.Info("Socks: Send packet to ", request.Destination(), " with ", len(data), " bytes") log.Access(source, request.Destination, log.AccessAccepted, "") dataBuf := buf.NewSmall() dataBuf.Append(data) v.udpServer.Dispatch(ctx, request.Destination(), dataBuf, func(payload *buf.Buffer) { defer payload.Release() log.Info("Socks|Server: Writing back UDP response with ", payload.Len(), " bytes") udpMessage := EncodeUDPPacket(request, payload.Bytes()) defer udpMessage.Release() conn.Write(udpMessage.Bytes()) }) } }
func (s *Server) processTCP(ctx context.Context, conn internet.Connection) error { conn.SetReusable(false) timedReader := net.NewTimeOutReader(16 /* seconds, for handshake */, conn) reader := bufio.NewReader(timedReader) inboundDest := proxy.InboundDestinationFromContext(ctx) session := &ServerSession{ config: s.config, port: inboundDest.Port, } source := proxy.SourceFromContext(ctx) request, err := session.Handshake(reader, conn) if err != nil { log.Access(source, "", log.AccessRejected, err) log.Info("Socks|Server: Failed to read request: ", err) return err } if request.Command == protocol.RequestCommandTCP { dest := request.Destination() log.Info("Socks|Server: TCP Connect request to ", dest) log.Access(source, dest, log.AccessAccepted, "") timedReader.SetTimeOut(s.config.Timeout) ctx = proxy.ContextWithDestination(ctx, dest) return s.transport(ctx, reader, conn) } if request.Command == protocol.RequestCommandUDP { return s.handleUDP() } return nil }