Browse Source

apply control func to activated sockets

Misaki Kasumi 1 year ago
parent
commit
3d07f686a5

+ 1 - 1
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")
 }

+ 17 - 2
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)

+ 20 - 14
transport/internet/system_listener.go

@@ -36,23 +36,27 @@ func (l *combinedListener) Close() error {
 	return l.Listener.Close()
 }
 
-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))
-				}
+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
+		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))
-				}
+		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(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
 			}