Esempio n. 1
0
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
}
Esempio n. 2
0
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
}
Esempio n. 3
0
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())
		})
	}
}
Esempio n. 4
0
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
}