A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.
Dependents: oldheating gps motorhome heating
Diff: udp/dhcp/dhcp.c
- Revision:
- 116:60521b29e4c9
- Parent:
- 115:5c003909bcf3
- Child:
- 119:8e1a7805b801
--- a/udp/dhcp/dhcp.c Wed Jan 23 15:42:35 2019 +0000 +++ b/udp/dhcp/dhcp.c Fri Jan 25 17:37:51 2019 +0000 @@ -10,6 +10,7 @@ #include "ip4addr.h" #include "mac.h" #include "udp.h" +#include "dns.h" bool DhcpTrace = false; @@ -53,29 +54,32 @@ uint32_t cookie; }; -#define REPEAT_DELAY_TIME_MS 60 * 1000 -static uint32_t delayStartMs = 0; //Reset whenever a message is sent and blocks another send until count exceeds REPEAT_DELAY_TIME -static uint32_t lifeStartMs = 0; //Reset whenever an IP address request has been acknowledged +#define MAX_REPEAT_DELAY_TIME_MS 60000 +#define MIN_REPEAT_DELAY_TIME_MS 1000 +static uint32_t repeatDelayTimer = 0; //Started whenever a message is sent and blocks another send until after the delay time +static uint32_t delayMs = MIN_REPEAT_DELAY_TIME_MS; //Doubles on failure up to max; reset to min whenever an IP address request has been acknowledged + +static uint32_t elapsedLifeTimer = 0; //Started whenever an IP address request has been acknowledged uint32_t DhcpGetElapsedLife() { - if (!lifeStartMs) return 0; - return (MsTimerCount - lifeStartMs) / 1000; + if (!elapsedLifeTimer) return 0; + return (MsTimerCount - elapsedLifeTimer) / 1000; } static uint8_t dhcpMessageType = 0; uint32_t DhcpLeaseTime = 0; -uint32_t DhcpServer = 0; -uint32_t DhcpRouter = 0; +uint32_t DhcpServerIp = 0; +uint32_t DhcpRouterIp = 0; uint32_t DhcpSubnetMask = 0; -uint32_t DhcpNtp = 0; +uint32_t DhcpNtpIp = 0; uint32_t DhcpRenewalT1 = 0; uint32_t DhcpRenewalT2 = 0; uint32_t DhcpBroadcastIp = 0; uint32_t DhcpLocalIp = 0; -uint32_t DhcpDnsServer = 0; -char DhcpDomainName[20]; -char DhcpHostName[20]; +uint32_t DhcpDnsServerIp = 0; +char DhcpDomainName[DNS_MAX_LABEL_LENGTH]; +char DhcpHostName [DNS_MAX_LABEL_LENGTH]; bool DhcpIpNeedsToBeRouted(uint32_t ip) { @@ -131,20 +135,20 @@ case 0: break; //NOP case 255: return; //End of options case 1: DhcpSubnetMask = readIp(&p); break; //Subnet Mask - case 3: DhcpRouter = readIp(&p); break; //Router - case 6: DhcpDnsServer = readIp(&p); break; //DNS server + case 3: DhcpRouterIp = readIp(&p); break; //Router + case 6: DhcpDnsServerIp = readIp(&p); break; //DNS server case 12: readString(&p, DhcpHostName); break; //Host name case 15: readString(&p, DhcpDomainName); break; //Domain name case 19: len = *++p; p+= len; break; //IP forwarding yes/no case 28: DhcpBroadcastIp = readIp(&p); break; //Broadcast IP - case 42: DhcpNtp = readIp(&p); break; //NTP + case 42: DhcpNtpIp = readIp(&p); break; //NTP case 44: len = *++p; p+= len; break; //NetBIOS name server case 45: len = *++p; p+= len; break; //NetBIOS datagram server case 46: len = *++p; p+= len; break; //NetBIOS node type case 47: len = *++p; p+= len; break; //NetBIOS scope case 53: len = *++p; dhcpMessageType = *++p; break; //DHCP message type case 51: DhcpLeaseTime = readOption32(&p); break; //Address lease time - case 54: DhcpServer = readIp(&p); break; //DHCP server + case 54: DhcpServerIp = readIp(&p); break; //DHCP server case 58: DhcpRenewalT1 = readOption32(&p); break; //T1 case 59: DhcpRenewalT2 = readOption32(&p); break; //T2 default: @@ -224,7 +228,6 @@ *p++ = 255; //End of options - delayStartMs = MsTimerCount; return HEADER_LENGTH + p - pOptions; } int DhcpHandleResponse(void (*traceback)(void), int sizeRx, void* pPacketRx, int* pSizeTx, void* pPacketTx) @@ -263,7 +266,8 @@ case DHCPACK: if (DhcpTrace) { LogTime("DHCP <- ack ip "); Ip4AddressLog(yiaddr); Log("\r\n"); } DhcpLocalIp = yiaddr; - lifeStartMs = MsTimerCount; + elapsedLifeTimer = MsTimerCount; //Start the life timer + delayMs = MIN_REPEAT_DELAY_TIME_MS; //Set the delay time back to minimum break; case DHCPNAK: if (DhcpTrace) { LogTime("DHCP <- nack ip "); Ip4AddressLog(yiaddr); Log("\r\n"); } @@ -276,10 +280,13 @@ } int DhcpPollForRequestToSend(void* pPacket, int* pSize) -{ - if (delayStartMs && !MsTimerHasElapsed(delayStartMs, REPEAT_DELAY_TIME_MS)) return DO_NOTHING; //Don't retry within the delay time +{ + if (repeatDelayTimer && !MsTimerHasElapsed(repeatDelayTimer, delayMs)) return DO_NOTHING; //Don't retry within the delay time + delayMs <<= 1; //Backoff (double) the delay time after each attempt + if (delayMs > MAX_REPEAT_DELAY_TIME_MS) delayMs = MAX_REPEAT_DELAY_TIME_MS; //Don't go beyond a maximum + repeatDelayTimer = MsTimerCount; //Start the delay timer - uint32_t elapsedTimeMs = MsTimerCount - lifeStartMs; + uint32_t elapsedTimeMs = MsTimerCount - elapsedLifeTimer; uint32_t leaseTimeMs = DhcpLeaseTime * 1000; if (DhcpLocalIp && elapsedTimeMs < (leaseTimeMs >> 1)) return 0; //Do nothing if have address and within T1 @@ -288,14 +295,14 @@ int dest = DO_NOTHING; if (DhcpLocalIp && elapsedTimeMs < leaseTimeMs) { - *pSize = sendRequest(pPacket, DHCPREQUEST, DhcpServer, DhcpLocalIp); //if within T2 then send request to the server - not broadcast + *pSize = sendRequest(pPacket, DHCPREQUEST, DhcpServerIp, DhcpLocalIp); //if within T2 then send request to the server - not broadcast dest = UNICAST_DHCP; } else { if (DhcpTrace) LogTimeF("DHCP lease has expired\r\n"); DhcpLocalIp = 0; - DhcpServer = 0; + DhcpServerIp = 0; *pSize = sendRequest(pPacket, DHCPDISCOVER, 0, 0); //If outside T2 then start from scratch to do a full DHCP dest = BROADCAST; }