UDP socket bind fail after returning from suspened state

For UDP socket creating and binding we are using below:

bool UDPSocket::Create()
{
  int retval = 0;
  struct timeval sTime;
  sTime.tv_sec = 0;
  sTime.tv_usec = 100000;
  if (mstLocalAddr.m_bIsIPV6)
    mSockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
  else
    mSockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (mSockfd == -1) {
    MLog("Socket create failed, errno: %d", errno);
    return false;
  }
   
  if (setsockopt(mSockfd, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast<char*>(&sTime), sizeof(struct timeval)) != 0) {
    MLog("Socket setsockopt() failed");
    return false;
  }

  if (mstLocalAddr.m_bIsIPV6) {
    retval = bind(mSockfd, (struct sockaddr*)&(mstLocalAddr.u.m_stIPV6Addr), sizeof(sockaddr_in6));
  } else {
    retval = bind(mSockfd, (struct sockaddr*)&(mstLocalAddr.u.m_stIPV4Addr), sizeof(sockaddr_in));
  }
  if (retval != 0) {
	printf("Socket Bind failed:%d", errno); 
    return false;
  }
  MLog("Socket Create and Bind success");
  return true;
}

Normally it works fine, but sometimes in the suspended state of the application when we try to create and bind socket on a certain port lets say 6355, mSockfd and setsockopt was successful, but bind return socket error[49] - Can't assign requested address.

Network Interface is pdp_ip0 or utunX and active, and through that interface other traffic like HTTP, SIP is working fine after coming back from the suspended state. Only problem is sometimes udp socket bind is getting failed.

Instead of using BSD sockets, try taking a look at NWConnection or nw_connection_t. The advantage this would give you over BSD Sockets it that when your app comes back into the foreground you can check the NWConnection.State so that you know when you need to re-establish your connection or if it is viable for usage.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
UDP socket bind fail after returning from suspened state
 
 
Q