-2

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.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Croolman
  • 1,103
  • 13
  • 40
  • Depending on the platform, after a socket function returns an error, there's usually another global variable value, such as `err` or `errno`, or a function to call, such as `WSAGetLastError()`, which has a specific error code. – Dan Korn Mar 07 '18 at 18:17
  • `sizeof(DHCP_hdr)` is this large enough for a complete reply packet ? – wildplasser Mar 07 '18 at 18:17
  • @wildplasser yes it is, it is, exactly 590 bytes – Croolman Mar 07 '18 at 18:37
  • @DanKorn yep,"Resource temporarily unavailable" is a human redable form of the `errno` after unsuccessful `recvfrom()` – Croolman Mar 07 '18 at 18:39
  • What is the value for errno? I mean EAGAIN, EBADF, EINTR, etc... –  Mar 07 '18 at 20:02
  • @AlejandroVisiedo value 11, EAGAIN – Croolman Mar 07 '18 at 20:35
  • Any firewall rule that can be filtering the traffic before it arrive to your application? If you are using some firewall, test to disable it. –  Mar 07 '18 at 20:39
  • 10,000 μS is not '50mS', it is *ten* milliseconds, and both ten mS and 50mS are far too short for a network timeout. It should be measured in seconds, if not tens of seconds. – user207421 Mar 07 '18 at 22:56
  • @EJP timeout is 5 thats why it is 50ms in total. The fact is - when I try to set timeout higher than 2 secons, the `setsockopt()` fails to do so. (returns -1) – Croolman Mar 08 '18 at 07:27

1 Answers1

1

"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.

Community
  • 1
  • 1
user58697
  • 7,808
  • 1
  • 14
  • 28
  • The timeout is sufficient, since acc to wireshark, the offer is sent in 25ms. I did raise the timeout anyway, but it doesnt help – Croolman Mar 07 '18 at 20:33
  • 2
    @Coolman The error you are getting does not agree with you. You are arguing with the error itself. – user207421 Mar 07 '18 at 22:59
  • At the end the reason why it threw the error was that some other application was already catching all the responses. – Croolman Mar 14 '18 at 06:55