1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2025-01-18 07:17:32 -05:00
v2fly/transport/internet/socket_activation_unix.go

64 lines
1.4 KiB
Go
Raw Normal View History

2024-08-30 15:21:02 -04:00
//go:build unix
// +build unix
package internet
import (
2024-09-02 13:07:42 -04:00
"fmt"
2024-08-30 15:21:02 -04:00
"os"
2024-09-02 13:07:42 -04:00
"path"
2024-08-30 15:21:02 -04:00
"strconv"
"syscall"
"github.com/v2fly/v2ray-core/v5/common/net"
)
func activateSocket(address string, f func(network, address string, fd uintptr)) (net.Listener, error) {
2024-09-02 13:07:42 -04:00
fd, err := strconv.Atoi(path.Base(address))
2024-08-30 15:21:02 -04:00
if err != nil {
return nil, err
}
2024-09-02 13:07:42 -04:00
err = syscall.SetNonblock(fd, true)
if err != nil {
return nil, err
}
acceptConn, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_ACCEPTCONN)
if err != nil {
return nil, err
}
if acceptConn == 0 {
return nil, fmt.Errorf("socket '%s' has not been marked to accept connections", address)
}
sockType, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
if err != nil {
return nil, err
}
if sockType != syscall.SOCK_STREAM {
// XXX: currently only stream socks are supported
return nil, fmt.Errorf("socket '%s' is not a stream socket", 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)
2024-09-02 13:07:42 -04:00
defer file.Close()
return net.FileListener(file)
2024-08-30 15:21:02 -04:00
}