Stellen Sie sich Multicast einfach wie Wasser vor: Prinzipiell schalten Sie einen Multicast-Sender im Netzwerk ein und dieses verteilt den Datenverkehr auf "magische Weise" in Ihrem Heimnetz.
Natürlich funktioniert das nie zufriedenstellend, daher machen wir hier alles manuell. Danke Manuell!
Wichtig ist zu verstehen, dass Sie eine Multicast-Gruppe ansteuern wie einen normalen Host im Netzwerk, Sie senden nur nicht auf dieses Ziel wie 192.168.1.101 um einen Computer zu erreichen, sondern an eine Gruppe wie z.B. 239.0.100.50 und je nachdem wo das landet kann man dort einfach auf dieser Quelle lauschen. Oder auch dorthin senden.
Dafür schreibt das Netzwerk sogenannte IGMP-Nachrichten mit, diese teilen dem Netzwerk mit, welchen Gruppen Sie beitreten wollen und der Verkehr landet dann auch mit bei Ihnen.
Denn standardmässig landet jeder Multicast-Traffic überall und das macht auch Sinn, denn z.B. mDNS für UPNP kann nicht wissen, ob ein TV nach den Diensten fragt.
224.0.0.0 - 224.0.0.255 Link-local multicast (reserved for routing protocols, never routed beyond local network)
+ 224.0.0.106 ist z.B. mDNS
224.0.1.0 - 224.0.1.255 Internetwork control (can be routed, used for protocols like NTP)
224.1.0.0 - 238.255.255.255 Public multicast (IANA assigned for specific applications, but mostly unused)
239.0.0.0 - 239.255.255.255 Private multicast (recommended for local use, never routed on the internet)
+ 239.0.100.50 nutzen wir in unserem Beispiel für RTP-Musik
+---------+---------+---------+---------+---------+---------+---------+---------+
| |
| +---------+ + |
| |10.0.0.2 | | |
| |openwrt | | |
| | | | |
| +---------+ +--------- |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
+---------+---------+---------+---------+---------+---------+---------+---------+
Wir fangen einfach an: 1 Switch (das kann ihr Router sein) hat 2 Geräte angeschlossen. Ein Server sendet auf die Gruppe 224.0.10.10 und eine Workstation am selben Switch möchte diesen Traffic als Musik ausgeben.
Das sollte auch sofort funktionieren. Ein kleines Python-Skript was uns später auch TTL-Anpassungen testen lässt:
import socket
import struct
import time
# Multicast group and port
MCAST_GROUP = '224.0.10.10'
MCAST_PORT = 5007
# Create a socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
# Set the time-to-live for the multicast packets
ttl = struct.pack('b', 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
# Send multicast packets in a loop
while True:
message = b"Test multicast message"
sock.sendto(message, (MCAST_GROUP, MCAST_PORT))
print("Sent message:", message)
time.sleep(1) # Adjust the interval as needed
als multicast.py abspeichern.
root@sender:~# python3 multicast.py
Auf dem client sollte das schon ankommen:
root@client:~# tcpdump -i eno0 -n dst 224.0.10.10 and udp and multicast
14:14:14.123456 IP 10.10.1.1.46792 > 224.0.10.10.5007: UDP, length 22
Das Problem mit WLAN ist, dass ein Router der Multicast an alle Geräte weiterverteilt bei WLAN nur jeden Client einzeln versorgen kann. Das bedeutet bei 3-4 Geräten ist das WLAN schnell ausgelastet und zudem würden die Clients den Traffic ohnehin verwerfen.
Wenn Ihr Router also WLAN und LAN im selben Netzwerk hält haben Sie jetzt schon das Problem, dass jeder Traffic an jeden Client weitergeleitet wird
IGMP Snooping bedeutet 1:1 übersetzt: Schnüffel alle Internet-Gruppen-Nachrichten mit damit Du Multicast-Traffic doch routen kannst. Denn obwohl wir hier keine Ziel-IP kennen können wir uns ja merken welcher Client gern welcher Gruppe lauschen würde.
Dazu gibt es 4 Rollen:
Multicast Router - das ist der Router der den Multicast-Traffic verwaltet indem er regelmässig IGMP-Nachrichten neu sendet welcher Client welche Gruppe hören will.
Multicast Switch - ist der Switch oder die Netzwerk-Brücke (für WLAN-z.B. oder das virtuelle LAN-Interface bei OpenWRT) der diese IGMP-Nachrichten mitschreibt und sich merkt welcher Hardware-Port diese bekommen soll (oder welcher WLAN-Client). Das ist also wie bei Hardware-Port --> MAC, nur halt für Multicast-Gruppe --> MAC.
Multicast Client - das ist das Zielgerät welches den Traffic zugeschoben bekommt. Dafür muss der Client u.U. IGMP-Nachrichten senden.
Multicast Server - der sendet stupide auf seinem Netzwerk-Interface auf eine Multicast-Gruppe und KEINE IGMP-Nachrichten (nicht mit Pings verwechseln, das ist ICMP!). Alle Weiterverteilung ist Sache des Netzwerks.
IGMP-Snooping macht also immer nur der Switch. IGMP-Nachrichten sendet ein Interessent, aber auch der Multicast-Router.
Ihr OpenWRT-Router hat i.d.R. 3 Switche: Den Hardware-Switch, eine Brücke für LAN und eine für WLAN. Fangen wir mit dem Hardware-Switch an:
root@openwrt:~# swconfig dev switch0 show
Global attributes:
enable_vlan: 1
ar8xxx_mib_poll_interval: 0
ar8xxx_mib_type: 0
enable_mirror_rx: 0
enable_mirror_tx: 0
mirror_monitor_port: 0
mirror_source_port: 0
arl_age_time: 300
arl_table: address resolution table
Port 0: MAC f4:f2:6d:xx:xx:xx <-- das ist CPU/eth0 am Router
Port 0: MAC b8:4d:43:xx:xx:xx -- daher sind alle andern MACs hier --
Port 0: MAC 24:68:b0:xx:xx:xx -- hier auch über Port 0 zu erreichen --
Port 0: MAC 26:c5:9e:xx:xx:xx -- können aber auch WLAN-Clients sein --
Port 0: MAC 44:4f:8e:xx:xx:xx
Port 1: MAC d8:9e:f3:xx:xx:xx <-- das ist eine Firewall/DSL-Modem am WAN-Port
Port 2: MAC 26:11:de:xx:xx:xx <-- das ist der Sender / Server an LAN-Port 1
Port 4: MAC 26:11:de:xx:xx:xy <-- das ist der Empfänger / Client an LAN-Port 3
igmp_snooping: 0
igmp_v3: 0
Port 0:
mib: ???
enable_eee: ???
igmp_snooping: 0
vlan_prio: 0
pvid: 0
link: port:0 link:up speed:1000baseT full-duplex txflow rxflow
Port 1:
mib: ???
enable_eee: 0
igmp_snooping: 0
vlan_prio: 0
pvid: 1
link: port:1 link:up speed:1000baseT full-duplex eee100 eee1000 auto
Port n: ...
Wir konzentrieren uns jetzt nur darauf, dass der Traffic vom Sender erst beim Clienten landet wenn dieser auch derselben Multicast-Gruppe beigetreten ist.
Openwrt: In /etc/config/network
(geht nicht im WebGUI LuCI) fügen wir Unterstützung für IGMP-Snooping und IGMP v3 ein:
config switch
option name 'switch0'
option reset '1'
option enable_vlan '1'
option igmp_snooping '1'
option igmp_v3 '1'
Ein /etc/init.d/network restart
und schon sollte erstmal Ruhe auf dem Multicast-Clienten sein.
root@central:~# swconfig dev switch0 show
Global attributes:
enable_vlan: 1
.
.
.
igmp_snooping: 1 <-- besser
igmp_v3: 1 <-- für später
Warum ist jetzt Stille? Nun der Switch hat keine Ahnung, dass Sie diesen Traffic haben wollen! Linux hat das Tool smcroute
damit können Sie jetzt testweise wieder der Gruppe beitreten:
root@client:~# smcroutectl join eno0 224.0.10.10
root@caelus:~# tcpdump -i eno0 -n dst 224.0.10.10 and udp and multicast
15:55:30.838367 IP 10.126.1.1.46792 > 224.0.10.10.5007: UDP, length 22
15:55:31.838575 IP 10.126.1.1.46792 > 224.0.10.10.5007: UDP, length 22
...
Und schon kommt auch wieder Traffic. Wie Sie sehen war unnötig den Sender neu zu starten - das wird bei Audio noch praktisch und wichtig.
Wenn Sie das jetzt 10 Minuten laufen lassen wird der Traffic wieder abbrechen. Ultra nervig zu debuggen wenn man nicht weiß was hier gerade passiert: Der Switch "vergisst" das nämlich in regelmässigen Abständen, damit Clients die keine "Leave"-Nachricht senden, also der Gruppe nicht explizit wieder austreten nicht unnötig weiter bespielt werden.
Wer sorgt nun dafür, dass wir auch bei Neustart des Switches wieder in die Gruppe kommen? (KOMM IN DIE GRUPPE!!!) Denn den Clienten jedesmal neu zu starten ist für Audio wirklich Mist.
Diese Rolle übernimmt
Openwrt: /etc/config/network
oder in LuCI Network --> Interfaces --> (Tab) Devices
Hier vermischt sich gern was Server und Client ist, daher einfach erklärt: SSDP sendet auf die Multicast-Gruppe 239.255.255.250 und zwar sowohl alle TVs die gern UPnP schauen wollen wie auch die Dienste die UPnP anbieten. Daher können Sie einfach als UPnP-Server und Client derselben Multicast-Gruppe beitreten und werden keine Infos doppelt / periodisch senden müssen. Ein TV sendet genauso in die Multicast-Gruppe was so vorhanden ist und alle Dienste und andere Clienten sehen das und senden zurück was Sie anzubieten haben.
Das hat also nix mit Multicast-Daten wie IPTV oder RTP-Musik zu tun - diese ist zwar Multicast, aber in UPnP ist nur das Dienste-finden Multicast, alle Dienste selbst können stinknormales Unicast-TCP sein (Videos vom Server gucken z.B.) oder Multicast (TV-Sender oder zentrale Musik hören).
Alle Clienten und Server senden Multicast auf 239.255.255.250 was so im LAN vorhanden ist. Die TTL ist hier mit 4 großzügig, da das nur minimale Informationen über Quellen und Empfänger sind.
Ist nur ein Framework zum Abspielen und Anbieten von Medien, die können aber 1:1 unicast sein. Ein Video in ihrer lokalen Mediathek ist i.d.R. ein einfacher http-link.
Hier erhält man i.d.R. für jeden Sender eine Multicast-Gruppe. Eine Übersicht für die Telekom gibt es hier: https://iptv.blog/artikel/multicastadressliste/. Da ich das nicht nutze kann ich zur TTL nix sagen, evtl. schaltet man mir das mal gratis für Testzwecke frei.
Hier senden wir lokal unseren Heim-Radiosender (können auch mehrere aufmachen) oder z.B. Bild von Überwachungskameras. Das ist wie bei IPTV immer eine Gruppe pro Sender. Bei uns lokal ist der TTL i.d.R. bei 1
Das brauchen Sie vorallem für IPTV - hier kann der Client zusätzlich zur Multicast-Gruppe noch mit angeben wer auf diese Gruppe senden soll, d.h. explizit nur (Sender + Gruppe) --> Client und nicht nur Gruppe --> Client
In OpenWRT können das manchmal software-bridges nicht korrekt, wir aktivieren es aber wo immer möglich.
TTL ist ein Layer 3 Wert der angibt nach wie vielen Hops (d.h. ein Router muss das Paket auf irgendeine Weise weiterleiten) das Paket verworfen wird. Angenommen Sie routen vom Internet zum LAN über eine Firewall --> +1 Hop. LAN-Server zu LAN-Client --> 0 Hops.
Ein Layer-2 Switch macht das daher nicht, also keine Bange - korrekt konfiguriert kann der TTL auf 1 bleiben und es geht trotzdem über WLAN.
Auf ALLEN Switches im Netzwerk sollte IGMP Snooping angeschaltet werden, das erlaubt den Switchen sich zu merken wohin Multicast-Traffic gesendet werden soll und lässt alle anderen Ports in Frieden.
opkg update && opkg install igmpproxy
/etc/config/network
config device
option name 'br-lan'
option type 'bridge'
list ports 'eth1.1'
option stp 1 # <-- verhindert bridge-loops
option igmp_snooping 1 # <-- brauchen wir für RTP
option multicast_querier 1 # <-- das auf 1 für den Haupt-AP bei WDS, 0 für alle anderen
Das gleiche auch bei Bridges für Gäste-WLAN setzen!
Das stellt sicher, dass nur 1 AP sich alle Multicast-Gruppen und Subscriptions merkt (multicast_querier = 1)
Damit ist schonmal sichergestellt, dass Multicast-Traffic nur bei Clienten im WLAN, etc. landet die den auch angefragt haben.
Wer es jetzt noch ultra exakt nehmen will (und wer will das nicht) stellt noch für die in den Routern verbauten LAN-Switche IGMP Snooping ein:
swconfig dev switch0 show swconfig dev switch0 set igmp_snooping 1
Denn sonst hat man auf einem Clienten der am selben Hardware-Switch wie der Sender hängt immer Traffic auch ohne subscribed zu sein.
tcpdump -i any port 5004
Zeigt sehr gut an ob man Musik auch empfängt obwohl keiner Multicast-Gruppe beigetreten wurde.
/etc/config/network
später