Browse Source

add implementation for transport environment and network env

Shelikhoo 3 years ago
parent
commit
69ab87239a

+ 2 - 0
app/proxyman/inbound/inbound.go

@@ -16,6 +16,7 @@ import (
 
 // Manager is to manage all inbound handlers.
 type Manager struct {
+	ctx             context.Context
 	access          sync.RWMutex
 	untaggedHandler []inbound.Handler
 	taggedHandlers  map[string]inbound.Handler
@@ -25,6 +26,7 @@ type Manager struct {
 // New returns a new Manager for inbound handlers.
 func New(ctx context.Context, config *proxyman.InboundConfig) (*Manager, error) {
 	m := &Manager{
+		ctx:            ctx,
 		taggedHandlers: make(map[string]inbound.Handler),
 	}
 	return m, nil

+ 20 - 0
app/proxyman/inbound/worker.go

@@ -9,6 +9,8 @@ import (
 	"github.com/v2fly/v2ray-core/v5/app/proxyman"
 	"github.com/v2fly/v2ray-core/v5/common"
 	"github.com/v2fly/v2ray-core/v5/common/buf"
+	"github.com/v2fly/v2ray-core/v5/common/environment"
+	"github.com/v2fly/v2ray-core/v5/common/environment/envctx"
 	"github.com/v2fly/v2ray-core/v5/common/net"
 	"github.com/v2fly/v2ray-core/v5/common/serial"
 	"github.com/v2fly/v2ray-core/v5/common/session"
@@ -112,6 +114,12 @@ func (w *tcpWorker) Proxy() proxy.Inbound {
 
 func (w *tcpWorker) Start() error {
 	ctx := context.Background()
+	proxyEnvironment := envctx.EnvironmentFromContext(w.ctx).(environment.ProxyEnvironment)
+	transportEnvironment, err := proxyEnvironment.NarrowScopeToTransport("transport")
+	if err != nil {
+		return newError("unable to narrow environment to transport").Base(err)
+	}
+	ctx = envctx.ContextWithEnvironment(ctx, transportEnvironment)
 	hub, err := internet.ListenTCP(ctx, w.address, w.port, w.stream, func(conn internet.Connection) {
 		go w.callback(conn)
 	})
@@ -371,6 +379,12 @@ func (w *udpWorker) clean() error {
 func (w *udpWorker) Start() error {
 	w.activeConn = make(map[connID]*udpConn, 16)
 	ctx := context.Background()
+	proxyEnvironment := envctx.EnvironmentFromContext(w.ctx).(environment.ProxyEnvironment)
+	transportEnvironment, err := proxyEnvironment.NarrowScopeToTransport("transport")
+	if err != nil {
+		return newError("unable to narrow environment to transport").Base(err)
+	}
+	ctx = envctx.ContextWithEnvironment(ctx, transportEnvironment)
 	h, err := udp.ListenUDP(ctx, w.address, w.port, w.stream, udp.HubCapacity(256))
 	if err != nil {
 		return err
@@ -480,6 +494,12 @@ func (w *dsWorker) Port() net.Port {
 
 func (w *dsWorker) Start() error {
 	ctx := context.Background()
+	proxyEnvironment := envctx.EnvironmentFromContext(w.ctx).(environment.ProxyEnvironment)
+	transportEnvironment, err := proxyEnvironment.NarrowScopeToTransport("transport")
+	if err != nil {
+		return newError("unable to narrow environment to transport").Base(err)
+	}
+	ctx = envctx.ContextWithEnvironment(ctx, transportEnvironment)
 	hub, err := internet.ListenUnix(ctx, w.address, w.stream, func(conn internet.Connection) {
 		go w.callback(conn)
 	})

+ 10 - 0
app/proxyman/outbound/handler.go

@@ -7,6 +7,8 @@ import (
 	"github.com/v2fly/v2ray-core/v5/app/proxyman"
 	"github.com/v2fly/v2ray-core/v5/common"
 	"github.com/v2fly/v2ray-core/v5/common/dice"
+	"github.com/v2fly/v2ray-core/v5/common/environment"
+	"github.com/v2fly/v2ray-core/v5/common/environment/envctx"
 	"github.com/v2fly/v2ray-core/v5/common/mux"
 	"github.com/v2fly/v2ray-core/v5/common/net"
 	"github.com/v2fly/v2ray-core/v5/common/net/packetaddr"
@@ -50,6 +52,7 @@ func getStatCounter(v *core.Instance, tag string) (stats.Counter, stats.Counter)
 
 // Handler is an implements of outbound.Handler.
 type Handler struct {
+	ctx             context.Context
 	tag             string
 	senderSettings  *proxyman.SenderConfig
 	streamSettings  *internet.MemoryStreamConfig
@@ -66,6 +69,7 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou
 	v := core.MustFromContext(ctx)
 	uplinkCounter, downlinkCounter := getStatCounter(v, config.Tag)
 	h := &Handler{
+		ctx:             ctx,
 		tag:             config.Tag,
 		outboundManager: v.GetFeature(outbound.ManagerType()).(outbound.Manager),
 		uplinkCounter:   uplinkCounter,
@@ -251,6 +255,12 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Conn
 		return h.getStatCouterConnection(conn), nil
 	}
 
+	proxyEnvironment := envctx.EnvironmentFromContext(h.ctx).(environment.ProxyEnvironment)
+	transportEnvironment, err := proxyEnvironment.NarrowScopeToTransport("transport")
+	if err != nil {
+		return nil, newError("unable to narrow environment to transport").Base(err)
+	}
+	ctx = envctx.ContextWithEnvironment(ctx, transportEnvironment)
 	conn, err := internet.Dial(ctx, dest, h.streamSettings)
 	return h.getStatCouterConnection(conn), err
 }

+ 14 - 0
app/proxyman/outbound/handler_test.go

@@ -5,6 +5,12 @@ import (
 	"testing"
 	_ "unsafe"
 
+	"github.com/v2fly/v2ray-core/v5/common/environment/systemnetworkimpl"
+
+	"github.com/v2fly/v2ray-core/v5/common/environment"
+	"github.com/v2fly/v2ray-core/v5/common/environment/envctx"
+	"github.com/v2fly/v2ray-core/v5/common/environment/transientstorageimpl"
+
 	"google.golang.org/protobuf/types/known/anypb"
 
 	core "github.com/v2fly/v2ray-core/v5"
@@ -43,6 +49,10 @@ func TestOutboundWithoutStatCounter(t *testing.T) {
 	v, _ := core.New(config)
 	v.AddFeature((outbound.Manager)(new(Manager)))
 	ctx := toContext(context.Background(), v)
+	defaultNetworkImpl := systemnetworkimpl.NewSystemNetworkDefault()
+	rootEnv := environment.NewRootEnvImpl(ctx, transientstorageimpl.NewScopedTransientStorageImpl(), defaultNetworkImpl.Dialer(), defaultNetworkImpl.Listener())
+	proxyEnvironment := rootEnv.ProxyEnvironment("o")
+	ctx = envctx.ContextWithEnvironment(ctx, proxyEnvironment)
 	h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{
 		Tag:           "tag",
 		ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
@@ -72,6 +82,10 @@ func TestOutboundWithStatCounter(t *testing.T) {
 	v, _ := core.New(config)
 	v.AddFeature((outbound.Manager)(new(Manager)))
 	ctx := toContext(context.Background(), v)
+	defaultNetworkImpl := systemnetworkimpl.NewSystemNetworkDefault()
+	rootEnv := environment.NewRootEnvImpl(ctx, transientstorageimpl.NewScopedTransientStorageImpl(), defaultNetworkImpl.Dialer(), defaultNetworkImpl.Listener())
+	proxyEnvironment := rootEnv.ProxyEnvironment("o")
+	ctx = envctx.ContextWithEnvironment(ctx, proxyEnvironment)
 	h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{
 		Tag:           "tag",
 		ProxySettings: serial.ToTypedMessage(&freedom.Config{}),

+ 23 - 2
common/environment/rootcap_impl.go

@@ -9,12 +9,21 @@ import (
 	"github.com/v2fly/v2ray-core/v5/transport/internet/tagged"
 )
 
-func NewRootEnvImpl(ctx context.Context, transientStorage storage.ScopedTransientStorage) RootEnvironment {
-	return &rootEnvImpl{transientStorage: transientStorage, ctx: ctx}
+func NewRootEnvImpl(ctx context.Context, transientStorage storage.ScopedTransientStorage,
+	systemDialer internet.SystemDialer, systemListener internet.SystemListener,
+) RootEnvironment {
+	return &rootEnvImpl{
+		transientStorage: transientStorage,
+		systemListener:   systemListener,
+		systemDialer:     systemDialer,
+		ctx:              ctx,
+	}
 }
 
 type rootEnvImpl struct {
 	transientStorage storage.ScopedTransientStorage
+	systemDialer     internet.SystemDialer
+	systemListener   internet.SystemListener
 
 	ctx context.Context
 }
@@ -30,6 +39,8 @@ func (r *rootEnvImpl) AppEnvironment(tag string) AppEnvironment {
 	}
 	return &appEnvImpl{
 		transientStorage: transientStorage,
+		systemListener:   r.systemListener,
+		systemDialer:     r.systemDialer,
 		ctx:              r.ctx,
 	}
 }
@@ -41,12 +52,16 @@ func (r *rootEnvImpl) ProxyEnvironment(tag string) ProxyEnvironment {
 	}
 	return &proxyEnvImpl{
 		transientStorage: transientStorage,
+		systemListener:   r.systemListener,
+		systemDialer:     r.systemDialer,
 		ctx:              r.ctx,
 	}
 }
 
 type appEnvImpl struct {
 	transientStorage storage.ScopedTransientStorage
+	systemDialer     internet.SystemDialer
+	systemListener   internet.SystemListener
 
 	ctx context.Context
 }
@@ -98,6 +113,8 @@ func (a *appEnvImpl) NarrowScope(key string) (AppEnvironment, error) {
 	}
 	return &appEnvImpl{
 		transientStorage: transientStorage,
+		systemDialer:     a.systemDialer,
+		systemListener:   a.systemListener,
 		ctx:              a.ctx,
 	}, nil
 }
@@ -108,6 +125,8 @@ func (a *appEnvImpl) doNotImpl() {
 
 type proxyEnvImpl struct {
 	transientStorage storage.ScopedTransientStorage
+	systemDialer     internet.SystemDialer
+	systemListener   internet.SystemListener
 
 	ctx context.Context
 }
@@ -156,6 +175,8 @@ func (p *proxyEnvImpl) doNotImpl() {
 
 type transportEnvImpl struct {
 	transientStorage storage.ScopedTransientStorage
+	systemDialer     internet.SystemDialer
+	systemListener   internet.SystemListener
 
 	ctx context.Context
 }

+ 84 - 0
common/environment/systemnetworkimpl/systemnetwork.go

@@ -0,0 +1,84 @@
+package systemnetworkimpl
+
+import (
+	"context"
+
+	"github.com/v2fly/v2ray-core/v5/common/environment"
+	"github.com/v2fly/v2ray-core/v5/common/net"
+	"github.com/v2fly/v2ray-core/v5/transport/internet"
+)
+
+func NewSystemNetworkImpl(listener internet.SystemListener, dialer internet.SystemDialer) environment.SystemNetworkCapabilitySet {
+	return &systemNetworkImpl{dialer: dialer, listener: listener}
+}
+
+type systemDefaultDialer struct{}
+
+func (s systemDefaultDialer) Listen(ctx context.Context, addr net.Addr, sockopt *internet.SocketConfig) (net.Listener, error) {
+	return internet.ListenSystem(ctx, addr, sockopt)
+}
+
+func (s systemDefaultDialer) ListenPacket(ctx context.Context, addr net.Addr, sockopt *internet.SocketConfig) (net.PacketConn, error) {
+	return internet.ListenSystemPacket(ctx, addr, sockopt)
+}
+
+func (s systemDefaultDialer) Dial(ctx context.Context, source net.Address, destination net.Destination, sockopt *internet.SocketConfig) (net.Conn, error) {
+	return internet.DialSystem(ctx, destination, sockopt)
+}
+
+func NewSystemNetworkDefault() environment.SystemNetworkCapabilitySet {
+	systemDefault := systemDefaultDialer{}
+	return &systemNetworkImpl{dialer: systemDefault, listener: systemDefault}
+}
+
+type systemNetworkImpl struct {
+	listener internet.SystemListener
+	dialer   internet.SystemDialer
+}
+
+func (s systemNetworkImpl) Dialer() internet.SystemDialer {
+	return s.dialer
+}
+
+func (s systemNetworkImpl) Listener() internet.SystemListener {
+	return s.listener
+}
+
+func NewSystemListenerWithDefaultOpt(listener internet.SystemListener, opt *internet.SocketConfig) internet.SystemListener {
+	return systemListenerWithDefaultOpt{SystemListener: listener, opt: opt}
+}
+
+type systemListenerWithDefaultOpt struct {
+	internet.SystemListener
+	opt *internet.SocketConfig
+}
+
+func (s systemListenerWithDefaultOpt) Listen(ctx context.Context, addr net.Addr, sockopt *internet.SocketConfig) (net.Listener, error) {
+	if sockopt == nil {
+		return s.Listen(ctx, addr, s.opt)
+	}
+	return s.Listen(ctx, addr, sockopt)
+}
+
+func (s systemListenerWithDefaultOpt) ListenPacket(ctx context.Context, addr net.Addr, sockopt *internet.SocketConfig) (net.PacketConn, error) {
+	if sockopt == nil {
+		return s.ListenPacket(ctx, addr, s.opt)
+	}
+	return s.ListenPacket(ctx, addr, sockopt)
+}
+
+func NewSystemDialerWithDefaultOpt(listener internet.SystemDialer, opt *internet.SocketConfig) internet.SystemDialer {
+	return systemDialerWithDefaultOpt{SystemDialer: listener, opt: opt}
+}
+
+type systemDialerWithDefaultOpt struct {
+	internet.SystemDialer
+	opt *internet.SocketConfig
+}
+
+func (s systemDialerWithDefaultOpt) Dial(ctx context.Context, source net.Address, destination net.Destination, sockopt *internet.SocketConfig) (net.Conn, error) {
+	if sockopt == nil {
+		return s.Dial(ctx, source, destination, s.opt)
+	}
+	return s.Dial(ctx, source, destination, sockopt)
+}

+ 4 - 2
v2ray.go

@@ -3,10 +3,11 @@ package core
 import (
 	"context"
 	"reflect"
-	"sync"
+	sync "sync"
 
 	"github.com/v2fly/v2ray-core/v5/common"
 	"github.com/v2fly/v2ray-core/v5/common/environment"
+	"github.com/v2fly/v2ray-core/v5/common/environment/systemnetworkimpl"
 	"github.com/v2fly/v2ray-core/v5/common/environment/transientstorageimpl"
 	"github.com/v2fly/v2ray-core/v5/common/serial"
 	"github.com/v2fly/v2ray-core/v5/features"
@@ -191,7 +192,8 @@ func initInstanceWithConfig(config *Config, server *Instance) (bool, error) {
 		return true, err
 	}
 
-	server.env = environment.NewRootEnvImpl(server.ctx, transientstorageimpl.NewScopedTransientStorageImpl())
+	defaultNetworkImpl := systemnetworkimpl.NewSystemNetworkDefault()
+	server.env = environment.NewRootEnvImpl(server.ctx, transientstorageimpl.NewScopedTransientStorageImpl(), defaultNetworkImpl.Dialer(), defaultNetworkImpl.Listener())
 
 	for _, appSettings := range config.App {
 		settings, err := serial.GetInstanceOf(appSettings)