'error "address already in use" with ipv6 udp server socket

Hello dear colleagues,

I need some hints/ideas for troubleshooting.

My programme runs in two instances. Each instance has its own network interface (eth0 and eth1). Both interfaces are using IPv6 internet addresses due to this is prescribed by a standard (for our application).

The problem: if instance 1 or instance 2 is running, my application runs through without any issues. When both applications are started at the same time, one of both instances crashes. I catch the signal and get the message

Address already in use

For my, it doesn't make sense. I open two different sockets, one for each interface. But proof my wrong. Maybe I understood the IPv6 parameter sin6_scope_id wrong. In addition, the usage of in6addr_any for IPv6 - doesn't it equal behave to INADDR_ANY of IPv4?

In this programme I open the following udp socket:

socketDescriptor_ = socket(AF_INET6, SOCK_DGRAM, htons(PC_UNSPEC));

As well I added some socket options:

   bool UDPSocket::AddSocketOptions2UDPSocket() {
      int optval = 1;
    
      if (setsockopt(socketDescriptor_, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
         return false;
      }
    
      struct timeval sdpTimeout {};
         sdpTimeout.tv_sec = 18;
         sdpTimeout.tv_usec = 0;
    
    
      if (setsockopt(socketDescriptor_, SOL_SOCKET, SO_RCVTIMEO, (void *) &sdpTimeout, sizeof(sdpTimeout)) < 0) {
         return false;
      }
      return true;
   }

After that, I construct the address descriptor before I bind the socket. For the address descriptor (method returns object descriptor) I wrote two solutions meanwhile:

1.)

descriptor.addressDescriptorIPv6.sin6_family = AF_INET6;
descriptor.addressDescriptorIPv6.sin6_addr = in6addr_any;
descriptor.addressDescriptorIPv6.sin6_port = htons(portNumber);
descriptor.addressDescriptorIPv6.sin6_scope_id = if_nametoindex(interfaceName_.c_str());

2.)

descriptor.addressDescriptorIPv6.sin6_family = AF_INET6;
inet_pton(AF_INET6,IPAddress.c_str(AF_INET6, &descriptor.addressDescriptorIPv6.sin6_addr);
descriptor.addressDescriptorIPv6.sin6_port = htons(portNumber);
descriptor.addressDescriptorIPv6.sin6_scope_id =
            if_nametoindex(interfaceName_.c_str());

The binding looks as follows:

if (bind(socketDescriptor_, (struct sockaddr *) &localSocketAddressDescriptor_, sizeof(localSocketAddressDescriptor_)) < 0) {
        connected_ = false;
        return false;
    } else {
        connected_ = true;
        return true;
    }

Additionally, I tried to bind the socket to a specific network device with further socket options:

setsockopt(socketDescriptor_,
           SOL_SOCKET,
           SO_BINDTODEVICE,
           interfaceName_.c_str(),
           sizeof(interfaceName_.c_str()) < 0);

Thanks for any help!

Kind regards, Matthias



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source