"When I first start up my XXX device / service it works fine; all the devices can see it. But after a certain time, XXX disappears. Other devices cannot see it."
To explain the problem we need a little background on IP multicast and IGMP snooping.
Multicast was designed for delivering high-bandwidth data streams, across a network without overloading the network.
Multicast avoids this problem by providing a way for a single stream to be delivered to many subscribers. The outgoing stream is directed to a single multicast address belonging to a "multicast group". When a router receives the packets of such a stream on an upstream port, it sends a copy to each of its downstream ports provided that some downstream node on that port has joined the multicast group. How does it know whether any downstream nodes belong to the group? That job is handled by the IGMP protocol.
But the bandwidth problem is not limited to routers. It also occurs with swithes on a local area network, especially when wireless is involved. If one person on your LAN is watching TV on their iPad, connected to a wireless access point which is connected to one port of your DNS or cable router, then your router needs to deliver the stream to the WAP. But the WAP is most likely behaving as a switch, not a router. So it is not supposed to be interpreting packets, just forwarding them to the devices connected to it. If this rule were followed strictly, it would mean that any device connected to that WAP would receive the video stream, even if it is not watching TV. And that video stream uses a substantial portion of the bandwidth available on the wireless link. So innocent devices who are not watching TV would experience a significant slowdown. To deal with this problem, switches use IGMP snooping. See the wikipedia article.
The idea of IGMP snooping is that a switch will watch the IGMP traffic generated by the devices it serves in order to decide which multicast groups each device wants to belong to. The switch then notifies its upstream router that it wants to subscribe to all groups which have at least one member among the nodes served by the switch. If no device on a switch port wants to belong to a certain group, then the switch will not forward any multicast packets for that group. A key point is this: while IGMP v2 provides a way for a device to leave a group, the switch cannot count on a device sending a leave request. First of all, the leave requests did not exist in IGMP v1, which the device may be using. Secondly, the device might crash. Therefore, a switch which does IGMP snooping will set an "IGMP membership timeout." When a device subscribes to a multicast group it must renew its membership before the timeout expires; otherwise the switch will mark it as not belonging to the group and stop sending it packets for that group.
To understand how to deal with this we need to discuss one more feature of the IGMP protocol and IGMP snooping. In order for your device to remain a member of a mcast group, it needs to periodically send a request (actually called a report in IGMP) to join the mcast group before the switch decides to remove it from the group. As explained in the Wikipedia page, the IGMP protocol deals with this by requiring that each network have a router which functions as an "IGMP querier". In order to avoid unnecessary network traffic, IGMP v2 specifies that this router should be "elected" by choosing the router with the lowest IP address. The job of the querier is simply to send an IGMP query packet to the multicast broadcast address (224.0.0.1) every so often. Switches are required to forward the query packets to all of their ports. When a device receives a query packet it responds (after a random delay and subject to a countdown timer) by sending reports requesting to join all groups that it wants to belong to.
Unfortunately, however, many cheap home network routers like the ones that you and I buy do not provide an IGMP querier. That is the reason that some UPnP services do not work on your home network.
The good news is that this problem is easy to fix. All we need to do is run a little daemon on one device which sends an IGMP query to the multicast broadcast address at regular intervals. QuerierD provides such a daemon. Once you start it up on one or more of your computers your devices will stop disappearing.
The querierd daemon will participate in the querier election process, so you can run querierd daemons on several devices on your network, some of which may not be running all the time. The querierd daemons will cooperate with any routers or other querierd daemons, so only one of them will provide the querier service at a time.
NOTE: A C implementation with similar functionality is available from Daniel Lorch: igmp-querier
Check out the releases page for a pre-built Debian package. Aimed at
ubuntu 20.04 and 22.04. Download the .deb and install with:
sudo apt install ./querierd-<version>.deb
To simplify the installation a Makefile is provided with QuerierD. To install QuerierD run following command:
sudo make install
To uninstall QuerierD run following command:
sudo make uninstall
There are two steps to installing QuerierD. First you need to install a python package named querier, as well as the package netifaces, which QuerierD uses.
If you have python setuptools installed, then the command
sudo python setup.py install
should install both packages, as needed. (Note, however, that installing netifaces may require a C compiler.) If you don't have setuptools you will need to install netifaces separately. Step 1 may or may not require superuser permissions, depending on how your python installation is configured.
Step 2 is to set up the querierd as a system service. This involves copying a couple of files into your system directories, and must be done as root. The details depend on your operating system. Here are the details:
Copy the service file to the systemd directory:
sudo cp lib/systemd/system/querierd.service /lib/systemd/system
- Don't forget to check the permissions!
- To change the IGMP broadcast interval add
-i <interval>to thequerierd.servicefile.
The Systemd service is now ready to be configured:
sudo systemctl daemon-reload
sudo systemctl start querierd.service
Wait a few seconds and check the status of the service:
sudo systemctl status querierd.service
After you have approved that everything works fine its time to enable the service to be started at boot:
sudo systemctl enable querierd.service
After starting the daemon by
$ sudo python -m querier.service
you can run tcpdump and watch the IGMP traffic:
$ sudo tcpdump -nv -ieth0 igmp
(replace eth0 by the appropriate interface on your computer).
$ watch bridge -d -s mdb show
Every 2.0s: bridge -d -s mdb show hypervisor: Sun Nov 26 19:59:26 2023
dev vmbr0 port tap100i0 grp 239.255.255.250 temp proto kernel 225.42
dev vmbr2 port tap109i0 grp 239.255.255.250 temp proto kernel 223.97
router ports on vmbr0: tap101i0 219.78 temp
router ports on vmbr2: tap110i0 208.79 temp