actually impl --mc-hop (and improve --zm-spam)
This commit is contained in:
parent
b28bfe64c0
commit
7673beef72
@ -295,7 +295,9 @@ class MDNS(MCast):
|
|||||||
while self.running:
|
while self.running:
|
||||||
timeout = (
|
timeout = (
|
||||||
0.02 + random.random() * 0.07
|
0.02 + random.random() * 0.07
|
||||||
if self.probing or self.q or self.defend or self.unsolicited
|
if self.probing or self.q or self.defend
|
||||||
|
else max(0.05, self.unsolicited[0] - time.time())
|
||||||
|
if self.unsolicited
|
||||||
else (last_hop + ihop if ihop else 180)
|
else (last_hop + ihop if ihop else 180)
|
||||||
)
|
)
|
||||||
rdy = select.select(self.srv, [], [], timeout)
|
rdy = select.select(self.srv, [], [], timeout)
|
||||||
@ -514,7 +516,8 @@ class MDNS(MCast):
|
|||||||
tx.add(srv)
|
tx.add(srv)
|
||||||
|
|
||||||
if not self.unsolicited and self.args.zm_spam:
|
if not self.unsolicited and self.args.zm_spam:
|
||||||
self.unsolicited.append(time.time() + self.args.zm_spam)
|
zf = time.time() + self.args.zm_spam + random.random() * 0.07
|
||||||
|
self.unsolicited.append(zf)
|
||||||
|
|
||||||
for srv, deadline in list(self.defend.items()):
|
for srv, deadline in list(self.defend.items()):
|
||||||
if now < deadline:
|
if now < deadline:
|
||||||
|
@ -15,7 +15,7 @@ from ipaddress import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from .__init__ import MACOS, TYPE_CHECKING
|
from .__init__ import MACOS, TYPE_CHECKING
|
||||||
from .util import Netdev, find_prefix, min_ex, spack
|
from .util import Daemon, Netdev, find_prefix, min_ex, spack
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .svchub import SvcHub
|
from .svchub import SvcHub
|
||||||
@ -228,6 +228,7 @@ class MCast(object):
|
|||||||
for srv in self.srv.values():
|
for srv in self.srv.values():
|
||||||
assert srv.ip in self.sips
|
assert srv.ip in self.sips
|
||||||
|
|
||||||
|
Daemon(self.hopper, "mc-hop")
|
||||||
return bound
|
return bound
|
||||||
|
|
||||||
def setup_socket(self, srv: MC_Sck) -> None:
|
def setup_socket(self, srv: MC_Sck) -> None:
|
||||||
@ -299,33 +300,55 @@ class MCast(object):
|
|||||||
t = "failed to set IPv4 TTL/LOOP; announcements may not survive multiple switches/routers"
|
t = "failed to set IPv4 TTL/LOOP; announcements may not survive multiple switches/routers"
|
||||||
self.log(t, 3)
|
self.log(t, 3)
|
||||||
|
|
||||||
self.hop(srv)
|
if self.hop(srv, False):
|
||||||
|
self.log("igmp was already joined?? chilling for a sec", 3)
|
||||||
|
time.sleep(1.2)
|
||||||
|
|
||||||
|
self.hop(srv, True)
|
||||||
self.b4.sort(reverse=True)
|
self.b4.sort(reverse=True)
|
||||||
self.b6.sort(reverse=True)
|
self.b6.sort(reverse=True)
|
||||||
|
|
||||||
def hop(self, srv: MC_Sck) -> None:
|
def hop(self, srv: MC_Sck, on: bool) -> bool:
|
||||||
"""rejoin to keepalive on routers/switches without igmp-snooping"""
|
"""rejoin to keepalive on routers/switches without igmp-snooping"""
|
||||||
sck = srv.sck
|
sck = srv.sck
|
||||||
req = srv.mreq
|
req = srv.mreq
|
||||||
if ":" in srv.ip:
|
if ":" in srv.ip:
|
||||||
try:
|
if not on:
|
||||||
sck.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_LEAVE_GROUP, req)
|
try:
|
||||||
# linux does leaves/joins twice with 0.2~1.05s spacing
|
sck.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_LEAVE_GROUP, req)
|
||||||
time.sleep(1.2)
|
return True
|
||||||
except:
|
except:
|
||||||
pass
|
return False
|
||||||
|
else:
|
||||||
sck.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, req)
|
sck.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, req)
|
||||||
else:
|
else:
|
||||||
try:
|
if not on:
|
||||||
sck.setsockopt(socket.IPPROTO_IP, socket.IP_DROP_MEMBERSHIP, req)
|
try:
|
||||||
time.sleep(1.2)
|
sck.setsockopt(socket.IPPROTO_IP, socket.IP_DROP_MEMBERSHIP, req)
|
||||||
except:
|
return True
|
||||||
pass
|
except:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# t = "joining {} from ip {} idx {} with mreq {}"
|
||||||
|
# self.log(t.format(srv.grp, srv.ip, srv.idx, repr(srv.mreq)), 6)
|
||||||
|
sck.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, req)
|
||||||
|
|
||||||
# t = "joining {} from ip {} idx {} with mreq {}"
|
return True
|
||||||
# self.log(t.format(srv.grp, srv.ip, srv.idx, repr(srv.mreq)), 6)
|
|
||||||
sck.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, req)
|
def hopper(self):
|
||||||
|
while self.args.mc_hop and self.running:
|
||||||
|
time.sleep(self.args.mc_hop)
|
||||||
|
if not self.running:
|
||||||
|
return
|
||||||
|
|
||||||
|
for srv in self.srv.values():
|
||||||
|
self.hop(srv, False)
|
||||||
|
|
||||||
|
# linux does leaves/joins twice with 0.2~1.05s spacing
|
||||||
|
time.sleep(1.2)
|
||||||
|
|
||||||
|
for srv in self.srv.values():
|
||||||
|
self.hop(srv, True)
|
||||||
|
|
||||||
def map_client(self, cip: str) -> Optional[MC_Sck]:
|
def map_client(self, cip: str) -> Optional[MC_Sck]:
|
||||||
try:
|
try:
|
||||||
|
Loading…
Reference in New Issue
Block a user