mDNS (und dns-sd) test version

Begonnen von justme1968, 17 Februar 2022, 10:36:56

Vorheriges Thema - Nächstes Thema

justme1968

zum hintergrund: neben upnp/ssdp gibt es mit mdns/dns-sd einen zweiten weit verbreiteten ansatz um dienste in einem lokalen netz bekannt zu geben und zu suchen bzw. zu finden.

da es sich mit meinem discovery modul aus diesem thread: https://forum.fhem.de/index.php/topic,67368.msg880001.html#msg880001 noch etwas hin zieht, inzwischen aber auch ein upnp/ssdp modul entsteht und ich weitere doppel entwicklungen vermeiden möchte habe ich einen schon sinnvoll benutzbaren mdns teil des discovery moduls aufgeräumt und standallone benutzbar gemacht.


was machen die routinen: man kann damit im one-shot unicast modus browsen und resolven. allerdings mit der auswertung mehrerer resource records (primary und additional) in einer antwort sowie dem empfangen von mehreren antworten auf eine anfrage innerhalb des gesetzten timeouts. unterstützt werden aktuell a, aaaa, ptr, txt und srv records in der antwort sowie alle typen in der anfrage.

das ganze funktioniert komplett ohne externe abhängigkeiten (außer fhem :) ) und ist non-blocking. es sollte möglich sein beliebig viele parallele anfragen abzusetzen.

der code ist sehr ähnlich zu den bereits in fhem vorhandenen non-blocking dns routinen. der hauptunterschied besteht darin das er genereller, d.h. für mehr resource records und mehrere antworten, implementiert ist und das natürlich mdns verwendet wird statt eines konfigurierten lokalen nameservers. ausserdem ist das interface eher an HttpUtils_NonblockingGet als an HttpUtils_gethostbyname orientiert.

noch nicht enthalten ist: das permanente lauschen und sammeln im hintergrund auf mdns multicast nachrichten an port 5353. das läuft zwar auch schon, aktuell brauche ich dafür aber das perl IO::Socket::Multicast modul und ich würde gerne ohne auskommen. ebenfalls ist aktuell ein cache für die antworten deaktiviert da er nur mit einem einzelnen resource record pro anfrage klar kommt und vermutlich der hintergrund dienst sowieso sinnvoller als ein reiner cache ist.

mögliche beispielaufrufe sehen etwa so aus:
{ mDNS::mDNS_Lookup({qname=>'_services._dns-sd._udp', callback=>\&mDNS::mDNS_dumpResult}) }
findet alle im lokalen netz angebotenen service typen

{ mDNS::mDNS_Lookup({qname=>'_http._tcp', callback=>\&mDNS::mDNS_dumpResult}) }
infos zu allen im lokalen netz angebotenen http dienste

{ mDNS::mDNS_Lookup({qname=>'_hue._tcp', callback=>\&mDNS::mDNS_dumpResult}) }
infos zu allen im lokalen netz vorhandenen hue bridges

{ mDNS::mDNS_Lookup({qname=>'_coap._tcp', callback=>\&mDNS::mDNS_dumpResult}) }
infos zu allen im lokalen netz vorhandenen coap diensten. das sind z.b. tradfri gateways und vermutlich auch shellys

{ mDNS::mDNS_Lookup({qname=>'_ipp._tcp',singleshot=>1, callback=>\&mDNS::mDNS_dumpResult}) }
infos zum ersten im lokalen netz gefundenen ipp drucker

{ mDNS::mDNS_Lookup({qname=>'<hostname>', qtype=>'A', callback=>\&mDNS::mDNS_dumpResult}) }
'normale' mdns ipv4 namensauflösung für <hostname> d.h. für hostname.local

{ mDNS::mDNS_Lookup({qname=>'<hostname>', qtype=>'AAAA', callback=>\&mDNS::mDNS_dumpResult}) }
das gleiche für ipv6

{ mDNS::mDNS_Lookup({qname=>'<hostname>', qtype=>'ALL',singlerr=>1,callback=>\&mDNS::mDNS_dumpResult}) }
die erste antwort für <hostname> egal ob v4 oder v6


statt mDNS::mDNS_dumpResult um das ergebnis nur ins log zu schreiben ist natürlich für eine sinnvolle verwendung eigener code als callback anzugeben.

die geplanten nächsten schritte sind: den multicast mode inklusive im hintergrund laufendem daten sammeln modul aufräumen und posten, die gesammelten daten dann im discovery modul verwenden, um auch upnp/ssdp im discovery modul zu verwenden irgendwie meine version von upnp/ssdp mit dem neuen modul aus dem upnp thread unter einen hut bringen.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

erwin

Hi !
super Sache, sehr brauchbar! Ich muss noch mehr testen... Eine Warning kommt allerdings, bei jedem Aufruf:
PERL WARNING: Variable "$hash" will not stay shared at ./FHEM/99_mDNS.pm line 296.
Ad multicast:
Es gibt dzt ca. 5 Module, die bereits MC (in der einen oder anderen Variante) verwenden....
Auch ich hab ein Modul im Betatest, das wahlweise TCP, UDP, Socket oder Multicast verwendet.
Details dazu hier: https://forum.fhem.de/index.php/topic,123697.0.html
Ich habe versucht das MC sehr "nahe" an DevIo zu implementieren, mit Hilfe von "FHEM:DEVIO:...", was allerdings etwas durch die Brust ins Auge ist  ;D
Evtl. könnten wir Rudi überzeugen, multicast im DevIo-Modul zu supporten, der zeitpunkt wäre für mich günstig, weil mein Modul noch nicht offiziell eingecheckt ist und dzt. nur von einer Handvoll Beta-testern verwendet wird...
Deine Meinung dazu?
l.g. erwin
FHEM aktuell auf RaspberryPI Mdl 1-4
Maintainer: 00_KNXIO.pm 10_KNX.pm
User: CUNO2 (868 SLOWRF) - HMS100xx, FS20, FHT, 1-Wire  - 2401(iButton), 18x20, 2406, 2413 (AVR), 2450,..,MQTT2, KNX, SONOFF, mySENSORS,....
Hardware:  Busware ROT, Weinzierl IP731, 1-Wire GW,...

justme1968

#2
da sind noch zwei zeilen vertauscht. wenn du 296 und 297 umtauschst sollte die meldung weg sein. ich habe auch die version oben ausgetauscht.

wie gut sich multicast ohne c backend machen lässt habe ich auch noch nicht geschaut. bisher habe ich ja IO::Socket::Multicast verwendet, würde externe abhängigkeiten aber gerne allgemein vermeiden, im speziellen scheint IO::Socket::Multicast aber zumindest zum teil c routinen zu brauchen und lässt sich deshalb z.b. auf meinem aktuellen mac nicht einfach installieren. wo es genau schief geht habe ich aber noch nicht weiter geschaut.

wenn wir uns auf eine fhem interne multicast lösung einigen können wäre das klasse. ob DevIo der allgemeingültig weg wäre habe ich noch nicht überlegt. aber wenn du da schon was hast werde ich auf jeden fall mal schauen ob das auch mit mdns so funktionieren würde.

was für mdns im multicast modus auf jeden fall wichtig wäre ist das sich neben ReuseAddr auch ReusePort setzen lässt bzw. das SO_REUSEPORT verwendbar ist da ich ja lokal den standart port 5353 zum senden und empfangen verwenden muss und es sehr wahrscheinlich ist das auf dem fhem system mindestens noch avahi und ähnliches läuft das diesen port ebenfalls verwenden muss.

ps: ich denke wenn wir multicast in fhem haben werden es bald mehr module explizit oder z.b. über mdns zur discovery implizit nutzen als 'nur' die 5 oder 6 die es aktuell sind.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

KölnSolar

Zitatupnp/ssdp im discovery modul zu verwenden irgendwie meine version von upnp/ssdp mit dem neuen modul aus dem upnp thread unter einen hut bringen.
Ich vermute Du meinst mich. :-\
mDNs ist mir noch gar nicht auf die Füße gefallen.

Mein UPNPController ist eigentlich fertig. Am WE kommt eine neue Version, so dass auch bei subscribed Services ohne logisches Modul FHEM-Events aus den upnp Events erzeugt werden.

Mein Hauptproblem ist, dass ich perlupnp verwende, wo sich nur begrenzt eingreifen lässt.

Wenn Du was von mir brauchst, melde Dich gerne.
Grüße
Markus
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

justme1968

@KölnSolar: perlupnp will ich auf jeden fall vermeiden. das reine empfangen und senden geht mit etwas eigenen code besser nonblocking in fhem zu integrieren. bei dir alles über den häufen zu schmeißen ist natürlich jetzt erst mal unsinn. erst recht da meine version aktuell noch gar nicht integriert ist. die upnp/ssdp baustelle auf meiner seite bleibt also erst mal offen.

@erwin: ich habe gerade ein kleines test programm hin gebaut das udp multicast für mdns empfängt und komplett ohne IO::Socket::Multicast (und c code abhängigkeit) auskommt. es geht also schon mal prinzipiell. aktuell noch sehr low level mit IO::Socket, eine ebene höher mit IO::Socket::INET scheint es aber auch zu gehen. bisher nur ipv4, ich wüsste aber nicht warum es nicht auch mit ipv6 bzw v4 und v6 kombiniert funktionieren sollte.

d.h. es spricht prinzipiell nichts dagegen multicast support ohne externe abhängigkeiten direkt in fhem einzubauen. auf den ersten blick scheint mir aber TcpServerUtils.pm besser als DevIO.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

KölnSolar

Zitatperlupnp will ich auf jeden fall vermeiden
versteh ich. :D

Aber vielleicht Teile kopieren ? :-\ den "logischen" Part ?

Zitateine ebene höher mit IO::Socket::INET scheint es aber auch zu gehen. bisher nur ipv4,
wird dort ja genutzt. Problematisch ist immer der LWP und HTTP Part für die Kommunikation. Mir fehlen aber die skills das auf etwas anderes umzubauen. DevIO ist eine Ebene zu hoch. TcpServerUtils.pm kann ich nicht beurteilen  :-[
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt