예제 #1
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)
	}
}
예제 #2
0
func TestSimpleRouter(t *testing.T) {
	assert := assert.On(t)

	config := &Config{
		Rule: []*RoutingRule{
			{
				Tag: "test",
				NetworkList: &net.NetworkList{
					Network: []net.Network{net.Network_TCP},
				},
			},
		},
	}

	space := app.NewSpace()
	ctx := app.ContextWithSpace(context.Background(), space)
	assert.Error(app.AddApplicationToSpace(ctx, new(dns.Config))).IsNil()
	assert.Error(app.AddApplicationToSpace(ctx, new(dispatcher.Config))).IsNil()
	assert.Error(app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig))).IsNil()
	assert.Error(app.AddApplicationToSpace(ctx, config)).IsNil()
	assert.Error(space.Initialize()).IsNil()

	r := FromSpace(space)

	ctx = proxy.ContextWithDestination(ctx, net.TCPDestination(net.DomainAddress("v2ray.com"), 80))
	tag, err := r.TakeDetour(ctx)
	assert.Error(err).IsNil()
	assert.String(tag).Equals("test")
}
예제 #3
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)
}
예제 #4
0
func TestChinaSitesJson(t *testing.T) {
	assert := assert.On(t)

	rule := ParseRule([]byte(`{
    "type": "chinasites",
    "outboundTag": "y"
  }`))
	assert.String(rule.Tag).Equals("y")
	cond, err := rule.BuildCondition()
	assert.Error(err).IsNil()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("v.qq.com"), 80)))).IsTrue()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("www.163.com"), 80)))).IsTrue()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("ngacn.cc"), 80)))).IsTrue()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("12306.cn"), 80)))).IsTrue()

	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("v2ray.com"), 80)))).IsFalse()
}
예제 #5
0
func TestChinaIPJson(t *testing.T) {
	assert := assert.On(t)

	rule := ParseRule([]byte(`{
    "type": "chinaip",
    "outboundTag": "x"
  }`))
	assert.String(rule.Tag).Equals("x")
	cond, err := rule.BuildCondition()
	assert.Error(err).IsNil()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("121.14.1.189"), 80)))).IsTrue()    // sina.com.cn
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("101.226.103.106"), 80)))).IsTrue() // qq.com
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("115.239.210.36"), 80)))).IsTrue()  // image.baidu.com
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("120.135.126.1"), 80)))).IsTrue()

	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("8.8.8.8"), 80)))).IsFalse()
}
예제 #6
0
func TestIPRule(t *testing.T) {
	assert := assert.On(t)

	rule := ParseRule([]byte(`{
    "type": "field",
    "ip": [
      "10.0.0.0/8",
      "192.0.0.0/24"
    ],
    "network": "tcp",
    "outboundTag": "direct"
  }`))
	assert.Pointer(rule).IsNotNil()
	cond, err := rule.BuildCondition()
	assert.Error(err).IsNil()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.DomainAddress("www.ooxx.com"), 80)))).IsFalse()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}), 80)))).IsTrue()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), 80)))).IsFalse()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.IPAddress([]byte{192, 0, 0, 1}), 80)))).IsTrue()
}
예제 #7
0
func TestDomainRule(t *testing.T) {
	assert := assert.On(t)

	rule := ParseRule([]byte(`{
    "type": "field",
    "domain": [
      "ooxx.com",
      "oxox.com",
      "regexp:\\.cn$"
    ],
    "network": "tcp",
    "outboundTag": "direct"
  }`))
	assert.Pointer(rule).IsNotNil()
	cond, err := rule.BuildCondition()
	assert.Error(err).IsNil()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("www.ooxx.com"), 80)))).IsTrue()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("www.aabb.com"), 80)))).IsFalse()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), 80)))).IsFalse()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("www.12306.cn"), 80)))).IsTrue()
	assert.Bool(cond.Apply(proxy.ContextWithDestination(context.Background(), v2net.TCPDestination(v2net.ParseAddress("www.acn.com"), 80)))).IsFalse()
}
예제 #8
0
func (v *Dispatcher) getInboundRay(ctx context.Context, dest v2net.Destination) (ray.InboundRay, bool) {
	destString := dest.String()
	v.Lock()
	defer v.Unlock()

	if entry, found := v.conns[destString]; found {
		return entry, true
	}

	log.Info("UDP|Server: establishing new connection for ", dest)
	ctx = proxy.ContextWithDestination(ctx, dest)
	return v.packetDispatcher.DispatchToOutbound(ctx), false
}
예제 #9
0
func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn internet.Connection) error {
	log.Debug("Dokodemo: processing connection from: ", conn.RemoteAddr())
	conn.SetReusable(false)
	ctx = proxy.ContextWithDestination(ctx, net.Destination{
		Network: network,
		Address: d.address,
		Port:    d.port,
	})
	inboundRay := d.packetDispatcher.DispatchToOutbound(ctx)

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

		timedReader := net.NewTimeOutReader(d.config.Timeout, conn)
		chunkReader := buf.NewReader(timedReader)

		if err := buf.PipeUntilEOF(chunkReader, inboundRay.InboundInput()); err != nil {
			log.Info("Dokodemo: Failed to transport request: ", err)
			return err
		}

		return nil
	})

	responseDone := signal.ExecuteAsync(func() error {
		v2writer := buf.NewWriter(conn)

		if err := buf.PipeUntilEOF(inboundRay.InboundOutput(), v2writer); err != nil {
			log.Info("Dokodemo: Failed to transport response: ", err)
			return err
		}
		return nil
	})

	if err := signal.ErrorOrFinish2(requestDone, responseDone); err != nil {
		inboundRay.InboundInput().CloseError()
		inboundRay.InboundOutput().CloseError()
		log.Info("Dokodemo: Connection ends with ", err)
		return err
	}

	return nil
}
예제 #10
0
파일: server.go 프로젝트: ylywyn/v2ray-core
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
}
예제 #11
0
func (v *VMessInboundHandler) Process(ctx context.Context, network net.Network, connection internet.Connection) error {
	connReader := net.NewTimeOutReader(8, connection)
	reader := bufio.NewReader(connReader)

	session := encoding.NewServerSession(v.clients)
	request, err := session.DecodeRequestHeader(reader)

	if err != nil {
		if errors.Cause(err) != io.EOF {
			log.Access(connection.RemoteAddr(), "", log.AccessRejected, err)
			log.Info("VMess|Inbound: Invalid request from ", connection.RemoteAddr(), ": ", err)
		}
		connection.SetReusable(false)
		return err
	}
	log.Access(connection.RemoteAddr(), request.Destination(), log.AccessAccepted, "")
	log.Info("VMess|Inbound: Received request for ", request.Destination())

	connection.SetReusable(request.Option.Has(protocol.RequestOptionConnectionReuse))

	ctx = proxy.ContextWithDestination(ctx, request.Destination())
	ctx = protocol.ContextWithUser(ctx, request.User)
	ray := v.packetDispatcher.DispatchToOutbound(ctx)

	input := ray.InboundInput()
	output := ray.InboundOutput()

	userSettings := request.User.GetSettings()
	connReader.SetTimeOut(userSettings.PayloadReadTimeout)
	reader.SetBuffered(false)

	requestDone := signal.ExecuteAsync(func() error {
		return transferRequest(session, request, reader, input)
	})

	writer := bufio.NewWriter(connection)
	response := &protocol.ResponseHeader{
		Command: v.generateCommand(ctx, request),
	}

	if connection.Reusable() {
		response.Option.Set(protocol.ResponseOptionConnectionReuse)
	}

	responseDone := signal.ExecuteAsync(func() error {
		return transferResponse(session, request, response, output, writer)
	})

	if err := signal.ErrorOrFinish2(requestDone, responseDone); err != nil {
		log.Info("VMess|Inbound: Connection ending with ", err)
		connection.SetReusable(false)
		input.CloseError()
		output.CloseError()
		return err
	}

	if err := writer.Flush(); err != nil {
		log.Info("VMess|Inbound: Failed to flush remain data: ", err)
		connection.SetReusable(false)
		return err
	}

	return nil
}
예제 #12
0
파일: server.go 프로젝트: ylywyn/v2ray-core
func (s *Server) handleConnection(ctx context.Context, conn internet.Connection) error {
	conn.SetReusable(false)

	timedReader := net.NewTimeOutReader(16, conn)
	bufferedReader := bufio.NewReader(timedReader)
	request, bodyReader, err := ReadTCPSession(s.user, bufferedReader)
	if err != nil {
		log.Access(conn.RemoteAddr(), "", log.AccessRejected, err)
		log.Info("Shadowsocks|Server: Failed to create request from: ", conn.RemoteAddr(), ": ", err)
		return err
	}

	bufferedReader.SetBuffered(false)

	userSettings := s.user.GetSettings()
	timedReader.SetTimeOut(userSettings.PayloadReadTimeout)

	dest := request.Destination()
	log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "")
	log.Info("Shadowsocks|Server: Tunnelling request to ", dest)

	ctx = proxy.ContextWithDestination(ctx, dest)
	ctx = protocol.ContextWithUser(ctx, request.User)
	ray := s.packetDispatcher.DispatchToOutbound(ctx)

	requestDone := signal.ExecuteAsync(func() error {
		bufferedWriter := bufio.NewWriter(conn)
		responseWriter, err := WriteTCPResponse(request, bufferedWriter)
		if err != nil {
			log.Warning("Shadowsocks|Server: Failed to write response: ", err)
			return err
		}

		payload, err := ray.InboundOutput().Read()
		if err != nil {
			return err
		}
		if err := responseWriter.Write(payload); err != nil {
			return err
		}
		payload.Release()

		if err := bufferedWriter.SetBuffered(false); err != nil {
			return err
		}

		if err := buf.PipeUntilEOF(ray.InboundOutput(), responseWriter); err != nil {
			log.Info("Shadowsocks|Server: Failed to transport all TCP response: ", err)
			return err
		}

		return nil
	})

	responseDone := signal.ExecuteAsync(func() error {
		defer ray.InboundInput().Close()

		if err := buf.PipeUntilEOF(bodyReader, ray.InboundInput()); err != nil {
			log.Info("Shadowsocks|Server: Failed to transport all TCP request: ", err)
			return err
		}
		return nil
	})

	if err := signal.ErrorOrFinish2(requestDone, responseDone); err != nil {
		log.Info("Shadowsocks|Server: Connection ends with ", err)
		ray.InboundInput().CloseError()
		ray.InboundOutput().CloseError()
		return err
	}

	return nil
}