From 3d07f686a5e90e6422e992f8f2a5f586d58831d4 Mon Sep 17 00:00:00 2001 From: Misaki Kasumi Date: Tue, 3 Sep 2024 01:56:20 +0800 Subject: [PATCH] apply control func to activated sockets --- transport/internet/socket_activation_other.go | 2 +- transport/internet/socket_activation_unix.go | 19 +++++++++- transport/internet/system_listener.go | 38 +++++++++++-------- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/transport/internet/socket_activation_other.go b/transport/internet/socket_activation_other.go index 920edff26..5bb93136d 100644 --- a/transport/internet/socket_activation_other.go +++ b/transport/internet/socket_activation_other.go @@ -8,6 +8,6 @@ import ( "github.com/v2fly/v2ray-core/v5/common/net" ) -func activateSocket(address string) (net.Listener, error) { +func activateSocket(address string, f func(network, address string, fd uintptr)) (net.Listener, error) { return nil, fmt.Errorf("socket activation is not supported on this platform") } diff --git a/transport/internet/socket_activation_unix.go b/transport/internet/socket_activation_unix.go index aca74f9fa..6dd92ab2f 100644 --- a/transport/internet/socket_activation_unix.go +++ b/transport/internet/socket_activation_unix.go @@ -13,7 +13,7 @@ import ( "github.com/v2fly/v2ray-core/v5/common/net" ) -func activateSocket(address string) (net.Listener, error) { +func activateSocket(address string, f func(network, address string, fd uintptr)) (net.Listener, error) { fd, err := strconv.Atoi(path.Base(address)) if err != nil { return nil, err @@ -41,7 +41,22 @@ func activateSocket(address string) (net.Listener, error) { return nil, fmt.Errorf("socket '%s' is not a stream socket", address) } - file := os.NewFile(uintptr(fd), address) + ufd := uintptr(fd) + + sa, err := syscall.Getsockname(fd) + if err != nil { + return nil, err + } + switch sa := sa.(type) { + case *syscall.SockaddrInet4: + addr := net.TCPAddr{IP: sa.Addr[:], Port: sa.Port, Zone: ""} + f("tcp4", addr.String(), ufd) + case *syscall.SockaddrInet6: + addr := net.TCPAddr{IP: sa.Addr[:], Port: sa.Port, Zone: strconv.Itoa(int(sa.ZoneId))} + f("tcp6", addr.String(), ufd) + } + + file := os.NewFile(ufd, address) defer file.Close() return net.FileListener(file) diff --git a/transport/internet/system_listener.go b/transport/internet/system_listener.go index a8b4cc602..e9ca184ce 100644 --- a/transport/internet/system_listener.go +++ b/transport/internet/system_listener.go @@ -36,23 +36,27 @@ func (l *combinedListener) Close() error { return l.Listener.Close() } +func getRawControlFunc(network, address string, ctx context.Context, sockopt *SocketConfig, controllers []controller) func(fd uintptr) { + return func(fd uintptr) { + if sockopt != nil { + if err := applyInboundSocketOptions(network, fd, sockopt); err != nil { + newError("failed to apply socket options to incoming connection").Base(err).WriteToLog(session.ExportIDToError(ctx)) + } + } + + setReusePort(fd) // nolint: staticcheck + + for _, controller := range controllers { + if err := controller(network, address, fd); err != nil { + newError("failed to apply external controller").Base(err).WriteToLog(session.ExportIDToError(ctx)) + } + } + } +} + func getControlFunc(ctx context.Context, sockopt *SocketConfig, controllers []controller) func(network, address string, c syscall.RawConn) error { return func(network, address string, c syscall.RawConn) error { - return c.Control(func(fd uintptr) { - if sockopt != nil { - if err := applyInboundSocketOptions(network, fd, sockopt); err != nil { - newError("failed to apply socket options to incoming connection").Base(err).WriteToLog(session.ExportIDToError(ctx)) - } - } - - setReusePort(fd) // nolint: staticcheck - - for _, controller := range controllers { - if err := controller(network, address, fd); err != nil { - newError("failed to apply external controller").Base(err).WriteToLog(session.ExportIDToError(ctx)) - } - } - }) + return c.Control(getRawControlFunc(network, address, ctx, sockopt, controllers)) } } @@ -97,7 +101,9 @@ func (dl *DefaultListener) Listen(ctx context.Context, addr net.Addr, sockopt *S } } else if strings.HasPrefix(address, "/dev/fd/") { // socket activation - l, err = activateSocket(address) + l, err = activateSocket(address, func(network, address string, fd uintptr) { + getRawControlFunc(network, address, ctx, sockopt, dl.controllers)(fd) + }) if err != nil { return nil, err }