What does it mean to bind a multicast socket (UDP)?

I use multicast UDP between hosts that have multiple network interfaces. I am using boost :: asio and I am confused by the two operations the recipients have to do: bind and then join-group.

Why do you need to provide a local interface address during bind when you do this with every multicast group that you join?

The question with my sister is about the multicast port: since you send to the address and the multicast port during sending, why only the address is indicated during the subscription to the multicast group, and not the port - the port specified in the tangled call for binding.

Note. "join-group" is a shell on top of setsockopt(IP_ADD_MEMBERSHIP) that, as documented, can be called several times on the same socket to subscribe to different groups (on different networks?). Therefore, it would be wise to refuse the call to bind and specify the port every time I subscribe to a group.

From what I see, it always binds to "0.0.0.0" and indicates the interface address when joining a group, it works very well. Confused

+54
udp multicast sockets boost-asio bind
May 21 '12 at 21:33
source share
4 answers

To bind a UDP socket when receiving multicast, specify the address and port from which you can receive data (NOT the local interface, as is the case for binding the TCP acceptor). The address specified in this case is filtered , i.e. A socket will only accept datagrams sent to this multicast address and port, regardless of which groups the socket subsequently joins. This explains why when binding to INADDR_ANY (0.0.0.0) I received datagrams sent to my multicast group, while when binding to any of the local interfaces I didn’t receive anything, even though the datagrams were sent to the network, to by which this interface corresponded.

Quote from UNIX® Network Programming Volume 1, Third Edition: Sockets WR Stevens Network Interface. 21.10. Sending and receiving

[...] We want the receiving socket to bind the multicast group and port, say, 239.255.1.2 port 8888. (Recall that we could just bind the wildcard IP address and port 8888, but tying the multicast address does not allow the socket receive any other datagrams that may come for port 8888.) Then we want the receiving socket to join the multicast group. The transmitting socket will send datagrams to the same multicast address and port, say, 239.255.1.2 port 8888.

+51
May 24 '12 at 14:25
source share

The bind operation basically says: “Use this local UDP port to send and receive data. In other words, it allocates this UDP port for exclusive use for your application. (The same is true for TCP sockets).

When you bind to "0.0.0.0" (INADDR_ANY), you basically speak at the TCP / IP level to use all available adapters to listen to and choose the best adapter to send. This is standard practice for most socket codes. The only time you do not specify 0 for the IP address is when you want to send / receive over a specific network adapter.

Similarly, if you specify the value of port 0 during binding, the OS will assign a randomly available port number to this socket. Therefore, I would expect UDP to multicast, you bind to INADDR_ANY at the specific port number on which multicast traffic is expected to be sent.

The join multicast group operation (IP_ADD_MEMBERSHIP) is necessary because it basically tells the network adapter not only to listen on Ethernet frames, where the destination MAC address is your own, it also reports that the ethernet adapter (NIC) is listening on IP multicast traffic, as well as for the corresponding multicast Ethernet address. Each multicast IP address corresponds to an Ethernet multicast address. When you use socket sending to a specific multicast IP address, the destination MAC address in the ethernet frame is set to the corresponding multicast MAC address for the multicast IP address. When you join a multicast group, you configure the network adapter to listen for traffic sent to the same MAC address (in addition to its own).

Without hardware support, multicasting will not be more efficient than regular broadcast IP messages. The connection operation also tells your router / gateway to forward multicast traffic from other networks. (Does anyone remember MBONE?)

If you join a multicast group, all network traffic for all ports on this IP address will be received by the NIC. Only traffic destined for your connected listening port will be transferred by the TCP / IP stack to your application. As to why the ports are indicated during multicast subscription - this is because the multicast IP address is only the IP address. "ports" is a property of the upper protocols (UDP and TCP).

You can learn more about how multicast IP addresses are mapped to Ethernet multicast addresses at different sites. The Wikipedia article is about as good:

IANA owns the OUI MAC address 01: 00: 5e, so multicast packets are delivered using the Ethernet MAC address range 01: 00: 5e: 00: 00: 00 - 01: 00: 5: 7f: ff: ff. This is 23 bits of available address space. The first octet (01) enables broadcast / multicast a bit. The lower 23 bits of the 28-bit multicast IP address are mapped to 23 bits of the available Ethernet address space.

+41
May 22 '12 at 4:00
source share

Fix for What does multicast (udp) socket binding mean? until it is partially true with the following quote:

The bind operation basically says: “Use this local UDP port to send and receive data. In other words, it allocates this UDP port for exclusive use for your application

There is one special case. Several applications can share the same port for listening (this is usually practical for multicast datagrams) if the SO_REUSEADDR option is used:

 int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // create UDP socket somehow ... int set_option_on = 1; // it is important to do "reuse address" before bind, not after int res = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &set_option_on, sizeof(set_option_on)); res = bind(sock, src_addr, len); 

If several processes performed such a "reuse binding", then each UDP datagram received on this common port will be delivered to each of the processes (providing natural co-traffic with multicast traffic).

a) any attempt to bind (“exclusive” or “reuse”) to a free port will succeed

b) an “exclusive bind” attempt fails if the port is already “bind to reuse”

c) the attempt to “reuse the binding” will fail if some process retains the “exclusive binding”

+8
Jan 30 '13 at 20:57
source share

It is also very important to distinguish SENDING multicast juice from RECEIVING multicast socket.

I agree with all of the above answers regarding RECEIVING multicast sockets. OP noted that binding RECEIVING skt to the interface did not help. However, you must bind the multicast SENDING socket to the interface.

For SENDING a multicast socket on a multi-homed server, it is very important to create a separate socket for each interface that you want to send. An associated SENDING skt must be created for each interface.

  // This is a fix for that bug that causes Servers to pop offline/online. // Servers will intermittently pop offline/online for 10 seconds or so. // The bug only happens if the machine had a DHCP gateway, and the gateway is no longer accessible. // After several minutes, the route to the DHCP gateway may timeout, at which // point the pingponging stops. // You need 3 machines, Client machine, server A, and server B // Client has both ethernets connected, and both ethernets receiving CITP pings (machine A pinging to en0, machine B pinging to en1) // Now turn off the ping from machine B (en1), but leave the network connected. // You will notice that the machine transmitting on the interface with // the DHCP gateway will fail sendto() with errno 'No route to host' if ( theErr == 0 ) { // inspired by 'ping -b' option in man page: // -b boundif // Bind the socket to interface boundif for sending. struct sockaddr_in bindInterfaceAddr; bzero(&bindInterfaceAddr, sizeof(bindInterfaceAddr)); bindInterfaceAddr.sin_len = sizeof(bindInterfaceAddr); bindInterfaceAddr.sin_family = AF_INET; bindInterfaceAddr.sin_addr.s_addr = htonl(interfaceipaddr); bindInterfaceAddr.sin_port = 0; // Allow the kernel to choose a random port number by passing in 0 for the port. theErr = bind(mSendSocketID, (struct sockaddr *)&bindInterfaceAddr, sizeof(bindInterfaceAddr)); struct sockaddr_in serverAddress; int namelen = sizeof(serverAddress); if (getsockname(mSendSocketID, (struct sockaddr *)&serverAddress, (socklen_t *)&namelen) < 0) { DLogErr(@"ERROR Publishing service... getsockname err"); } else { DLog( @"socket %d bind, %@ port %d", mSendSocketID, [NSString stringFromIPAddress:htonl(serverAddress.sin_addr.s_addr)], htons(serverAddress.sin_port) ); } 

Without this fix, multicast will periodically receive sendto () errno "No host route." If someone can shed some light on why disconnecting a DHCP gateway causes Mac OS X multicast SENDING sockets to get confused, I'd love to hear that.

+4
Apr 08 '15 at 23:08
source share



All Articles