netutils/dhcpc:receiving unexpected packet not leading to dhcp retry.
Signed-off-by: 田昕 <tianxin7@xiaomi.com>
This commit is contained in:
parent
3837091582
commit
21e1ef11da
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user