📄 dhcpcstate2.c
字号:
}/********************************************************************************* retrans_renewing - signal when reception interval for renewal reply expires** 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; int length; time_t curr_epoch = 0; struct sockaddr_in dest; struct ifnet *pIf; struct ifreq ifr; /* * 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, TRUE); 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); if (dhcpTime (&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. * Resume filtering with the BPF device (suspended before * entry to this routine) before restarting. */ bzero ((char *) &ifr, sizeof (struct ifreq)); sprintf (ifr.ifr_name, "%s%d", pLeaseData->ifData.iface->if_name, pLeaseData->ifData.iface->if_unit); ioctl (pLeaseData->ifData.bpfDev, BIOCSTART, (int) &ifr); 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 length = make_request (pLeaseData, REBINDING, TRUE); dhcpcMsgOut.udp->uh_sum = 0; dhcpcMsgOut.udp->uh_sum = udp_cksum (&spudph, (char *) dhcpcMsgOut.udp, ntohs (spudph.ulen)); bzero ((char *) &dest, sizeof (struct sockaddr_in)); dest.sin_len = sizeof (struct sockaddr_in); dest.sin_family = AF_INET; dest.sin_addr.s_addr = dhcpcMsgOut.ip->ip_dst.s_addr; pIf = pLeaseData->ifData.iface; /* Remember to re-enable the BPF filter here. */ bzero ((char *) &ifr, sizeof (struct ifreq)); sprintf (ifr.ifr_name, "%s%d", pLeaseData->ifData.iface->if_name, pLeaseData->ifData.iface->if_unit); ioctl (pLeaseData->ifData.bpfDev, BIOCSTART, (int) &ifr); status = dhcpSend (pIf, &dest, sbuf.buf, length, TRUE);#ifdef DHCPC_DEBUG if (status == ERROR) logMsg ("Can't send DHCPREQUEST(REBINDING)\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = BOUND; pLeaseData->currState = REBINDING; /* Set a timeout in case we miss the reply. */ timeout = limit - curr_epoch; timeout /= 2; if (timeout < 60) timeout = 60; wdStart (pLeaseData->timer, sysClkRateGet () * timeout, (FUNCPTR) retrans_rebinding, (int) pLeaseData); 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. * Resume filtering with the BPF device (suspended while * bound). */ bzero ((char *) &ifr, sizeof (struct ifreq)); sprintf (ifr.ifr_name, "%s%d", pLeaseData->ifData.iface->if_name, pLeaseData->ifData.iface->if_unit); ioctl (pLeaseData->ifData.bpfDev, BIOCSTART, (int) &ifr);#ifdef DHCPC_DEBUG logMsg ("Entering RENEWING state.\n", 0, 0, 0, 0, 0, 0);#endif length = make_request (pLeaseData, RENEWING, TRUE); /* Ignore transmission failures for handling by timeout. */ status = send_unicast (&pLeaseData->dhcpcParam->server_id, dhcpcMsgOut.dhcp, length);#ifdef DHCPC_DEBUG if (status < 0) logMsg ("Can't send DHCPREQUEST(RENEWING)\n.", 0, 0, 0, 0, 0, 0);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -