3
votes

I could not find a working example for this, so I am going to post a question (and let's see if I can reduce this to an MVP code example). So, I need to do mdns queries, I can use two sockets (one for sending / second for receiving) but so far I have not been able to make it work with a single socket.

So the steps that I am performing are:

Enumerate all the interface addresses on the host. Then for each host:

  1. Create a non blocking UDP socket
  2. bind() to either the interface address:5353 or the multicast group address (either of these cause either read or write to fail)
  3. Set IP_MULTICAST_IF to the local interface
  4. IP_ADD_MEMBERSHIP to the multicast group
  5. Add the sockets for read/write in kqueue

So depending on what I do in step 2 either read or write fails:

  1. If I bind the socket to the multicast group I get read notifications from the kqueue and can read packets, but when I get a write notification from the kqueue and try to write it fails with errno 49
  2. If I bind the socket to the interface address I can send the packets but no read notifications ever arrive from the kqueue

So which address I need to bind to then? Also, since the IP_ADD_MEMBERSHIP parameter ip_mreq has the interface field, do I really need the IP_MULTICAST_IF?

1

1 Answers

5
votes

If you bind to a specific interface address (on Linux at least), you'll be unable to receive multicast. If you bind to a multicast address, you can't send.

What you need to do is bind to INADDR_ANY, then when you set the IP_ADD_MEMBERSHIP option, you set the interface address that you want to receive multicast packets on. If you have multiple interfaces, you can call this for each interface you want to bind to.