netutils/dhcpc:receiving unexpected packet not leading to dhcp retry.

Signed-off-by: 田昕 <tianxin7@xiaomi.com>
This commit is contained in:
田昕 2022-09-07 15:29:26 +08:00 committed by Xiang Xiao
parent 3837091582
commit 21e1ef11da

View File

@ -680,6 +680,7 @@ int dhcpc_request(FAR void *handle, FAR struct dhcpc_state *presult)
uint8_t msgtype; uint8_t msgtype;
int retries; int retries;
int state; int state;
clock_t start;
/* RFC2131: For example, a client may choose a different, /* RFC2131: For example, a client may choose a different,
* random initial 'xid' each time the client is rebooted, and * random initial 'xid' each time the client is rebooted, and
@ -730,43 +731,49 @@ int dhcpc_request(FAR void *handle, FAR struct dhcpc_state *presult)
/* Get the DHCPOFFER response */ /* Get the DHCPOFFER response */
result = recv(pdhcpc->sockfd, &pdhcpc->packet, start = clock();
sizeof(struct dhcp_msg), 0); do
if (result >= 0)
{ {
msgtype = dhcpc_parsemsg(pdhcpc, result, presult); result = recv(pdhcpc->sockfd, &pdhcpc->packet,
if (msgtype == DHCPOFFER) sizeof(struct dhcp_msg), 0);
if (result >= 0)
{ {
/* Save the servid from the presult so that it is not msgtype = dhcpc_parsemsg(pdhcpc, result, presult);
* clobbered by a new OFFER. if (msgtype == DHCPOFFER)
*/ {
/* Save the servid from the presult so that it is not
* clobbered by a new OFFER.
*/
ninfo("Received OFFER from %08" PRIx32 "\n", ninfo("Received OFFER from %08" PRIx32 "\n",
(uint32_t)ntohl(presult->serverid.s_addr)); (uint32_t)ntohl(presult->serverid.s_addr));
pdhcpc->ipaddr.s_addr = presult->ipaddr.s_addr; pdhcpc->ipaddr.s_addr = presult->ipaddr.s_addr;
pdhcpc->serverid.s_addr = presult->serverid.s_addr; pdhcpc->serverid.s_addr = presult->serverid.s_addr;
/* Temporarily use the address offered by the server /* Temporarily use the address offered by the server
* and break out of the loop. * and break out of the loop.
*/ */
netlib_set_ipv4addr(pdhcpc->interface, netlib_set_ipv4addr(pdhcpc->interface,
&presult->ipaddr); &presult->ipaddr);
state = STATE_HAVE_OFFER; state = STATE_HAVE_OFFER;
}
}
/* An error has occurred. If this was a timeout error (meaning
* that nothing was received on this socket for a long period
* of time). Then loop and send the DISCOVER command again.
*/
else if (errno != EAGAIN)
{
/* An error other than a timeout was received -- error out */
return ERROR;
} }
} }
while (state == STATE_INITIAL && TICK2MSEC(clock() - start) <
/* An error has occurred. If this was a timeout error (meaning CONFIG_NETUTILS_DHCPC_RECV_TIMEOUT_MS);
* that nothing was received on this socket for a long period
* of time). Then loop and send the DISCOVER command again.
*/
else if (errno != EAGAIN)
{
/* An error other than a timeout was received -- error out */
return ERROR;
}
} }
while (state == STATE_INITIAL && while (state == STATE_INITIAL &&
retries < CONFIG_NETUTILS_DHCPC_RETRIES); retries < CONFIG_NETUTILS_DHCPC_RETRIES);
@ -804,67 +811,70 @@ int dhcpc_request(FAR void *handle, FAR struct dhcpc_state *presult)
/* Get the ACK/NAK response to the REQUEST (or timeout) */ /* Get the ACK/NAK response to the REQUEST (or timeout) */
result = recv(pdhcpc->sockfd, &pdhcpc->packet, start = clock();
sizeof(struct dhcp_msg), 0); do
if (result >= 0)
{ {
/* Parse the response */ result = recv(pdhcpc->sockfd, &pdhcpc->packet,
sizeof(struct dhcp_msg), 0);
msgtype = dhcpc_parsemsg(pdhcpc, result, presult); if (result >= 0)
/* The ACK response means that the server has accepted
* our request and we have the lease.
*/
if (msgtype == DHCPACK)
{ {
ninfo("Received ACK\n"); /* Parse the response */
state = STATE_HAVE_LEASE;
msgtype = dhcpc_parsemsg(pdhcpc, result, presult);
/* The ACK response means that the server has accepted
* our request and we have the lease.
*/
if (msgtype == DHCPACK)
{
ninfo("Received ACK\n");
state = STATE_HAVE_LEASE;
}
/* NAK means the server has refused our request */
else if (msgtype == DHCPNAK)
{
ninfo("Received NAK\n");
return ERROR;
}
/* If we get any OFFERs from other servers, then decline
* them now and continue waiting for the ACK from the server
* that we requested from.
*/
else if (msgtype == DHCPOFFER)
{
ninfo("Received another OFFER, send DECLINE\n");
dhcpc_sendmsg(pdhcpc, presult, DHCPDECLINE);
}
/* Otherwise, it is something that we do not recognize */
else
{
ninfo("Ignoring msgtype=%d\n", msgtype);
}
} }
/* NAK means the server has refused our request. Break out of /* An error has occurred. If this was a timeout error (meaning
* this loop with state == STATE_HAVE_OFFER and send DISCOVER * that nothing was received on this socket for a long period of
* again * time). Then break out and send the DISCOVER command again
* (at most 3 times).
*/ */
else if (msgtype == DHCPNAK) else if (errno != EAGAIN)
{ {
ninfo("Received NAK\n"); /* An error other than a timeout was received */
break;
}
/* If we get any OFFERs from other servers, then decline netlib_set_ipv4addr(pdhcpc->interface, &oldaddr);
* them now and continue waiting for the ACK from the server return ERROR;
* that we requested from.
*/
else if (msgtype == DHCPOFFER)
{
ninfo("Received another OFFER, send DECLINE\n");
dhcpc_sendmsg(pdhcpc, presult, DHCPDECLINE);
}
/* Otherwise, it is something that we do not recognize */
else
{
ninfo("Ignoring msgtype=%d\n", msgtype);
} }
} }
while (state == STATE_HAVE_OFFER && TICK2MSEC(clock() - start) <
/* An error has occurred. If this was a timeout error (meaning CONFIG_NETUTILS_DHCPC_RECV_TIMEOUT_MS);
* that nothing was received on this socket for a long period of
* time). Then break out and send the DISCOVER command again
* (at most 3 times).
*/
else if (errno != EAGAIN)
{
/* An error other than a timeout was received */
netlib_set_ipv4addr(pdhcpc->interface, &oldaddr);
return ERROR;
}
} }
while (state == STATE_HAVE_OFFER && while (state == STATE_HAVE_OFFER &&
retries < CONFIG_NETUTILS_DHCPC_RETRIES); retries < CONFIG_NETUTILS_DHCPC_RETRIES);