📄 dhcpcstate2.c
字号:
** This routine sends a timeout notification to the client monitor task when * the interval for receiving a server reply to a renewal request expires. It* is called at interrupt level by a watchdog timer. The monitor task will * eventually execute the RENEWING state to process the timeout event and* retransmit the DHCP request message.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void retrans_renewing ( LEASE_DATA * pLeaseData /* lease-specific status information */ ) { /* * Ignore the timeout if a state transition occurred * before processing completed. */ if (pLeaseData->currState != RENEWING) return; /* Construct and send a timeout message to the lease monitor task. */ dhcpcEventAdd (DHCP_AUTO_EVENT, DHCP_TIMEOUT, pLeaseData, TRUE); return; }/********************************************************************************* retrans_rebinding - signal when reception interval for rebind offer expires** This routine sends a timeout notification to the client monitor task when * the interval for receiving a lease offer from a different server expires. It* is called at interrupt level by a watchdog timer. The monitor task will * eventually execute the REBINDING state to process the timeout event and* retransmit the DHCP discover message.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void retrans_rebinding ( LEASE_DATA * pLeaseData /* lease-specific status information */ ) { /* * Ignore the timeout if a state transition occurred * before processing completed. */ if (pLeaseData->currState != REBINDING) return; /* Construct and send a timeout message to the lease monitor task. */ dhcpcEventAdd (DHCP_AUTO_EVENT, DHCP_TIMEOUT, pLeaseData, TRUE); return; }/********************************************************************************* retrans_reboot_verify - retransmission in rebooting state** This routine signals the DHCP client monitor task when the timeout interval * for receiving a server reply expires for the lease indicated by the * <pLeaseData> parameter. The client monitor task will pass the event to the * reboot_verify() routine in the finite state machine.* retrans_reboot_verify - signal when verification reception interval expires** This routine sends a timeout notification to the client monitor task when * the interval for receiving a server reply to a reboot (or verify) request * expires. It is called at interrupt level by a watchdog timer. The monitor * task will eventually execute the REBOOTING or VERIFYING state to process * the timeout event and retransmit the appropriate DHCP request message.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void retrans_reboot_verify ( LEASE_DATA * pLeaseData /* lease-specific status information */ ) { /* * Ignore the timeout if a state transition occurred * before processing completed. */ if (pLeaseData->currState != REBOOTING && pLeaseData->currState != VERIFYING) return; /* Construct and send a timeout message to the lease monitor task. */ dhcpcEventAdd (DHCP_AUTO_EVENT, DHCP_TIMEOUT, pLeaseData, TRUE); return; }/********************************************************************************* bound - Active state of client finite state machine** This routine contains the fourth state of the client finite state machine.* It accepts and services all user requests for BOOTP and infinite DHCP leases* throughout their lifetimes. For finite DHCP leases, it handles all processing* until one of the lease timers expires. At that point, processing continues * with the renewing() or rebinding() routines.* .IP* This routine is invoked by the event handler of the client monitor task,* and should only be called internally. Any arriving DHCP messages contain* stale offers or responses and are discarded. User requests generated* by calls to the dhcpcRelease() and dhcpcVerify() routines are accepted.** RETURNS: OK (processing complete), DHCPC_DONE (remove lease),* DHCPC_MORE (continue), or ERROR.** ERRNO: N/A** NOMANUAL*/int bound ( EVENT_DATA * pEvent /* pointer to event descriptor */ ) { int timeout; /* Epoch when intermediate lease timers expire. */ int limit; /* Epoch when lease expires. */ LEASE_DATA * pLeaseData; int status; time_t curr_epoch = 0; /* * Use the cookie to access the lease-specific data structures. For now, * just typecast the cookie. This translation could be replaced with a more * sophisticated lookup at some point. */ pLeaseData = (LEASE_DATA *)pEvent->leaseId; /* * Process events for BOOTP and infinite DHCP leases. Timeouts and * incoming messages should never occur for either type of lease. Also, * BOOTP leases require no special processing in response to user requests * for verification or shutdown. */ if (pLeaseData->dhcpcParam->lease_duration == ~0) { /* Ignore timeouts and received DHCP messages. */ if (pEvent->source != DHCP_AUTO_EVENT) { /* Process user requests. */ if (pEvent->type == DHCP_USER_RELEASE) /* Relinquish lease. */ { if (pLeaseData->leaseType != DHCP_BOOTP) release (pLeaseData); return (DHCPC_DONE); } if (pEvent->type == DHCP_USER_VERIFY) /* Verify lease. */ { if (pLeaseData->leaseType != DHCP_BOOTP) { /* Set the lease data to execute verify() routine. */ pLeaseData->prevState = BOUND; pLeaseData->currState = VERIFY; return (DHCPC_MORE); } } } return (OK); } /* The rest of the routine handles processing for finite DHCP leases. */ bzero (sbuf.buf, sbuf.size + DHCPC_OFF); if (time (&curr_epoch) == -1) {#ifdef DHCPC_DEBUG logMsg ("time() error in bound()\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } if (pLeaseData->prevState != BOUND) { /* * The interval between lease acknowledgement and the entry to the * bound() routine depends on the workload of the client monitor task * and is completely unpredictable. Check all lease timers, since they * might have expired during that time. */ wdCancel (pLeaseData->timer);#ifdef DHCPC_DEBUG logMsg ("dhcpc: Entering BOUND state.\n", 0, 0, 0, 0, 0, 0);#endif timeout = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->dhcp_t2; limit = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->lease_duration; if (curr_epoch >= limit || timeout <= curr_epoch) { /* Lease or second timer expired - create a timeout event. */ pEvent->source = DHCP_AUTO_EVENT; pEvent->type = DHCP_TIMEOUT; } else { timeout = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->dhcp_t1; if (timeout <= curr_epoch) { /* First timer expired - create a timeout event. */ pEvent->source = DHCP_AUTO_EVENT; pEvent->type = DHCP_TIMEOUT; } else { /* No timers expired - set to time remaining with T1. */ timeout = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->dhcp_t1 - curr_epoch; wdStart (pLeaseData->timer, sysClkRateGet() * timeout, (FUNCPTR)alarm_bound, (int)pLeaseData); } } pLeaseData->prevState = BOUND;#ifdef DHCPC_DEBUG logMsg ("dhcpc: Ready for user requests.\n", 0, 0, 0, 0, 0, 0); #endif } if (pEvent->type == DHCPC_STATE_BEGIN) /* Initial processing finished. */ return (OK); if (pEvent->source == DHCP_AUTO_EVENT) { /* If no timers have expired, ignore received DHCP messages. */ if (pEvent->type == DHCP_MSG_ARRIVED) return (OK); else { /* * Initiate renewal or rebinding when lease timers expire. * If the client monitor task is overloaded, processing may * occur well after the event notification is received. * In the worst case, the lease could expire before any * processing is performed. The timers can also expire * during a requested lease verification. Excess timeout * notifications which might be present from earlier states * are ignored. */ limit = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->lease_duration; if (curr_epoch >= limit) { /* Lease expired between notification and processing. */ pLeaseData->prevState = REQUESTING; pLeaseData->currState = INIT; return (DHCPC_MORE); } timeout = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->dhcp_t2; if (timeout <= curr_epoch && curr_epoch < limit) { /* Second timer expired: contact any server for parameters. */#ifdef DHCPC_DEBUG logMsg ("Entering REBINDING state.\n", 0, 0, 0, 0, 0, 0);#endif make_request (pLeaseData, REBINDING, TRUE); dhcpcMsgOut.udp->uh_sum = 0; dhcpcMsgOut.udp->uh_sum = udp_cksum (&spudph, (char *)dhcpcMsgOut.udp, ntohs (spudph.ulen)); if (etherOutput (pLeaseData->ifData.iface, dhcpcMsgOut.ether, &sbuf.buf [DHCPC_OFF + ETHERHL], sbuf.size - ETHERHL) == ERROR)#ifdef DHCPC_DEBUG logMsg ("Can't send DHCPREQUEST(REBINDING)\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = BOUND; pLeaseData->currState = REBINDING; return (OK); } timeout = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->dhcp_t1; limit = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->dhcp_t2; if (timeout <= curr_epoch && curr_epoch < limit) { /* * First timer expired: * attempt to renew lease with current server. */#ifdef DHCPC_DEBUG logMsg ("Entering RENEWING state.\n", 0, 0, 0, 0, 0, 0);#endif make_request (pLeaseData, RENEWING, TRUE); /* Ignore transmission failures for handling by timeout. */ status = send_unicast (&pLeaseData->dhcpcParam->server_id, dhcpcMsgOut.dhcp);#ifdef DHCPC_DEBUG if (status < 0) logMsg ("Can't send DHCPREQUEST(RENEWING)\n.", 0, 0, 0, 0, 0, 0);#endif /* DHCP request sent. Set lease data to execute next state. */ pLeaseData->prevState = BOUND; pLeaseData->currState = RENEWING; pLeaseData->initEpoch = curr_epoch; /* * Set the retransmission timer to wait for one-half of the * remaining time before T2 expires, or 60 seconds if T2 * expires in less than one minute. */ timeout = limit - curr_epoch; if (timeout > 60) timeout /= 2; else timeout = 60; /* Set timer for retransmission of request message. */ wdStart (pLeaseData->timer, sysClkRateGet() * timeout, (FUNCPTR)retrans_renewing, (int)pLeaseData); return (OK); } } /* End of timeout processing. */ } /* End of automatic events. */ else { /* Process user requests. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -