예제 #1
0
파일: hub.go 프로젝트: v2ray/v2ray-core
func ListenUDP(address v2net.Address, port v2net.Port, option ListenOption) (*UDPHub, error) {
	if option.Concurrency < 1 {
		option.Concurrency = 1
	}
	udpConn, err := net.ListenUDP("udp", &net.UDPAddr{
		IP:   address.IP(),
		Port: int(port),
	})
	if err != nil {
		return nil, err
	}
	if option.ReceiveOriginalDest {
		fd, err := internal.GetSysFd(udpConn)
		if err != nil {
			log.Warning("UDP|Listener: Failed to get fd: ", err)
			return nil, err
		}
		err = SetOriginalDestOptions(fd)
		if err != nil {
			log.Warning("UDP|Listener: Failed to set socket options: ", err)
			return nil, err
		}
	}
	hub := &UDPHub{
		conn:   udpConn,
		queue:  NewUDPPayloadQueue(option),
		option: option,
		cancel: signal.NewCloseSignal(),
	}
	go hub.start()
	return hub, nil
}
예제 #2
0
파일: server.go 프로젝트: ylywyn/v2ray-core
func (s *Server) Process(ctx context.Context, network v2net.Network, conn internet.Connection) error {
	conn.SetReusable(false)

	timedReader := v2net.NewTimeOutReader(s.config.Timeout, conn)
	reader := bufio.OriginalReaderSize(timedReader, 2048)

	request, err := http.ReadRequest(reader)
	if err != nil {
		if errors.Cause(err) != io.EOF {
			log.Warning("HTTP: Failed to read http request: ", err)
		}
		return err
	}
	log.Info("HTTP: Request to Method [", request.Method, "] Host [", request.Host, "] with URL [", request.URL, "]")
	defaultPort := v2net.Port(80)
	if strings.ToLower(request.URL.Scheme) == "https" {
		defaultPort = v2net.Port(443)
	}
	host := request.Host
	if len(host) == 0 {
		host = request.URL.Host
	}
	dest, err := parseHost(host, defaultPort)
	if err != nil {
		log.Warning("HTTP: Malformed proxy host (", host, "): ", err)
		return err
	}
	log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "")
	ctx = proxy.ContextWithDestination(ctx, dest)
	if strings.ToUpper(request.Method) == "CONNECT" {
		return s.handleConnect(ctx, request, reader, conn)
	} else {
		return s.handlePlainHTTP(ctx, request, reader, conn)
	}
}
예제 #3
0
파일: hub.go 프로젝트: DZLZHCODE/v2ray-core
func ListenUDP(address v2net.Address, port v2net.Port, option ListenOption) (*UDPHub, error) {
	udpConn, err := net.ListenUDP("udp", &net.UDPAddr{
		IP:   address.IP(),
		Port: int(port),
	})
	if err != nil {
		return nil, err
	}
	if option.ReceiveOriginalDest {
		fd, err := internal.GetSysFd(udpConn)
		if err != nil {
			log.Warning("UDP|Listener: Failed to get fd: ", err)
			return nil, err
		}
		err = SetOriginalDestOptions(fd)
		if err != nil {
			log.Warning("UDP|Listener: Failed to set socket options: ", err)
			return nil, err
		}
	}
	hub := &UDPHub{
		conn:   udpConn,
		option: option,
	}
	go hub.start()
	return hub, nil
}
예제 #4
0
파일: router.go 프로젝트: v2ray/v2ray-core
func parseIP(s string) *router.CIDR {
	var addr, mask string
	i := strings.Index(s, "/")
	if i < 0 {
		addr = s
	} else {
		addr = s[:i]
		mask = s[i+1:]
	}
	ip := v2net.ParseAddress(addr)
	switch ip.Family() {
	case v2net.AddressFamilyIPv4:
		bits := uint32(32)
		if len(mask) > 0 {
			bits64, err := strconv.ParseUint(mask, 10, 32)
			if err != nil {
				return nil
			}
			bits = uint32(bits64)
		}
		if bits > 32 {
			log.Warning("Router: invalid network mask: ", bits)
			return nil
		}
		return &router.CIDR{
			Ip:     []byte(ip.IP()),
			Prefix: bits,
		}
	case v2net.AddressFamilyIPv6:
		bits := uint32(128)
		if len(mask) > 0 {
			bits64, err := strconv.ParseUint(mask, 10, 32)
			if err != nil {
				return nil
			}
			bits = uint32(bits64)
		}
		if bits > 128 {
			log.Warning("Router: invalid network mask: ", bits)
			return nil
		}
		return &router.CIDR{
			Ip:     []byte(ip.IP()),
			Prefix: bits,
		}
	default:
		log.Warning("Router: unsupported address: ", s)
		return nil
	}
}
예제 #5
0
func (v *VMessInboundHandler) generateCommand(ctx context.Context, request *protocol.RequestHeader) protocol.ResponseCommand {
	if v.detours != nil {
		tag := v.detours.To
		if v.inboundHandlerManager != nil {
			handler, err := v.inboundHandlerManager.GetHandler(ctx, tag)
			if err != nil {
				log.Warning("VMess|Inbound: Failed to get detour handler: ", tag, err)
				return nil
			}
			proxyHandler, port, availableMin := handler.GetRandomInboundProxy()
			inboundHandler, ok := proxyHandler.(*VMessInboundHandler)
			if ok {
				if availableMin > 255 {
					availableMin = 255
				}

				log.Info("VMessIn: Pick detour handler for port ", port, " for ", availableMin, " minutes.")
				user := inboundHandler.GetUser(request.User.Email)
				if user == nil {
					return nil
				}
				account, _ := user.GetTypedAccount()
				return &protocol.CommandSwitchAccount{
					Port:     port,
					ID:       account.(*vmess.InternalAccount).ID.UUID(),
					AlterIds: uint16(len(account.(*vmess.InternalAccount).AlterIDs)),
					Level:    user.Level,
					ValidMin: byte(availableMin),
				}
			}
		}
	}

	return nil
}
예제 #6
0
func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
	log.Info("WebSocket|Dailer: Creating connection to ", dest)
	if src == nil {
		src = v2net.AnyIP
	}
	networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
	if err != nil {
		return nil, err
	}
	wsSettings := networkSettings.(*Config)

	id := src.String() + "-" + dest.NetAddr()
	var conn *wsconn
	if dest.Network == v2net.Network_TCP && wsSettings.ConnectionReuse.IsEnabled() {
		connt := globalCache.Get(id)
		if connt != nil {
			conn = connt.(*wsconn)
		}
	}
	if conn == nil {
		var err error
		conn, err = wsDial(src, dest, options)
		if err != nil {
			log.Warning("WebSocket|Dialer: Dial failed: ", err)
			return nil, err
		}
	}
	return NewConnection(id, conn, globalCache, wsSettings), nil
}
예제 #7
0
func (this *DefaultDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, session *proxy.SessionInfo) ray.InboundRay {
	direct := ray.NewRay()
	dispatcher := this.ohm.GetDefaultHandler()
	destination := session.Destination

	if this.router != nil {
		if tag, err := this.router.TakeDetour(destination); err == nil {
			if handler := this.ohm.GetHandler(tag); handler != nil {
				log.Info("DefaultDispatcher: Taking detour [", tag, "] for [", destination, "].")
				dispatcher = handler
			} else {
				log.Warning("DefaultDispatcher: Nonexisting tag: ", tag)
			}
		} else {
			log.Info("DefaultDispatcher: Default route for ", destination)
		}
	}

	if meta.AllowPassiveConnection {
		go dispatcher.Dispatch(destination, alloc.NewLocalBuffer(32).Clear(), direct)
	} else {
		go this.FilterPacketAndDispatch(destination, direct, dispatcher)
	}

	return direct
}
예제 #8
0
// Start starts the Point server, and return any error during the process.
// In the case of any errors, the state of the server is unpredicatable.
func (this *Point) Start() error {
	if this.port <= 0 {
		log.Error("Point: Invalid port ", this.port)
		return common.ErrBadConfiguration
	}

	err := retry.Timed(100 /* times */, 100 /* ms */).On(func() error {
		err := this.ich.Start()
		if err != nil {
			return err
		}
		log.Warning("Point: started on port ", this.port)
		return nil
	})
	if err != nil {
		return err
	}

	for _, detourHandler := range this.idh {
		err := detourHandler.Start()
		if err != nil {
			return err
		}
	}

	return nil
}
예제 #9
0
파일: tcp_hub.go 프로젝트: v2ray/v2ray-core
func ListenTCP(address v2net.Address, port v2net.Port, callback ConnectionHandler, settings *StreamConfig) (*TCPHub, error) {
	var listener Listener
	var err error
	options := ListenOptions{
		Stream: settings,
	}
	switch settings.Network {
	case v2net.Network_TCP:
		listener, err = TCPListenFunc(address, port, options)
	case v2net.Network_KCP:
		listener, err = KCPListenFunc(address, port, options)
	case v2net.Network_WebSocket:
		listener, err = WSListenFunc(address, port, options)
	case v2net.Network_RawTCP:
		listener, err = RawTCPListenFunc(address, port, options)
	default:
		log.Error("Internet|Listener: Unknown stream type: ", settings.Network)
		err = ErrUnsupportedStreamType
	}

	if err != nil {
		log.Warning("Internet|Listener: Failed to listen on ", address, ":", port)
		return nil, err
	}

	hub := &TCPHub{
		listener:     listener,
		connCallback: callback,
	}

	go hub.start()
	return hub, nil
}
예제 #10
0
파일: server.go 프로젝트: v2ray/v2ray-core
func (v *Server) handleConnection(connection internet.Connection) {
	defer connection.Close()

	timedReader := v2net.NewTimeOutReader(v.config.Timeout, connection)
	reader := bufio.NewReader(timedReader)
	defer reader.Release()

	writer := bufio.NewWriter(connection)
	defer writer.Release()

	auth, auth4, err := protocol.ReadAuthentication(reader)
	if err != nil && errors.Cause(err) != protocol.Socks4Downgrade {
		if errors.Cause(err) != io.EOF {
			log.Warning("Socks: failed to read authentication: ", err)
		}
		return
	}

	clientAddr := v2net.DestinationFromAddr(connection.RemoteAddr())
	if err != nil && err == protocol.Socks4Downgrade {
		v.handleSocks4(clientAddr, reader, writer, auth4)
	} else {
		v.handleSocks5(clientAddr, reader, writer, auth)
	}
}
예제 #11
0
파일: server.go 프로젝트: v2ray/v2ray-core
func (v *Server) handleSocks4(clientAddr v2net.Destination, reader *bufio.BufferedReader, writer *bufio.BufferedWriter, auth protocol.Socks4AuthenticationRequest) error {
	result := protocol.Socks4RequestGranted
	if auth.Command == protocol.CmdBind {
		result = protocol.Socks4RequestRejected
	}
	socks4Response := protocol.NewSocks4AuthenticationResponse(result, auth.Port, auth.IP[:])

	socks4Response.Write(writer)

	if result == protocol.Socks4RequestRejected {
		log.Warning("Socks: Unsupported socks 4 command ", auth.Command)
		log.Access(clientAddr, "", log.AccessRejected, ErrUnsupportedSocksCommand)
		return ErrUnsupportedSocksCommand
	}

	reader.SetCached(false)
	writer.SetCached(false)

	dest := v2net.TCPDestination(v2net.IPAddress(auth.IP[:]), auth.Port)
	session := &proxy.SessionInfo{
		Source:      clientAddr,
		Destination: dest,
		Inbound:     v.meta,
	}
	log.Access(clientAddr, dest, log.AccessAccepted, "")
	v.transport(reader, writer, session)
	return nil
}
예제 #12
0
func (v *VMessOutboundHandler) handleResponse(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, dest v2net.Destination, output buf.Writer, finish *sync.Mutex) {
	defer finish.Unlock()

	reader := bufio.NewReader(conn)
	defer reader.Release()

	header, err := session.DecodeResponseHeader(reader)
	if err != nil {
		conn.SetReusable(false)
		log.Warning("VMess|Outbound: Failed to read response from ", request.Destination(), ": ", err)
		return
	}
	v.handleCommand(dest, header.Command)

	conn.SetReusable(header.Option.Has(protocol.ResponseOptionConnectionReuse))

	reader.SetCached(false)
	bodyReader := session.DecodeResponseBody(request, reader)
	defer bodyReader.Release()

	if err := buf.PipeUntilEOF(bodyReader, output); err != nil {
		conn.SetReusable(false)
	}

	return
}
예제 #13
0
func (h *Handler) Dial(ctx context.Context, dest v2net.Destination) (internet.Connection, error) {
	if h.senderSettings != nil {
		if h.senderSettings.ProxySettings.HasTag() {
			tag := h.senderSettings.ProxySettings.Tag
			handler := h.outboundManager.GetHandler(tag)
			if handler != nil {
				log.Info("Proxyman|OutboundHandler: Proxying to ", tag)
				ctx = proxy.ContextWithDestination(ctx, dest)
				stream := ray.NewRay(ctx)
				go handler.Dispatch(ctx, stream)
				return NewConnection(stream), nil
			}

			log.Warning("Proxyman|OutboundHandler: Failed to get outbound handler with tag: ", tag)
		}

		if h.senderSettings.Via != nil {
			ctx = internet.ContextWithDialerSource(ctx, h.senderSettings.Via.AsAddress())
		}
		if h.senderSettings != nil {
			ctx = internet.ContextWithStreamSettings(ctx, h.senderSettings.StreamSettings)
		}
	}

	return internet.Dial(ctx, dest)
}
예제 #14
0
파일: default.go 프로젝트: v2ray/v2ray-core
func (v *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
	direct := ray.NewRay()
	dispatcher := v.ohm.GetDefaultHandler()
	destination := session.Destination

	if v.router != nil {
		if tag, err := v.router.TakeDetour(session); err == nil {
			if handler := v.ohm.GetHandler(tag); handler != nil {
				log.Info("DefaultDispatcher: Taking detour [", tag, "] for [", destination, "].")
				dispatcher = handler
			} else {
				log.Warning("DefaultDispatcher: Nonexisting tag: ", tag)
			}
		} else {
			log.Info("DefaultDispatcher: Default route for ", destination)
		}
	}

	if session.Inbound != nil && session.Inbound.AllowPassiveConnection {
		go dispatcher.Dispatch(destination, buf.NewLocal(32), direct)
	} else {
		go v.FilterPacketAndDispatch(destination, direct, dispatcher)
	}

	return direct
}
예제 #15
0
func (this *Server) handlePlainHTTP(request *http.Request, session *proxy.SessionInfo, reader *bufio.Reader, writer io.Writer) {
	if len(request.URL.Host) <= 0 {
		response := this.GenerateResponse(400, "Bad Request")
		response.Write(writer)

		return
	}

	request.Host = request.URL.Host
	StripHopByHopHeaders(request)

	ray := this.packetDispatcher.DispatchToOutbound(session)
	defer ray.InboundInput().Close()
	defer ray.InboundOutput().Release()

	var finish sync.WaitGroup
	finish.Add(1)
	go func() {
		defer finish.Done()
		requestWriter := v2io.NewBufferedWriter(v2io.NewChainWriter(ray.InboundInput()))
		err := request.Write(requestWriter)
		if err != nil {
			log.Warning("HTTP: Failed to write request: ", err)
			return
		}
		requestWriter.Flush()
	}()

	finish.Add(1)
	go func() {
		defer finish.Done()
		responseReader := bufio.NewReader(v2io.NewChanReader(ray.InboundOutput()))
		response, err := http.ReadResponse(responseReader, request)
		if err != nil {
			log.Warning("HTTP: Failed to read response: ", err)
			response = this.GenerateResponse(503, "Service Unavailable")
		}
		responseWriter := v2io.NewBufferedWriter(writer)
		err = response.Write(responseWriter)
		if err != nil {
			log.Warning("HTTP: Failed to write response: ", err)
			return
		}
		responseWriter.Flush()
	}()
	finish.Wait()
}
예제 #16
0
func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
	log.Info("Freedom: Opening connection to ", destination)

	defer payload.Release()
	defer ray.OutboundInput().Release()
	defer ray.OutboundOutput().Close()

	var conn internet.Connection
	if this.domainStrategy == Config_USE_IP && destination.Address.Family().IsDomain() {
		destination = this.ResolveIP(destination)
	}
	err := retry.ExponentialBackoff(5, 100).On(func() error {
		rawConn, err := internet.Dial(this.meta.Address, destination, this.meta.GetDialerOptions())
		if err != nil {
			return err
		}
		conn = rawConn
		return nil
	})
	if err != nil {
		log.Warning("Freedom: Failed to open connection to ", destination, ": ", err)
		return err
	}
	defer conn.Close()

	input := ray.OutboundInput()
	output := ray.OutboundOutput()

	if !payload.IsEmpty() {
		conn.Write(payload.Value)
	}

	go func() {
		v2writer := v2io.NewAdaptiveWriter(conn)
		defer v2writer.Release()

		v2io.Pipe(input, v2writer)
		if tcpConn, ok := conn.(*tcp.RawConnection); ok {
			tcpConn.CloseWrite()
		}
	}()

	var reader io.Reader = conn

	timeout := this.timeout
	if destination.Network == v2net.Network_UDP {
		timeout = 16
	}
	if timeout > 0 {
		reader = v2net.NewTimeOutReader(timeout /* seconds */, conn)
	}

	v2reader := v2io.NewAdaptiveReader(reader)
	v2io.Pipe(v2reader, output)
	v2reader.Release()
	ray.OutboundOutput().Close()

	return nil
}
예제 #17
0
func (this *Point) GetHandler(tag string) (proxy.InboundHandler, int) {
	handler, found := this.taggedInboundHandlers[tag]
	if !found {
		log.Warning("V2Ray: Unable to find an inbound handler with tag: ", tag)
		return nil, 0
	}
	return handler.GetConnectionHandler()
}
예제 #18
0
파일: config.go 프로젝트: v2ray/v2ray-core
func CreateNetworkConfig(network v2net.Network) (interface{}, error) {
	creator, ok := globalNetworkConfigCreatorCache[network]
	if !ok {
		log.Warning("Internet: Network config creator not found: ", network)
		return nil, ErrUnconfiguredNetwork
	}
	return creator(), nil
}
예제 #19
0
파일: v2ray.go 프로젝트: ylywyn/v2ray-core
// Start starts the Point server, and return any error during the process.
// In the case of any errors, the state of the server is unpredicatable.
func (v *Point) Start() error {
	ihm := proxyman.InboundHandlerManagerFromSpace(v.space)
	if err := ihm.Start(); err != nil {
		return err
	}
	log.Warning("V2Ray started.")

	return nil
}
예제 #20
0
func ReadAuthentication(reader io.Reader) (auth Socks5AuthenticationRequest, auth4 Socks4AuthenticationRequest, err error) {
	buffer := make([]byte, 256)

	nBytes, err := reader.Read(buffer)
	if err != nil {
		return
	}
	if nBytes < 2 {
		log.Warning("Socks: expected 2 bytes read, but only ", nBytes, " bytes read")
		err = transport.ErrCorruptedPacket
		return
	}

	if buffer[0] == socks4Version {
		auth4.Version = buffer[0]
		auth4.Command = buffer[1]
		auth4.Port = v2net.PortFromBytes(buffer[2:4])
		copy(auth4.IP[:], buffer[4:8])
		err = Socks4Downgrade
		return
	}

	auth.version = buffer[0]
	if auth.version != socksVersion {
		log.Warning("Socks: Unknown protocol version ", auth.version)
		err = proxy.ErrInvalidProtocolVersion
		return
	}

	auth.nMethods = buffer[1]
	if auth.nMethods <= 0 {
		log.Warning("Socks: Zero length of authentication methods")
		err = proxy.ErrInvalidAuthentication
		return
	}

	if nBytes-2 != int(auth.nMethods) {
		log.Warning("Socks: Unmatching number of auth methods, expecting ", auth.nMethods, ", but got ", nBytes)
		err = proxy.ErrInvalidAuthentication
		return
	}
	copy(auth.authMethods[:], buffer[2:nBytes])
	return
}
예제 #21
0
파일: wsconn.go 프로젝트: ylywyn/v2ray-core
func (ws *wsconn) getNewReadBuffer() error {
	_, r, err := ws.wsc.NextReader()
	if err != nil {
		log.Warning("WS transport: ws connection NewFrameReader return ", err)
		ws.connClosing = true
		ws.Close()
		return err
	}
	ws.readBuffer = bufio.NewReader(r)
	return nil
}
예제 #22
0
파일: server.go 프로젝트: ylywyn/v2ray-core
func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, reader io.Reader, writer io.Writer) error {
	if len(request.URL.Host) <= 0 {
		response := generateResponse(400, "Bad Request")
		return response.Write(writer)
	}

	request.Host = request.URL.Host
	StripHopByHopHeaders(request)

	ray := s.packetDispatcher.DispatchToOutbound(ctx)
	input := ray.InboundInput()
	output := ray.InboundOutput()

	requestDone := signal.ExecuteAsync(func() error {
		defer input.Close()

		requestWriter := bufio.NewWriter(buf.NewBytesWriter(ray.InboundInput()))
		err := request.Write(requestWriter)
		if err != nil {
			return err
		}
		if err := requestWriter.Flush(); err != nil {
			return err
		}
		return nil
	})

	responseDone := signal.ExecuteAsync(func() error {
		responseReader := bufio.OriginalReader(buf.NewBytesReader(ray.InboundOutput()))
		response, err := http.ReadResponse(responseReader, request)
		if err != nil {
			log.Warning("HTTP: Failed to read response: ", err)
			response = generateResponse(503, "Service Unavailable")
		}
		responseWriter := bufio.NewWriter(writer)
		if err := response.Write(responseWriter); err != nil {
			return err
		}

		if err := responseWriter.Flush(); err != nil {
			return err
		}
		return nil
	})

	if err := signal.ErrorOrFinish2(requestDone, responseDone); err != nil {
		log.Info("HTTP|Server: Connecton ending with ", err)
		input.CloseError()
		output.CloseError()
		return err
	}

	return nil
}
예제 #23
0
// Start starts the Point server, and return any error during the process.
// In the case of any errors, the state of the server is unpredicatable.
func (this *Point) Start() error {
	for _, inbound := range this.inboundHandlers {
		err := inbound.Start()
		if err != nil {
			return err
		}
	}
	log.Warning("V2Ray started.")

	return nil
}
예제 #24
0
파일: config.go 프로젝트: ylywyn/v2ray-core
func (v *Config) BuildCertificates() []tls.Certificate {
	certs := make([]tls.Certificate, 0, len(v.Certificate))
	for _, entry := range v.Certificate {
		keyPair, err := tls.X509KeyPair(entry.Certificate, entry.Key)
		if err != nil {
			log.Warning("TLS: ignoring invalid X509 key pair: ", err)
			continue
		}
		certs = append(certs, keyPair)
	}
	return certs
}
예제 #25
0
func (this *Config) GetInternalHosts() map[string]net.IP {
	hosts := make(map[string]net.IP)
	for domain, ipOrDomain := range this.GetHosts() {
		address := ipOrDomain.AsAddress()
		if address.Family().IsDomain() {
			log.Warning("DNS: Ignoring domain address in static hosts: ", address.Domain())
			continue
		}
		hosts[domain] = address.IP()
	}
	return hosts
}
예제 #26
0
func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
	buffer := alloc.NewSmallBuffer()
	defer buffer.Release()

	_, err = io.ReadFull(reader, buffer.Value[:4])
	if err != nil {
		return
	}

	request = &Socks5Request{
		Version: buffer.Value[0],
		Command: buffer.Value[1],
		// buffer[2] is a reserved field
		AddrType: buffer.Value[3],
	}
	switch request.AddrType {
	case AddrTypeIPv4:
		_, err = io.ReadFull(reader, request.IPv4[:])
		if err != nil {
			return
		}
	case AddrTypeDomain:
		_, err = io.ReadFull(reader, buffer.Value[0:1])
		if err != nil {
			return
		}
		domainLength := buffer.Value[0]
		_, err = io.ReadFull(reader, buffer.Value[:domainLength])
		if err != nil {
			return
		}

		request.Domain = string(append([]byte(nil), buffer.Value[:domainLength]...))
	case AddrTypeIPv6:
		_, err = io.ReadFull(reader, request.IPv6[:])
		if err != nil {
			return
		}
	default:
		log.Warning("Socks: Unexpected address type ", request.AddrType)
		err = transport.ErrCorruptedPacket
		return
	}

	_, err = io.ReadFull(reader, buffer.Value[:2])
	if err != nil {
		return
	}

	request.Port = v2net.PortFromBytes(buffer.Value[:2])
	return
}
예제 #27
0
파일: proxy.go 프로젝트: v2ray/v2ray-core
func (v *OutboundProxy) Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
	handler := v.outboundManager.GetHandler(options.Proxy.Tag)
	if handler == nil {
		log.Warning("Proxy: Failed to get outbound handler with tag: ", options.Proxy.Tag)
		return internet.Dial(src, dest, internet.DialerOptions{
			Stream: options.Stream,
		})
	}
	log.Info("Proxy: Dialing to ", dest)
	stream := ray.NewRay()
	go handler.Dispatch(dest, nil, stream)
	return NewProxyConnection(src, dest, stream), nil
}
예제 #28
0
파일: server.go 프로젝트: ylywyn/v2ray-core
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
}
예제 #29
0
func (this *Server) handleConnection(conn internet.Connection) {
	defer conn.Close()
	timedReader := v2net.NewTimeOutReader(this.config.Timeout, conn)
	reader := bufio.NewReaderSize(timedReader, 2048)

	request, err := http.ReadRequest(reader)
	if err != nil {
		if err != io.EOF {
			log.Warning("HTTP: Failed to read http request: ", err)
		}
		return
	}
	log.Info("HTTP: Request to Method [", request.Method, "] Host [", request.Host, "] with URL [", request.URL, "]")
	defaultPort := v2net.Port(80)
	if strings.ToLower(request.URL.Scheme) == "https" {
		defaultPort = v2net.Port(443)
	}
	host := request.Host
	if len(host) == 0 {
		host = request.URL.Host
	}
	dest, err := parseHost(host, defaultPort)
	if err != nil {
		log.Warning("HTTP: Malformed proxy host (", host, "): ", err)
		return
	}
	log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "")
	session := &proxy.SessionInfo{
		Source:      v2net.DestinationFromAddr(conn.RemoteAddr()),
		Destination: dest,
		Inbound:     this.meta,
	}
	if strings.ToUpper(request.Method) == "CONNECT" {
		this.handleConnect(request, session, reader, conn)
	} else {
		this.handlePlainHTTP(request, session, reader, conn)
	}
}
예제 #30
0
파일: udp.go 프로젝트: DZLZHCODE/v2ray-core
func ReadUDPRequest(packet []byte) (*Socks5UDPRequest, error) {
	if len(packet) < 5 {
		return nil, transport.ErrCorruptedPacket
	}
	request := new(Socks5UDPRequest)

	// packet[0] and packet[1] are reserved
	request.Fragment = packet[2]

	addrType := packet[3]
	var dataBegin int

	switch addrType {
	case AddrTypeIPv4:
		if len(packet) < 10 {
			return nil, transport.ErrCorruptedPacket
		}
		ip := packet[4:8]
		request.Port = v2net.PortFromBytes(packet[8:10])
		request.Address = v2net.IPAddress(ip)
		dataBegin = 10
	case AddrTypeIPv6:
		if len(packet) < 22 {
			return nil, transport.ErrCorruptedPacket
		}
		ip := packet[4:20]
		request.Port = v2net.PortFromBytes(packet[20:22])
		request.Address = v2net.IPAddress(ip)
		dataBegin = 22
	case AddrTypeDomain:
		domainLength := int(packet[4])
		if len(packet) < 5+domainLength+2 {
			return nil, transport.ErrCorruptedPacket
		}
		domain := string(packet[5 : 5+domainLength])
		request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2])
		request.Address = v2net.ParseAddress(domain)
		dataBegin = 5 + domainLength + 2
	default:
		log.Warning("Unknown address type ", addrType)
		return nil, ErrorUnknownAddressType
	}

	if len(packet) > dataBegin {
		request.Data = alloc.NewBuffer().Clear().Append(packet[dataBegin:])
	}

	return request, nil
}