socket_activation_unix.go 996 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. //go:build unix
  2. // +build unix
  3. package internet
  4. import (
  5. "fmt"
  6. "os"
  7. "path"
  8. "strconv"
  9. "syscall"
  10. "github.com/v2fly/v2ray-core/v5/common/net"
  11. )
  12. func activateSocket(address string) (net.Listener, error) {
  13. fd, err := strconv.Atoi(path.Base(address))
  14. if err != nil {
  15. return nil, err
  16. }
  17. err = syscall.SetNonblock(fd, true)
  18. if err != nil {
  19. return nil, err
  20. }
  21. acceptConn, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_ACCEPTCONN)
  22. if err != nil {
  23. return nil, err
  24. }
  25. if acceptConn == 0 {
  26. return nil, fmt.Errorf("socket '%s' has not been marked to accept connections", address)
  27. }
  28. sockType, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
  29. if err != nil {
  30. return nil, err
  31. }
  32. if sockType != syscall.SOCK_STREAM {
  33. // XXX: currently only stream socks are supported
  34. return nil, fmt.Errorf("socket '%s' is not a stream socket", address)
  35. }
  36. file := os.NewFile(uintptr(fd), address)
  37. defer file.Close()
  38. return net.FileListener(file)
  39. }