Просмотр исходного кода

option to allow passive connection

v2ray 9 лет назад
Родитель
Сommit
bcd27ba36f

+ 2 - 1
app/dispatcher/dispatcher.go

@@ -3,6 +3,7 @@ package dispatcher
 import (
 	"github.com/v2ray/v2ray-core/app"
 	v2net "github.com/v2ray/v2ray-core/common/net"
+	"github.com/v2ray/v2ray-core/proxy"
 	"github.com/v2ray/v2ray-core/transport/ray"
 )
 
@@ -12,5 +13,5 @@ const (
 
 // PacketDispatcher dispatch a packet and possibly further network payload to its destination.
 type PacketDispatcher interface {
-	DispatchToOutbound(destination v2net.Destination) ray.InboundRay
+	DispatchToOutbound(meta *proxy.InboundHandlerMeta, destination v2net.Destination) ray.InboundRay
 }

+ 7 - 2
app/dispatcher/impl/default.go

@@ -4,6 +4,7 @@ import (
 	"github.com/v2ray/v2ray-core/app"
 	"github.com/v2ray/v2ray-core/app/proxyman"
 	"github.com/v2ray/v2ray-core/app/router"
+	"github.com/v2ray/v2ray-core/common/alloc"
 	"github.com/v2ray/v2ray-core/common/log"
 	v2net "github.com/v2ray/v2ray-core/common/net"
 	"github.com/v2ray/v2ray-core/proxy"
@@ -42,7 +43,7 @@ func (this *DefaultDispatcher) Release() {
 
 }
 
-func (this *DefaultDispatcher) DispatchToOutbound(destination v2net.Destination) ray.InboundRay {
+func (this *DefaultDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, destination v2net.Destination) ray.InboundRay {
 	direct := ray.NewRay()
 	dispatcher := this.ohm.GetDefaultHandler()
 
@@ -59,7 +60,11 @@ func (this *DefaultDispatcher) DispatchToOutbound(destination v2net.Destination)
 		}
 	}
 
-	go this.FilterPacketAndDispatch(destination, direct, dispatcher)
+	if meta.AllowPassiveConnection {
+		go dispatcher.Dispatch(destination, alloc.NewLocalBuffer(32).Clear(), direct)
+	} else {
+		go this.FilterPacketAndDispatch(destination, direct, dispatcher)
+	}
 
 	return direct
 }

+ 2 - 1
app/dispatcher/testing/dispatcher.go

@@ -2,6 +2,7 @@ package testing
 
 import (
 	v2net "github.com/v2ray/v2ray-core/common/net"
+	"github.com/v2ray/v2ray-core/proxy"
 	"github.com/v2ray/v2ray-core/transport/ray"
 )
 
@@ -29,7 +30,7 @@ func NewTestPacketDispatcher(handler func(destination v2net.Destination, traffic
 	}
 }
 
-func (this *TestPacketDispatcher) DispatchToOutbound(destination v2net.Destination) ray.InboundRay {
+func (this *TestPacketDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, destination v2net.Destination) ray.InboundRay {
 	traffic := ray.NewRay()
 	this.Destination <- destination
 	go this.Handler(destination, traffic)

+ 6 - 3
app/dns/nameserver.go

@@ -10,6 +10,7 @@ import (
 	"github.com/v2ray/v2ray-core/common/dice"
 	"github.com/v2ray/v2ray-core/common/log"
 	v2net "github.com/v2ray/v2ray-core/common/net"
+	"github.com/v2ray/v2ray-core/proxy"
 	"github.com/v2ray/v2ray-core/transport/internet/udp"
 
 	"github.com/miekg/dns"
@@ -49,9 +50,11 @@ type UDPNameServer struct {
 
 func NewUDPNameServer(address v2net.Destination, dispatcher dispatcher.PacketDispatcher) *UDPNameServer {
 	s := &UDPNameServer{
-		address:   address,
-		requests:  make(map[uint16]*PendingRequest),
-		udpServer: udp.NewUDPServer(dispatcher),
+		address:  address,
+		requests: make(map[uint16]*PendingRequest),
+		udpServer: udp.NewUDPServer(&proxy.InboundHandlerMeta{
+			AllowPassiveConnection: false,
+		}, dispatcher),
 	}
 	return s
 }

+ 2 - 2
proxy/dokodemo/dokodemo.go

@@ -89,7 +89,7 @@ func (this *DokodemoDoor) Start() error {
 }
 
 func (this *DokodemoDoor) ListenUDP() error {
-	this.udpServer = udp.NewUDPServer(this.packetDispatcher)
+	this.udpServer = udp.NewUDPServer(this.meta, this.packetDispatcher)
 	udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handleUDPPackets)
 	if err != nil {
 		log.Error("Dokodemo failed to listen on ", this.meta.Address, ":", this.meta.Port, ": ", err)
@@ -148,7 +148,7 @@ func (this *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
 	}
 	log.Info("Dokodemo: Handling request to ", dest)
 
-	ray := this.packetDispatcher.DispatchToOutbound(dest)
+	ray := this.packetDispatcher.DispatchToOutbound(this.meta, dest)
 	defer ray.InboundOutput().Release()
 
 	var inputFinish, outputFinish sync.Mutex

+ 2 - 2
proxy/http/server.go

@@ -140,7 +140,7 @@ func (this *Server) handleConnect(request *http.Request, destination v2net.Desti
 	}
 	response.Write(writer)
 
-	ray := this.packetDispatcher.DispatchToOutbound(destination)
+	ray := this.packetDispatcher.DispatchToOutbound(this.meta, destination)
 	this.transport(reader, writer, ray)
 }
 
@@ -220,7 +220,7 @@ func (this *Server) handlePlainHTTP(request *http.Request, dest v2net.Destinatio
 	request.Host = request.URL.Host
 	StripHopByHopHeaders(request)
 
-	ray := this.packetDispatcher.DispatchToOutbound(dest)
+	ray := this.packetDispatcher.DispatchToOutbound(this.meta, dest)
 	defer ray.InboundInput().Close()
 	defer ray.InboundOutput().Release()
 

+ 5 - 4
proxy/proxy.go

@@ -16,10 +16,11 @@ const (
 )
 
 type InboundHandlerMeta struct {
-	Tag            string
-	Address        v2net.Address
-	Port           v2net.Port
-	StreamSettings *internet.StreamSettings
+	Tag                    string
+	Address                v2net.Address
+	Port                   v2net.Port
+	AllowPassiveConnection bool
+	StreamSettings         *internet.StreamSettings
 }
 
 type OutboundHandlerMeta struct {

+ 2 - 2
proxy/shadowsocks/server.go

@@ -70,7 +70,7 @@ func (this *Server) Start() error {
 	this.tcpHub = tcpHub
 
 	if this.config.UDP {
-		this.udpServer = udp.NewUDPServer(this.packetDispatcher)
+		this.udpServer = udp.NewUDPServer(this.meta, this.packetDispatcher)
 		udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handlerUDPPayload)
 		if err != nil {
 			log.Error("Shadowsocks: Failed to listen UDP on ", this.meta.Address, ":", this.meta.Port, ": ", err)
@@ -204,7 +204,7 @@ func (this *Server) handleConnection(conn internet.Connection) {
 	log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "")
 	log.Info("Shadowsocks: Tunnelling request to ", dest)
 
-	ray := this.packetDispatcher.DispatchToOutbound(dest)
+	ray := this.packetDispatcher.DispatchToOutbound(this.meta, dest)
 	defer ray.InboundOutput().Release()
 
 	var writeFinish sync.Mutex

+ 1 - 1
proxy/socks/server.go

@@ -283,7 +283,7 @@ func (this *Server) handleSocks4(clientAddr string, reader *v2io.BufferedReader,
 }
 
 func (this *Server) transport(reader io.Reader, writer io.Writer, destination v2net.Destination) {
-	ray := this.packetDispatcher.DispatchToOutbound(destination)
+	ray := this.packetDispatcher.DispatchToOutbound(this.meta, destination)
 	input := ray.InboundInput()
 	output := ray.InboundOutput()
 

+ 1 - 1
proxy/socks/server_udp.go

@@ -9,7 +9,7 @@ import (
 )
 
 func (this *Server) listenUDP() error {
-	this.udpServer = udp.NewUDPServer(this.packetDispatcher)
+	this.udpServer = udp.NewUDPServer(this.meta, this.packetDispatcher)
 	udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handleUDPPayload)
 	if err != nil {
 		log.Error("Socks: Failed to listen on udp ", this.meta.Address, ":", this.meta.Port)

+ 4 - 1
proxy/testing/mocks/inboundhandler.go

@@ -7,6 +7,7 @@ import (
 	"github.com/v2ray/v2ray-core/app/dispatcher"
 	v2io "github.com/v2ray/v2ray-core/common/io"
 	v2net "github.com/v2ray/v2ray-core/common/net"
+	"github.com/v2ray/v2ray-core/proxy"
 )
 
 type InboundConnectionHandler struct {
@@ -30,7 +31,9 @@ func (this *InboundConnectionHandler) Close() {
 }
 
 func (this *InboundConnectionHandler) Communicate(destination v2net.Destination) error {
-	ray := this.PacketDispatcher.DispatchToOutbound(destination)
+	ray := this.PacketDispatcher.DispatchToOutbound(&proxy.InboundHandlerMeta{
+		AllowPassiveConnection: false,
+	}, destination)
 
 	input := ray.InboundInput()
 	output := ray.InboundOutput()

+ 1 - 1
proxy/vmess/inbound/inbound.go

@@ -163,7 +163,7 @@ func (this *VMessInboundHandler) HandleConnection(connection internet.Connection
 
 	connection.SetReusable(request.Option.Has(protocol.RequestOptionConnectionReuse))
 
-	ray := this.packetDispatcher.DispatchToOutbound(request.Destination())
+	ray := this.packetDispatcher.DispatchToOutbound(this.meta, request.Destination())
 	input := ray.InboundInput()
 	output := ray.InboundOutput()
 	defer input.Close()

+ 14 - 12
shell/point/config.go

@@ -10,11 +10,12 @@ import (
 )
 
 type InboundConnectionConfig struct {
-	Port           v2net.Port
-	ListenOn       v2net.Address
-	StreamSettings *internet.StreamSettings
-	Protocol       string
-	Settings       []byte
+	Port                   v2net.Port
+	ListenOn               v2net.Address
+	StreamSettings         *internet.StreamSettings
+	Protocol               string
+	Settings               []byte
+	AllowPassiveConnection bool
 }
 
 type OutboundConnectionConfig struct {
@@ -43,13 +44,14 @@ type InboundDetourAllocationConfig struct {
 }
 
 type InboundDetourConfig struct {
-	Protocol       string
-	PortRange      v2net.PortRange
-	ListenOn       v2net.Address
-	Tag            string
-	Allocation     *InboundDetourAllocationConfig
-	StreamSettings *internet.StreamSettings
-	Settings       []byte
+	Protocol               string
+	PortRange              v2net.PortRange
+	ListenOn               v2net.Address
+	Tag                    string
+	Allocation             *InboundDetourAllocationConfig
+	StreamSettings         *internet.StreamSettings
+	Settings               []byte
+	AllowPassiveConnection bool
 }
 
 type OutboundDetourConfig struct {

+ 4 - 0
shell/point/config_json.go

@@ -71,6 +71,7 @@ func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error {
 		Protocol      string                   `json:"protocol"`
 		StreamSetting *internet.StreamSettings `json:"streamSettings"`
 		Settings      json.RawMessage          `json:"settings"`
+		AllowPassive  bool                     `json:"allowPassive"`
 	}
 
 	jsonConfig := new(JsonConfig)
@@ -91,6 +92,7 @@ func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error {
 
 	this.Protocol = jsonConfig.Protocol
 	this.Settings = jsonConfig.Settings
+	this.AllowPassiveConnection = jsonConfig.AllowPassive
 	return nil
 }
 
@@ -186,6 +188,7 @@ func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error {
 		Tag           string                         `json:"tag"`
 		Allocation    *InboundDetourAllocationConfig `json:"allocate"`
 		StreamSetting *internet.StreamSettings       `json:"streamSettings"`
+		AllowPassive  bool                           `json:"allowPassive"`
 	}
 	jsonConfig := new(JsonInboundDetourConfig)
 	if err := json.Unmarshal(data, jsonConfig); err != nil {
@@ -216,6 +219,7 @@ func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error {
 	if jsonConfig.StreamSetting != nil {
 		this.StreamSettings = jsonConfig.StreamSetting
 	}
+	this.AllowPassiveConnection = jsonConfig.AllowPassive
 	return nil
 }
 

+ 6 - 4
shell/point/inbound_detour_always.go

@@ -26,10 +26,12 @@ func NewInboundDetourHandlerAlways(space app.Space, config *InboundDetourConfig)
 	for i := ports.From; i <= ports.To; i++ {
 		ichConfig := config.Settings
 		ich, err := proxyrepo.CreateInboundHandler(config.Protocol, space, ichConfig, &proxy.InboundHandlerMeta{
-			Address:        config.ListenOn,
-			Port:           i,
-			Tag:            config.Tag,
-			StreamSettings: config.StreamSettings})
+			Address:                config.ListenOn,
+			Port:                   i,
+			Tag:                    config.Tag,
+			StreamSettings:         config.StreamSettings,
+			AllowPassiveConnection: config.AllowPassiveConnection,
+		})
 		if err != nil {
 			log.Error("Failed to create inbound connection handler: ", err)
 			return nil, err

+ 6 - 4
shell/point/inbound_detour_dynamic.go

@@ -33,10 +33,12 @@ func NewInboundDetourHandlerDynamic(space app.Space, config *InboundDetourConfig
 
 	// To test configuration
 	ich, err := proxyrepo.CreateInboundHandler(config.Protocol, space, config.Settings, &proxy.InboundHandlerMeta{
-		Address:        config.ListenOn,
-		Port:           0,
-		Tag:            config.Tag,
-		StreamSettings: config.StreamSettings})
+		Address:                config.ListenOn,
+		Port:                   0,
+		Tag:                    config.Tag,
+		StreamSettings:         config.StreamSettings,
+		AllowPassiveConnection: config.AllowPassiveConnection,
+	})
 	if err != nil {
 		log.Error("Point: Failed to create inbound connection handler: ", err)
 		return nil, err

+ 6 - 4
shell/point/point.go

@@ -93,10 +93,12 @@ func NewPoint(pConfig *Config) (*Point, error) {
 	ichConfig := pConfig.InboundConfig.Settings
 	ich, err := proxyrepo.CreateInboundHandler(
 		pConfig.InboundConfig.Protocol, vpoint.space, ichConfig, &proxy.InboundHandlerMeta{
-			Tag:            "system.inbound",
-			Address:        pConfig.InboundConfig.ListenOn,
-			Port:           vpoint.port,
-			StreamSettings: pConfig.InboundConfig.StreamSettings})
+			Tag:                    "system.inbound",
+			Address:                pConfig.InboundConfig.ListenOn,
+			Port:                   vpoint.port,
+			StreamSettings:         pConfig.InboundConfig.StreamSettings,
+			AllowPassiveConnection: pConfig.InboundConfig.AllowPassiveConnection,
+		})
 	if err != nil {
 		log.Error("Failed to create inbound connection handler: ", err)
 		return nil, err

+ 5 - 2
transport/internet/udp/udp_server.go

@@ -8,6 +8,7 @@ import (
 	"github.com/v2ray/v2ray-core/common/alloc"
 	"github.com/v2ray/v2ray-core/common/log"
 	v2net "github.com/v2ray/v2ray-core/common/net"
+	"github.com/v2ray/v2ray-core/proxy"
 	"github.com/v2ray/v2ray-core/transport/ray"
 )
 
@@ -95,12 +96,14 @@ type UDPServer struct {
 	sync.RWMutex
 	conns            map[string]*TimedInboundRay
 	packetDispatcher dispatcher.PacketDispatcher
+	meta             *proxy.InboundHandlerMeta
 }
 
-func NewUDPServer(packetDispatcher dispatcher.PacketDispatcher) *UDPServer {
+func NewUDPServer(meta *proxy.InboundHandlerMeta, packetDispatcher dispatcher.PacketDispatcher) *UDPServer {
 	return &UDPServer{
 		conns:            make(map[string]*TimedInboundRay),
 		packetDispatcher: packetDispatcher,
+		meta:             meta,
 	}
 }
 
@@ -137,7 +140,7 @@ func (this *UDPServer) Dispatch(source v2net.Destination, destination v2net.Dest
 	}
 
 	log.Info("UDP Server: establishing new connection for ", destString)
-	inboundRay := this.packetDispatcher.DispatchToOutbound(destination)
+	inboundRay := this.packetDispatcher.DispatchToOutbound(this.meta, destination)
 	timedInboundRay := NewTimedInboundRay(destString, inboundRay, this)
 	outputStream := timedInboundRay.InboundInput()
 	if outputStream != nil {