UDP recvfrom not successful

I am trying to write DHCP client, but failing to receive the DHCP Offer due to "Resource temporarily unavailable" on recvfrom(). I set my socket like so (leaving out the checks for return values):

    int sct = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    return sct;
    /* set option for socket to broadcast */
    int opt_val = 1;    
    int res = setsockopt(sct, SOL_SOCKET, SO_REUSEADDR, (char *)&opt_val, sizeof(opt_val));    
    res = setsockopt(sct, SOL_SOCKET, SO_BROADCAST, (char *)&opt_val, sizeof(opt_val));

Then I bind to the socket to the interface and then the actuall bind itself. All success. Then I send DHCP Discover with sucess and I fail to catch DHCP Offer. Shows up in WIreshark. Receiving the packet like so:

struct sockaddr_in srcInfo;
struct timeval t_out;
t_out.tv_usec = timeout * 10000; // 50 ms timeout
t_out.tv_sec = 0;
socklen_t sockSize = sizeof(srcInfo);
int setSc = setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&t_out, sizeof(struct timeval));
ssize_t res = recvfrom(socket, (void*)buffer, sizeof(DHCP_hdr), 0, (struct sockaddr *)&srcInfo, &sockSize);

The res var is always -1 and the error is as written above. I have tried everything that is here on SO - no success. Using FD_SET with FD_ISSET. Setting the socket as nonblocking, calling recvfrom right after that again. Always getting the same error.

1 answer

  • answered 2018-03-07 20:01 user58697

    "Resource temporarily unavailable" corresponds to EAGAIN. The Errors section of man recvfrom says that EAGAIN is set if:

    a receive timeout had been set, and the timeout expired before data were received.

    Your timeout seems to be too short.

    According to RFC 1541, the client may retransmit the discover message no sooner than 4 seconds after the initial message has been transmitted. It implies that a reasonable timeout shall be in that ballpark.