mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
mdns: support primitive clients (android, rfc-6.7)
This commit is contained in:
parent
d326ba9723
commit
35175fd685
|
@ -621,7 +621,7 @@ def run_argparse(
|
|||
ap2.add_argument("--qr", action="store_true", help="show http:// QR-code on startup")
|
||||
ap2.add_argument("--qrs", action="store_true", help="show https:// QR-code on startup")
|
||||
ap2.add_argument("--qrl", metavar="PATH", type=u, default="", help="location to include in the url, for example [\033[32mpriv/?pw=hunter2\033[0m]")
|
||||
ap2.add_argument("--qri", metavar="PREFIX", type=u, default="", help="select IP which starts with PREFIX")
|
||||
ap2.add_argument("--qri", metavar="PREFIX", type=u, default="", help="select IP which starts with PREFIX; [\033[32m.\033[0m] to force default IP when mDNS URL would have been used instead")
|
||||
ap2.add_argument("--qr-fg", metavar="COLOR", type=int, default=0 if tty else 16, help="foreground; try [\033[32m0\033[0m] if the qr-code is unreadable")
|
||||
ap2.add_argument("--qr-bg", metavar="COLOR", type=int, default=229, help="background (white=255)")
|
||||
ap2.add_argument("--qrp", metavar="CELLS", type=int, default=4, help="padding (spec says 4 or more, but 1 is usually fine)")
|
||||
|
|
|
@ -373,24 +373,66 @@ class MDNS(MCast):
|
|||
self.stop(True)
|
||||
return
|
||||
|
||||
# then rfc-6.7; dns pretending to be mdns (android...)
|
||||
if p.header.id or addr[1] != 5353:
|
||||
rsp: Optional[DNSRecord] = None
|
||||
for r in p.questions:
|
||||
try:
|
||||
lhn = U(r.qname).lower()
|
||||
except:
|
||||
self.log("invalid question: {}".format(r))
|
||||
continue
|
||||
|
||||
if lhn != self.lhn:
|
||||
continue
|
||||
|
||||
if p.header.id and r.qtype in (QTYPE.A, QTYPE.AAAA):
|
||||
rsp = rsp or DNSRecord(DNSHeader(p.header.id, 0x8400))
|
||||
rsp.add_question(r)
|
||||
for ip in srv.ips:
|
||||
qt = r.qtype
|
||||
v6 = ":" in ip
|
||||
if v6 == (qt == QTYPE.AAAA):
|
||||
rd = AAAA(ip) if v6 else A(ip)
|
||||
rr = RR(self.hn, qt, DC.IN, 10, rd)
|
||||
rsp.add_answer(rr)
|
||||
if rsp:
|
||||
srv.sck.sendto(rsp.pack(), addr[:2])
|
||||
# but don't return in case it's a differently broken client
|
||||
|
||||
# then a/aaaa records
|
||||
for r in p.questions:
|
||||
if U(r.qname).lower() != self.lhn:
|
||||
try:
|
||||
lhn = U(r.qname).lower()
|
||||
except:
|
||||
self.log("invalid question: {}".format(r))
|
||||
continue
|
||||
|
||||
if lhn != self.lhn:
|
||||
continue
|
||||
|
||||
# gvfs keeps repeating itself
|
||||
found = False
|
||||
unicast = False
|
||||
for r in p.rr:
|
||||
rname = U(r.rname).lower()
|
||||
for rr in p.rr:
|
||||
try:
|
||||
rname = U(rr.rname).lower()
|
||||
except:
|
||||
self.log("invalid rr: {}".format(rr))
|
||||
continue
|
||||
|
||||
if rname == self.lhn:
|
||||
if r.ttl > 60:
|
||||
if rr.ttl > 60:
|
||||
found = True
|
||||
if r.rclass == DC.F_IN:
|
||||
if rr.rclass == DC.F_IN:
|
||||
unicast = True
|
||||
|
||||
if unicast:
|
||||
# spec-compliant mDNS-over-unicast
|
||||
srv.sck.sendto(srv.bp_ip, (cip, 5353))
|
||||
elif addr[1] != 5353:
|
||||
# just in case some clients use (and want us to use) invalid ports
|
||||
srv.sck.sendto(srv.bp_ip, addr[:2])
|
||||
|
||||
if not found:
|
||||
self.q[cip] = (0, srv, srv.bp_ip)
|
||||
|
@ -400,6 +442,9 @@ class MDNS(MCast):
|
|||
|
||||
# and service queries
|
||||
for r in p.questions:
|
||||
if not r or not r.qname:
|
||||
continue
|
||||
|
||||
qname = U(r.qname).lower()
|
||||
if qname in self.lsvcs or qname == "_services._dns-sd._udp.local.":
|
||||
self.q[cip] = (deadline, srv, srv.bp_svc)
|
||||
|
@ -408,10 +453,13 @@ class MDNS(MCast):
|
|||
# (workaround gvfs race-condition where it occasionally
|
||||
# doesn't read/decode the full response...)
|
||||
if now < srv.last_tx + 12:
|
||||
for r in p.rr:
|
||||
rdata = U(r.rdata).lower()
|
||||
for rr in p.rr:
|
||||
if not rr.rdata:
|
||||
continue
|
||||
|
||||
rdata = U(rr.rdata).lower()
|
||||
if rdata in self.lsfqdns:
|
||||
if r.ttl > 2250:
|
||||
if rr.ttl > 2250:
|
||||
self.q.pop(cip, None)
|
||||
break
|
||||
|
||||
|
|
|
@ -106,9 +106,9 @@ class DNSRecord(object):
|
|||
) -> None:
|
||||
self.header = header or DNSHeader()
|
||||
self.questions: list[DNSQuestion] = questions or []
|
||||
self.rr = rr or []
|
||||
self.auth = auth or []
|
||||
self.ar = ar or []
|
||||
self.rr: list[RR] = rr or []
|
||||
self.auth: list[RR] = auth or []
|
||||
self.ar: list[RR] = ar or []
|
||||
|
||||
if q:
|
||||
self.questions.append(q)
|
||||
|
|
|
@ -508,19 +508,20 @@ class TcpSrv(object):
|
|||
def _qr(self, t1: dict[str, list[int]], t2: dict[str, list[int]]) -> str:
|
||||
ip = None
|
||||
ips = list(t1) + list(t2)
|
||||
if self.args.zm:
|
||||
qri = self.args.qri
|
||||
if self.args.zm and not qri:
|
||||
name = self.args.name + ".local"
|
||||
t1[name] = next(v for v in (t1 or t2).values())
|
||||
ips = [name] + ips
|
||||
|
||||
for ip in ips:
|
||||
if ip.startswith(self.args.qri):
|
||||
if ip.startswith(qri) or qri == ".":
|
||||
break
|
||||
ip = ""
|
||||
|
||||
if not ip:
|
||||
# maybe /bin/ip is missing or smth
|
||||
ip = self.args.qri
|
||||
ip = qri
|
||||
|
||||
if not ip:
|
||||
return ""
|
||||
|
|
Loading…
Reference in a new issue