// frees an item (may crash if allocation in progess) void DHCPDestroyItem (struct LL_IP *pCur) { if (pCur!=NULL) { LOG (5, "Freeing item %s %s", inet_ntoa (pCur->dwIP), haddrtoa (pCur->sMacAddr, 6,':') ) ; // put item at the end of the list and resort array SetIP(pCur, INADDR_NONE); // will be the last item memset(pCur->sMacAddr, 0, 6); qsort (tFirstIP, nAllocatedIP, sizeof *tFirstIP, QsortCompare); qsort (tMAC, nAllocatedIP, sizeof *tMAC, MACCompare); DecNumAllocated(); ReorderLeases(); free ( tFirstIP[nAllocatedIP] ); // free the last item } // wake up DHCP thread --> actualizes GUI with SendLeases WakeUpThread (TH_DHCP); } // DHCPDestroyItem
// Create or realloc an item struct LL_IP *DHCPReallocItem (struct LL_IP *pCur, DWORD dwNewIP, const unsigned char *pMac, int nMacLen) { if (pCur==NULL) { pCur = tFirstIP[nAllocatedIP] = malloc (sizeof *tFirstIP[0]); pCur->dwAllocNum = nAllocatedIP; tMAC[nAllocatedIP] = pCur; IncNumAllocated(); } SetIP(pCur, dwNewIP); SetAllocTime(pCur); ZeroRenewTime(pCur); SetMacAddr(pCur, pMac, nMacLen); // sort whole array qsort (tFirstIP, nAllocatedIP, sizeof *tFirstIP, QsortCompare); qsort (tMAC, nAllocatedIP, sizeof *tMAC, MACCompare); ReorderLeases(); return pCur; } // DHCPReallocItem
//Read in and initialize the leases void LoadLeases(void) { //We need to make sure the leases we load actually fit in the address pool, so we'll be //tracking the index to the lease file and the index to the allocated list int leaseindex, allocindex; // From Nick : I realized that there was a race condition in that code, // particularly with the reading and saving of KEY_LEASE_NUMLEASES // I’ve added a function, which LoadLeases calls immediately on entry: WaitForMsgQueueToFinish (LL_ID_SETTINGS); nAllocatedIP = 0; ReadKey(TFTPD32_DHCP_KEY, KEY_LEASE_NUMLEASES, &nAllocatedIP, sizeof(nAllocatedIP), REG_DWORD, szTftpd32IniFile); if (nAllocatedIP > sParamDHCP.nPoolSize) { SVC_WARNING ("The pool size is too small for the number of leases, ignoring extra leases"); nAllocatedIP = sParamDHCP.nPoolSize; } allocindex = 0; for(leaseindex = 0; leaseindex < nAllocatedIP; ++leaseindex) { char key [_MAX_PATH]; char tmpval [_MAX_PATH]; tFirstIP[allocindex] = malloc (sizeof(struct LL_IP)); memset(tFirstIP[allocindex], 0, sizeof(struct LL_IP)); tFirstIP[allocindex]->dwAllocNum = leaseindex; sprintf(key, "%s%d%s", KEY_LEASE_PREFIX, leaseindex, KEY_LEASE_MAC); if(ReadKey(TFTPD32_DHCP_KEY, key, tmpval, _MAX_PATH, REG_SZ, szTftpd32IniFile)) atohaddr(tmpval, tFirstIP[allocindex]->sMacAddr, 6); sprintf(key, "%s%d%s", KEY_LEASE_PREFIX, leaseindex, KEY_LEASE_IP); if(ReadKey(TFTPD32_DHCP_KEY, key, tmpval, _MAX_PATH, REG_SZ, szTftpd32IniFile)) tFirstIP[allocindex]->dwIP.s_addr = inet_addr(tmpval); sprintf(key, "%s%d%s", KEY_LEASE_PREFIX, leaseindex, KEY_LEASE_ALLOC); if(ReadKey(TFTPD32_DHCP_KEY, key, tmpval, _MAX_PATH, REG_SZ, szTftpd32IniFile)) tFirstIP[allocindex]->tAllocated = atotime(tmpval); sprintf(key, "%s%d%s", KEY_LEASE_PREFIX, leaseindex, KEY_LEASE_RENEW); if(ReadKey(TFTPD32_DHCP_KEY, key, tmpval, _MAX_PATH, REG_SZ, szTftpd32IniFile)) tFirstIP[allocindex]->tRenewed = atotime(tmpval); // fix errors in date conversion (registry modified at hand) if (tFirstIP[allocindex]->tAllocated == -1) tFirstIP[allocindex]->tAllocated = 0; if (tFirstIP[allocindex]->tRenewed == -1) tFirstIP[allocindex]->tRenewed = 0; //If the address doesn't fit in the pool, don't add it after all //Since we are assuming the leases were written in order, do a quick check for dups //and invalid macaddrs if((!AddrFitsPool(&tFirstIP[allocindex]->dwIP)) || (IsMacEmpty(tFirstIP[allocindex])) || ((allocindex > 0) && (tFirstIP[allocindex]->dwIP.s_addr == tFirstIP[allocindex - 1]->dwIP.s_addr))) { free(tFirstIP[allocindex]); tFirstIP[allocindex] = NULL; } else { tMAC[allocindex] = tFirstIP[allocindex]; //Copy to cross index ++allocindex; //Move on to the next one } } if(allocindex != nAllocatedIP) SetNumAllocated(allocindex); // ensure that data base is sorted (especially if we've dropped some leases in the load) qsort (tMAC, nAllocatedIP, sizeof *tMAC, MACCompare); qsort (tFirstIP, nAllocatedIP, sizeof *tFirstIP, QsortCompare); ReorderLeases(); } // LoadLeases