zeroconf: add network filtering options

This commit is contained in:
ed 2022-11-26 22:37:12 +00:00
parent f39e370e2a
commit cfd41fcf41
5 changed files with 61 additions and 24 deletions

View file

@ -614,7 +614,7 @@ def run_argparse(
ap2.add_argument("-mcr", metavar="SEC", type=int, default=60, help="md-editor mod-chk rate") ap2.add_argument("-mcr", metavar="SEC", type=int, default=60, help="md-editor mod-chk rate")
ap2.add_argument("--urlform", metavar="MODE", type=u, default="print,get", help="how to handle url-form POSTs; see --help-urlform") ap2.add_argument("--urlform", metavar="MODE", type=u, default="print,get", help="how to handle url-form POSTs; see --help-urlform")
ap2.add_argument("--wintitle", metavar="TXT", type=u, default="cpp @ $pub", help="window title, for example [\033[32m$ip-10.1.2.\033[0m] or [\033[32m$ip-]") ap2.add_argument("--wintitle", metavar="TXT", type=u, default="cpp @ $pub", help="window title, for example [\033[32m$ip-10.1.2.\033[0m] or [\033[32m$ip-]")
ap2.add_argument("--name", metavar="TXT", type=str, default=srvname, help="server name (displayed topleft in browser and in mDNS)") ap2.add_argument("--name", metavar="TXT", type=u, default=srvname, help="server name (displayed topleft in browser and in mDNS)")
ap2.add_argument("--license", action="store_true", help="show licenses and exit") ap2.add_argument("--license", action="store_true", help="show licenses and exit")
ap2.add_argument("--version", action="store_true", help="show versions and exit") ap2.add_argument("--version", action="store_true", help="show versions and exit")
@ -665,26 +665,32 @@ def run_argparse(
ap2 = ap.add_argument_group("Zeroconf options") ap2 = ap.add_argument_group("Zeroconf options")
ap2.add_argument("-z", action="store_true", help="enable all zeroconf backends (mdns, ssdp)") ap2.add_argument("-z", action="store_true", help="enable all zeroconf backends (mdns, ssdp)")
ap2.add_argument("--z-on", metavar="NICS/NETS", type=u, default="", help="enable zeroconf ONLY on the comma-separated list of subnets and/or interface names\n └─example: \033[32meth0, wlo1, virhost0, 192.168.123.0/24, fd00:fda::/96\033[0m")
ap2.add_argument("--z-off", metavar="NICS/NETS", type=u, default="", help="disable zeroconf on the comma-separated list of subnets and/or interface names")
ap2.add_argument("-zv", action="store_true", help="verbose all zeroconf backends") ap2.add_argument("-zv", action="store_true", help="verbose all zeroconf backends")
ap2.add_argument("--mc-hop", metavar="SEC", type=int, default=0, help="rejoin multicast groups every SEC seconds (workaround for some switches/routers which cause mDNS to suddenly stop working after some time); try [\033[32m300\033[0m] or [\033[32m180\033[0m]") ap2.add_argument("--mc-hop", metavar="SEC", type=int, default=0, help="rejoin multicast groups every SEC seconds (workaround for some switches/routers which cause mDNS to suddenly stop working after some time); try [\033[32m300\033[0m] or [\033[32m180\033[0m]")
ap2 = ap.add_argument_group("Zeroconf-mDNS options:") ap2 = ap.add_argument_group("Zeroconf-mDNS options:")
ap2.add_argument("--zm", action="store_true", help="announce the enabled protocols over mDNS (multicast DNS-SD) -- compatible with KDE, gnome, macOS, ...") ap2.add_argument("--zm", action="store_true", help="announce the enabled protocols over mDNS (multicast DNS-SD) -- compatible with KDE, gnome, macOS, ...")
ap2.add_argument("--zm-on", metavar="NICS/NETS", type=u, default="", help="enable zeroconf ONLY on the comma-separated list of subnets and/or interface names")
ap2.add_argument("--zm-off", metavar="NICS/NETS", type=u, default="", help="disable zeroconf on the comma-separated list of subnets and/or interface names")
ap2.add_argument("--zm4", action="store_true", help="IPv4 only -- try this if some clients can't connect") ap2.add_argument("--zm4", action="store_true", help="IPv4 only -- try this if some clients can't connect")
ap2.add_argument("--zm6", action="store_true", help="IPv6 only") ap2.add_argument("--zm6", action="store_true", help="IPv6 only")
ap2.add_argument("--zmv", action="store_true", help="verbose mdns") ap2.add_argument("--zmv", action="store_true", help="verbose mdns")
ap2.add_argument("--zmvv", action="store_true", help="verboser mdns") ap2.add_argument("--zmvv", action="store_true", help="verboser mdns")
ap2.add_argument("--zms", metavar="dhf", type=str, default="", help="list of services to announce -- d=webdav h=http f=ftp s=smb -- lowercase=plaintext uppercase=TLS -- default: all enabled services except http/https (\033[32mDdfs\033[0m if \033[33m--ftp\033[0m and \033[33m--smb\033[0m is set)") ap2.add_argument("--zms", metavar="dhf", type=u, default="", help="list of services to announce -- d=webdav h=http f=ftp s=smb -- lowercase=plaintext uppercase=TLS -- default: all enabled services except http/https (\033[32mDdfs\033[0m if \033[33m--ftp\033[0m and \033[33m--smb\033[0m is set)")
ap2.add_argument("--zm-ld", metavar="PATH", type=str, default="", help="link a specific folder for webdav shares") ap2.add_argument("--zm-ld", metavar="PATH", type=u, default="", help="link a specific folder for webdav shares")
ap2.add_argument("--zm-lh", metavar="PATH", type=str, default="", help="link a specific folder for http shares") ap2.add_argument("--zm-lh", metavar="PATH", type=u, default="", help="link a specific folder for http shares")
ap2.add_argument("--zm-lf", metavar="PATH", type=str, default="", help="link a specific folder for ftp shares") ap2.add_argument("--zm-lf", metavar="PATH", type=u, default="", help="link a specific folder for ftp shares")
ap2.add_argument("--zm-ls", metavar="PATH", type=str, default="", help="link a specific folder for smb shares") ap2.add_argument("--zm-ls", metavar="PATH", type=u, default="", help="link a specific folder for smb shares")
ap2.add_argument("--zm-mnic", action="store_true", help="merge NICs which share subnets; assume that same subnet means same network") ap2.add_argument("--zm-mnic", action="store_true", help="merge NICs which share subnets; assume that same subnet means same network")
ap2.add_argument("--zm-msub", action="store_true", help="merge subnets on each NIC -- always enabled for ipv6 -- reduces network load, but gnome-gvfs clients may stop working") ap2.add_argument("--zm-msub", action="store_true", help="merge subnets on each NIC -- always enabled for ipv6 -- reduces network load, but gnome-gvfs clients may stop working")
ap2.add_argument("--zm-noneg", action="store_true", help="disable NSEC replies -- try this if some clients don't see copyparty") ap2.add_argument("--zm-noneg", action="store_true", help="disable NSEC replies -- try this if some clients don't see copyparty")
ap2 = ap.add_argument_group("Zeroconf-SSDP options:") ap2 = ap.add_argument_group("Zeroconf-SSDP options:")
ap2.add_argument("--zs", action="store_true", help="announce the enabled protocols over SSDP -- compatible with Windows") ap2.add_argument("--zs", action="store_true", help="announce the enabled protocols over SSDP -- compatible with Windows")
ap2.add_argument("--zs-on", metavar="NICS/NETS", type=u, default="", help="enable zeroconf ONLY on the comma-separated list of subnets and/or interface names")
ap2.add_argument("--zs-off", metavar="NICS/NETS", type=u, default="", help="disable zeroconf on the comma-separated list of subnets and/or interface names")
ap2.add_argument("--zsv", action="store_true", help="verbose SSDP") ap2.add_argument("--zsv", action="store_true", help="verbose SSDP")
ap2.add_argument("--zsl", metavar="PATH", type=u, default="", help="location to include in the url (or a complete external URL), for example [\033[32mpriv/?pw=hunter2\033[0m] or [\033[32mpriv/?pw=hunter2\033[0m]") ap2.add_argument("--zsl", metavar="PATH", type=u, default="", help="location to include in the url (or a complete external URL), for example [\033[32mpriv/?pw=hunter2\033[0m] or [\033[32mpriv/?pw=hunter2\033[0m]")
ap2.add_argument("--zsid", metavar="UUID", type=u, default=uuid.uuid4().urn[4:], help="USN (device identifier) to announce") ap2.add_argument("--zsid", metavar="UUID", type=u, default=uuid.uuid4().urn[4:], help="USN (device identifier) to announce")

View file

@ -60,9 +60,12 @@ class MDNS_Sck(MC_Sck):
class MDNS(MCast): class MDNS(MCast):
def __init__(self, hub: "SvcHub") -> None: def __init__(self, hub: "SvcHub") -> None:
grp4 = "" if hub.args.zm6 else MDNS4 al = hub.args
grp6 = "" if hub.args.zm4 else MDNS6 grp4 = "" if al.zm6 else MDNS4
super(MDNS, self).__init__(hub, MDNS_Sck, grp4, grp6, 5353, hub.args.zmv) grp6 = "" if al.zm4 else MDNS6
super(MDNS, self).__init__(
hub, MDNS_Sck, al.zm_on, al.zm_off, grp4, grp6, 5353, hub.args.zmv
)
self.srv: dict[socket.socket, MDNS_Sck] = {} self.srv: dict[socket.socket, MDNS_Sck] = {}
self.ttl = 300 self.ttl = 300

View file

@ -54,6 +54,8 @@ class MCast(object):
self, self,
hub: "SvcHub", hub: "SvcHub",
Srv: type[MC_Sck], Srv: type[MC_Sck],
on: list[str],
off: list[str],
mc_grp_4: str, mc_grp_4: str,
mc_grp_6: str, mc_grp_6: str,
port: int, port: int,
@ -65,6 +67,8 @@ class MCast(object):
self.args = hub.args self.args = hub.args
self.asrv = hub.asrv self.asrv = hub.asrv
self.log_func = hub.log self.log_func = hub.log
self.on = on
self.off = off
self.grp4 = mc_grp_4 self.grp4 = mc_grp_4
self.grp6 = mc_grp_6 self.grp6 = mc_grp_6
self.port = port self.port = port
@ -84,26 +88,37 @@ class MCast(object):
def create_servers(self) -> list[str]: def create_servers(self) -> list[str]:
bound: list[str] = [] bound: list[str] = []
netdevs = self.hub.tcpsrv.netdevs
ips = [x[0] for x in self.hub.tcpsrv.bound] ips = [x[0] for x in self.hub.tcpsrv.bound]
if "::" in ips: if "::" in ips:
ips = [x for x in ips if x != "::"] + list( ips = [x for x in ips if x != "::"] + list(
[x.split("/")[0] for x in self.hub.tcpsrv.netdevs if ":" in x] [x.split("/")[0] for x in netdevs if ":" in x]
) )
ips.append("0.0.0.0") ips.append("0.0.0.0")
if "0.0.0.0" in ips: if "0.0.0.0" in ips:
ips = [x for x in ips if x != "0.0.0.0"] + list( ips = [x for x in ips if x != "0.0.0.0"] + list(
[x.split("/")[0] for x in self.hub.tcpsrv.netdevs if ":" not in x] [x.split("/")[0] for x in netdevs if ":" not in x]
) )
ips = [x for x in ips if x not in ("::1", "127.0.0.1")] ips = [x for x in ips if x not in ("::1", "127.0.0.1")]
# ip -> ip/prefix # ip -> ip/prefix
ips = [ ips = [[x for x in netdevs if x.startswith(y + "/")][0] for y in ips]
[x for x in self.hub.tcpsrv.netdevs if x.startswith(y + "/")][0]
for y in ips on = self.on[:]
] off = self.off[:]
for lst in (on, off):
for av in list(lst):
for sk, sv in netdevs.items():
if av == sv.split(",")[0] and sk not in lst:
lst.append(sk)
if on:
ips = [x for x in ips if x in on]
elif off:
ips = [x for x in ips if x not in off]
if not self.grp4: if not self.grp4:
ips = [x for x in ips if ":" in x] ips = [x for x in ips if ":" in x]
@ -124,7 +139,7 @@ class MCast(object):
v6 = ":" in ip v6 = ":" in ip
netdev = "?" netdev = "?"
try: try:
netdev = self.hub.tcpsrv.netdevs[ip].split(",")[0] netdev = netdevs[ip].split(",")[0]
idx = socket.if_nametoindex(netdev) idx = socket.if_nametoindex(netdev)
except: except:
idx = socket.INADDR_ANY idx = socket.INADDR_ANY
@ -145,7 +160,7 @@ class MCast(object):
# add a/aaaa records for the other nic IPs # add a/aaaa records for the other nic IPs
other_ips: set[str] = set() other_ips: set[str] = set()
if v6 and netdev not in ("?", ""): if v6 and netdev not in ("?", ""):
for oip, onic in self.hub.tcpsrv.netdevs.items(): for oip, onic in netdevs.items():
if ( if (
onic.split(",")[0] == netdev onic.split(",")[0] == netdev
and oip in all_selected and oip in all_selected

View file

@ -88,8 +88,11 @@ class SSDPd(MCast):
"""communicates with ssdp clients over multicast""" """communicates with ssdp clients over multicast"""
def __init__(self, hub: "SvcHub") -> None: def __init__(self, hub: "SvcHub") -> None:
vinit = hub.args.zsv and not hub.args.zmv al = hub.args
super(SSDPd, self).__init__(hub, SSDP_Sck, GRP, "", 1900, vinit) vinit = al.zsv and not al.zmv
super(SSDPd, self).__init__(
hub, SSDP_Sck, al.zs_on, al.zs_off, GRP, "", 1900, vinit
)
self.srv: dict[socket.socket, SSDP_Sck] = {} self.srv: dict[socket.socket, SSDP_Sck] = {}
self.rxc = CachedSet(0.7) self.rxc = CachedSet(0.7)
self.txc = CachedSet(5) # win10: every 3 sec self.txc = CachedSet(5) # win10: every 3 sec

View file

@ -289,12 +289,22 @@ class SvcHub(object):
Daemon(self.sd_notify, "sd-notify") Daemon(self.sd_notify, "sd-notify")
def _process_config(self) -> bool: def _process_config(self) -> bool:
if self.args.loris1 == "no": al = self.args
self.args.loris1 = "0,0" if al.loris1 == "no":
al.loris1 = "0,0"
i1, i2 = self.args.loris1.split(",") i1, i2 = al.loris1.split(",")
self.args.loris1w = int(i1) al.loris1w = int(i1)
self.args.loris1b = int(i2) al.loris1b = int(i2)
al.zm_on = al.zm_on or al.z_on
al.zs_on = al.zs_on or al.z_on
al.zm_off = al.zm_off or al.z_off
al.zs_off = al.zs_off or al.z_off
for n in ("zm_on", "zm_off", "zs_on", "zs_off"):
vs = getattr(al, n).replace(" ", ",").split(",")
vs = [x for x in vs if x]
setattr(al, n, vs)
return True return True