add support for socket passing

This commit is contained in:
mat 2025-08-06 09:04:17 -03:00
parent b664ebb01f
commit 2fad85ee08
5 changed files with 42 additions and 29 deletions

View file

@ -536,7 +536,7 @@ def get_sects():
dedent( dedent(
""" """
\033[33m-i\033[0m takes a comma-separated list of interfaces to listen on; \033[33m-i\033[0m takes a comma-separated list of interfaces to listen on;
IP-addresses and/or unix-sockets (Unix Domain Sockets) IP-addresses, unix-sockets and/or open file descriptors
the default (\033[32m-i ::\033[0m) means all IPv4 and IPv6 addresses the default (\033[32m-i ::\033[0m) means all IPv4 and IPv6 addresses
@ -562,6 +562,8 @@ def get_sects():
\033[32m-i unix:\033[33m/dev/shm/party.sock\033[0m keeps umask-defined permission \033[32m-i unix:\033[33m/dev/shm/party.sock\033[0m keeps umask-defined permission
(usually \033[33m0600\033[0m) and the same user/group as copyparty (usually \033[33m0600\033[0m) and the same user/group as copyparty
\033[32m-i fd:\033[33m3\033[0m uses the socket passed to copyparty on file descriptor 3
\033[33m-p\033[0m (tcp ports) is ignored for unix sockets \033[33m-p\033[0m (tcp ports) is ignored for unix sockets
""" """
), ),

View file

@ -607,7 +607,7 @@ class Ftpd(object):
if "::" in ips: if "::" in ips:
ips.append("0.0.0.0") ips.append("0.0.0.0")
ips = [x for x in ips if "unix:" not in x] ips = [x for x in ips if not x.startswith(("unix:", "fd:"))]
if self.args.ftp4: if self.args.ftp4:
ips = [x for x in ips if ":" not in x] ips = [x for x in ips if ":" not in x]

View file

@ -868,7 +868,7 @@ class SvcHub(object):
have_tcp = False have_tcp = False
for zs in al.i: for zs in al.i:
if not zs.startswith("unix:"): if not zs.startswith(("unix:", "fd:")):
have_tcp = True have_tcp = True
if not have_tcp: if not have_tcp:
zb = False zb = False
@ -878,7 +878,7 @@ class SvcHub(object):
setattr(al, zs, False) setattr(al, zs, False)
zb = True zb = True
if zb: if zb:
t = "only listening on unix-sockets; cannot enable zeroconf/mdns/ssdp as requested" t = "no ip addresses provided; cannot enable zeroconf/mdns/ssdp as requested"
self.log("root", t, 3) self.log("root", t, 3)
if not self.args.no_dav: if not self.args.no_dav:

View file

@ -245,8 +245,10 @@ class TcpSrv(object):
def _listen(self, ip: str, port: int) -> None: def _listen(self, ip: str, port: int) -> None:
uds_perm = uds_gid = -1 uds_perm = uds_gid = -1
bound = False
tcp = False
if "unix:" in ip: if "unix:" in ip:
tcp = False
ipv = socket.AF_UNIX ipv = socket.AF_UNIX
uds = ip.split(":") uds = ip.split(":")
ip = uds[-1] ip = uds[-1]
@ -259,7 +261,12 @@ class TcpSrv(object):
import grp import grp
uds_gid = grp.getgrnam(uds[2]).gr_gid uds_gid = grp.getgrnam(uds[2]).gr_gid
elif "fd:" in ip:
fd = ip[3:]
bound = socket.socket(fileno=int(fd))
tcp = bound.proto == socket.IPPROTO_TCP
ipv = bound.family
elif ":" in ip: elif ":" in ip:
tcp = True tcp = True
ipv = socket.AF_INET6 ipv = socket.AF_INET6
@ -267,7 +274,10 @@ class TcpSrv(object):
tcp = True tcp = True
ipv = socket.AF_INET ipv = socket.AF_INET
srv = socket.socket(ipv, socket.SOCK_STREAM) if not bound:
srv = socket.socket(ipv, socket.SOCK_STREAM)
else:
srv = bound
if not ANYWIN or self.args.reuseaddr: if not ANYWIN or self.args.reuseaddr:
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
@ -286,29 +296,30 @@ class TcpSrv(object):
srv.setsockopt(socket.SOL_IP, socket.IP_FREEBIND, 1) srv.setsockopt(socket.SOL_IP, socket.IP_FREEBIND, 1)
try: try:
if tcp: if not bound:
srv.bind((ip, port)) if tcp:
else: srv.bind((ip, port))
if ANYWIN or self.args.rm_sck:
if os.path.exists(ip):
os.unlink(ip)
srv.bind(ip)
else: else:
tf = "%s.%d" % (ip, os.getpid()) if ANYWIN or self.args.rm_sck:
if os.path.exists(tf): if os.path.exists(ip):
os.unlink(tf) os.unlink(ip)
srv.bind(tf) srv.bind(ip)
if uds_gid != -1: else:
os.chown(tf, -1, uds_gid) tf = "%s.%d" % (ip, os.getpid())
if uds_perm != -1: if os.path.exists(tf):
os.chmod(tf, uds_perm) os.unlink(tf)
atomic_move(self.nlog, tf, ip, VF_CAREFUL) srv.bind(tf)
if uds_gid != -1:
os.chown(tf, -1, uds_gid)
if uds_perm != -1:
os.chmod(tf, uds_perm)
atomic_move(self.nlog, tf, ip, VF_CAREFUL)
sport = srv.getsockname()[1] if tcp else port sport = srv.getsockname()[1] if tcp else port
if port != sport: if port != sport:
# linux 6.0.16 lets you bind a port which is in use # linux 6.0.16 lets you bind a port which is in use
# except it just gives you a random port instead # except it just gives you a random port instead
raise OSError(E_ADDR_IN_USE[0], "") raise OSError(E_ADDR_IN_USE[0], "")
self.srv.append(srv) self.srv.append(srv)
except (OSError, socket.error) as ex: except (OSError, socket.error) as ex:
try: try:
@ -437,7 +448,7 @@ class TcpSrv(object):
def detect_interfaces(self, listen_ips: list[str]) -> dict[str, Netdev]: def detect_interfaces(self, listen_ips: list[str]) -> dict[str, Netdev]:
from .stolen.ifaddr import get_adapters from .stolen.ifaddr import get_adapters
listen_ips = [x for x in listen_ips if "unix:" not in x] listen_ips = [x for x in listen_ips if not x.startswith(("unix:", "fd:"))]
nics = get_adapters(True) nics = get_adapters(True)
eps: dict[str, Netdev] = {} eps: dict[str, Netdev] = {}

View file

@ -179,7 +179,7 @@ class Tftpd(object):
if "::" in ips: if "::" in ips:
ips.append("0.0.0.0") ips.append("0.0.0.0")
ips = [x for x in ips if "unix:" not in x] ips = [x for x in ips if not x.startswith(("unix:", "fd:"))]
if self.args.tftp4: if self.args.tftp4:
ips = [x for x in ips if ":" not in x] ips = [x for x in ips if ":" not in x]