Author: hummen Date: Wed Mar 23 11:14:04 2011 New Revision: 2467 Log: patch for dhcp-3.1.3 enabling static client leases NOTE: This patch needs review and testing. Added: trunk/openwrt/patches/120-dhcp-ma-ap.patch Added: trunk/openwrt/patches/120-dhcp-ma-ap.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/openwrt/patches/120-dhcp-ma-ap.patch Wed Mar 23 11:14:04 2011 (r2467) @@ -0,0 +1,770 @@ +diff -ruN dhcp-3.1.3-orig/includes/dhcpd.h dhcp-3.1.3/includes/dhcpd.h +--- dhcp-3.1.3-orig/includes/dhcpd.h 2009-09-01 22:32:27.000000000 +0200 ++++ dhcp-3.1.3/includes/dhcpd.h 2011-03-21 21:44:00.413869746 +0100 +@@ -686,6 +686,15 @@ + struct class *class; + }; + ++#if defined (LARGE_SUBNET) ++#define MAX_ALLOCATE_RANGE 256 ++struct range { ++ struct range *next; ++ struct iaddr low, high; ++ unsigned min, max, cnt; ++}; ++#endif/*LARGE_SUBNET*/ ++ + struct pool { + OMAPI_OBJECT_PREAMBLE; + struct pool *next; +@@ -707,6 +716,11 @@ + #if defined (FAILOVER_PROTOCOL) + dhcp_failover_state_t *failover_peer; + #endif ++ ++#if defined (LARGE_SUBNET) ++ struct range *range; ++#endif/*LARGE_SUBNET*/ ++ + }; + + struct shared_network { +@@ -2608,9 +2622,20 @@ + unsigned, const char *, int)); + int find_host_for_network PROTO ((struct subnet **, struct host_decl **, + struct iaddr *, struct shared_network *)); ++ ++#if defined (LARGE_SUBNET) ++int new_address_range PROTO ((struct parse *, struct iaddr, struct iaddr, ++ struct subnet *, struct pool *, ++ struct lease **, int)); ++#else /*LARGE_SUBNET*/ ++ + void new_address_range PROTO ((struct parse *, struct iaddr, struct iaddr, + struct subnet *, struct pool *, + struct lease **)); ++ ++#endif/*LARGE_SUBNET*/ ++ ++ + isc_result_t dhcp_lease_free (omapi_object_t *, const char *, int); + isc_result_t dhcp_lease_get (omapi_object_t **, const char *, int); + int find_grouped_subnet PROTO ((struct subnet **, struct shared_network *, +diff -ruN dhcp-3.1.3-orig/includes/mac2ip.h dhcp-3.1.3/includes/mac2ip.h +--- dhcp-3.1.3-orig/includes/mac2ip.h 1970-01-01 01:00:00.000000000 +0100 ++++ dhcp-3.1.3/includes/mac2ip.h 2011-03-21 21:44:00.415852974 +0100 +@@ -0,0 +1,60 @@ ++/** ++ * Author: Max Gelmroth ++ * ++ * NOTE: for mac2ip to work properly you ++ * need to create a mac2ip.conf file ++ * and store it in /etc ++ * ++ * by now it only has to contain two ++ * lines that define the ip bounds the ++ * hashed ip will be adjusted to ++ * ++ * the file should look like: ++ * lower_client_ip_bound=xxx.xxx.xxx.xxx ++ * upper_client_ip_bound=xxx.xxx.xxx.xxx ++ * lower_service_ip_bound=xxx.xxx.xxx.xxx ++ * upper_service_ip_bound=xxx.xxx.xxx.xxx ++ * ++ */ ++ ++ ++#ifndef __MAC2IP_H__ ++#define __MAC2IP_H__ ++ ++ ++#include <stdint.h> ++ ++ ++typedef struct mac2ip_ipv4_t{ ++ uint8_t x[4]; ++} mac2ip_ipv4_t; ++ ++typedef struct mac2ip_mac_t{ ++ uint8_t x[6]; ++} mac2ip_mac_t; ++ ++ ++typedef struct ip_bounds { ++ ++ /* ++ * lower client's ip bound := 0 ++ * upper client's ip bound := 1 ++ * lower service's ip bound := 2 ++ * upper service's ip bound := 3 ++ */ ++ mac2ip_ipv4_t bound[4]; ++ ++} ip_bounds; ++ ++/* ++ * hash mac random ip that is adjusted to the ip-bounds ++ * configured in /etc/mac2ip.conf ++ * result will be stored in 'ip' ++ * ++*/ ++int mac_to_ip(const mac2ip_mac_t *, mac2ip_ipv4_t *); ++ ++int read_ip_bounds(ip_bounds *); ++ ++ ++#endif /* __MAC2IP_H__ */ +diff -ruN dhcp-3.1.3-orig/includes/site.h dhcp-3.1.3/includes/site.h +--- dhcp-3.1.3-orig/includes/site.h 2009-04-07 22:00:42.000000000 +0200 ++++ dhcp-3.1.3/includes/site.h 2011-03-21 21:44:00.418827814 +0100 +@@ -195,3 +195,11 @@ + traces. */ + + #define TRACING ++ ++/* Define this if you want to be able to support class A/B networks. */ ++ ++#define LARGE_SUBNET ++ ++/* Define this if you use this dhcpd on a mobileACcess AP */ ++ ++#define MOBAC_MODE +diff -ruN dhcp-3.1.3-orig/server/confpars.c dhcp-3.1.3/server/confpars.c +--- dhcp-3.1.3-orig/server/confpars.c 2009-09-01 22:32:28.000000000 +0200 ++++ dhcp-3.1.3/server/confpars.c 2011-03-21 21:44:00.425769109 +0100 +@@ -3341,8 +3341,64 @@ + } + #endif /* FAILOVER_PROTOCOL */ + ++#if defined (LARGE_SUBNET) ++ do { ++ unsigned min, max; ++ struct range *range; ++ ++ /* Make sure that high and low addresses are in same subnet. */ ++ net = subnet_number (low, subnet -> netmask); ++ if (!addr_eq (net, subnet_number (high, subnet -> netmask))) ++ break; ++ ++ /* Make sure that the addresses are on the correct subnet. */ ++ if (!addr_eq (net, subnet -> net)) ++ break; ++ ++ /* Get the high and low host addresses... */ ++ max = host_addr (high, subnet -> netmask); ++ min = host_addr (low, subnet -> netmask); ++ ++ /* Allow range to be specified high-to-low as well as low-to-high. */ ++ if (min > max) { ++ max = min; ++ min = host_addr (high, subnet -> netmask); ++ } ++ ++ /* Allocate if range is small enough */ ++ if (max - min + 1 <= MAX_ALLOCATE_RANGE) ++ break; ++ ++ /* Record the range for later use */ ++ range = dmalloc (sizeof(struct range), MDL); ++ if (!range) ++ log_fatal ("Can't allocate range"); ++ low = ip_addr (subnet -> net, subnet -> netmask, min); ++ high = ip_addr (subnet -> net, subnet -> netmask, max); ++ range -> low = low; ++ range -> high = high; ++ range -> min = min; ++ range -> max = max; ++ range -> cnt = max - min + 1; ++ ++ range -> next = pool -> range; ++ pool -> range = range; ++ ++ log_debug ("saved range: %u.%u.%u.%u ~ %u.%u.%u.%u, cnt=%u", ++ low.iabuf[0], low.iabuf[1], low.iabuf[2], low.iabuf[3], ++ high.iabuf[0], high.iabuf[1], high.iabuf[2], high.iabuf[3], range -> cnt); ++ ++ pool_dereference (&pool, MDL); ++ return; ++ } while (0); ++ ++ /* Create the new address range... */ ++ new_address_range (cfile, low, high, subnet, pool, lpchain, 0); ++#else /*LARGE_SUBNET*/ + /* Create the new address range... */ + new_address_range (cfile, low, high, subnet, pool, lpchain); ++#endif/*LARGE_SUBNET*/ ++ + pool_dereference (&pool, MDL); + } + +diff -ruN dhcp-3.1.3-orig/server/dhcp.c dhcp-3.1.3/server/dhcp.c +--- dhcp-3.1.3-orig/server/dhcp.c 2009-09-01 22:32:28.000000000 +0200 ++++ dhcp-3.1.3/server/dhcp.c 2011-03-21 21:44:00.433702018 +0100 +@@ -39,11 +39,20 @@ + + #include "dhcpd.h" + ++#if defined (MOBAC_MODE) ++#include "mac2ip.h" ++#include <time.h> ++#endif ++ + int outstanding_pings; + + static char dhcp_message [256]; + static int site_code_min; + ++#if defined (MOBAC_MODE) ++const char mobac_interface[] = "br0"; ++#endif ++ + static int find_min_site_code(struct universe *); + static isc_result_t lowest_site_code(const void *, unsigned, void *); + +@@ -2102,6 +2111,26 @@ + lease_time = default_lease_time; + } + ++#if defined (MOBAC_MODE) ++ /* Check the number of seconds till midnight. If this is less ++ than default_lease_time set it as lease_time */ ++ if (strcmp(packet -> interface -> name, mobac_interface) == 0) { ++ time_t cur_time = time(NULL); ++ struct tm timestruct; ++ gmtime_r(&cur_time, ×truct); ++ ++ int seconds_to_midnight; ++ ++ seconds_to_midnight = (23 - timestruct.tm_hour) * 60 * 60; ++ seconds_to_midnight += (59 - timestruct.tm_min) * 60; ++ seconds_to_midnight += 60 - timestruct.tm_sec; ++ ++ if ((int) lease_time > seconds_to_midnight) ++ lease_time = seconds_to_midnight; ++ } ++#endif ++ ++ + #if defined (FAILOVER_PROTOCOL) + /* Okay, we know the lease duration. Now check the + failover state, if any. */ +@@ -3783,6 +3812,91 @@ + } else + #endif + { ++ ++#if defined (LARGE_SUBNET) ++ while (!pool -> free && pool -> range) { ++ struct range *range = pool -> range; ++ unsigned cnt = range -> cnt; ++ struct subnet *subnet = NULL; ++ ++ if (cnt < 0) cnt = 0; ++ if (cnt > MAX_ALLOCATE_RANGE) cnt = MAX_ALLOCATE_RANGE; ++ ++ /* find subnet from shared_network: next_sibling? */ ++ if (cnt) { ++ struct shared_network *share = pool -> shared_network; ++ for (subnet = share -> subnets; subnet; subnet = subnet -> next_sibling) { ++ struct iaddr net = subnet_number (range -> low, subnet -> netmask); ++ if (!addr_eq(net, subnet_number (range -> high, subnet -> netmask))) ++ continue; ++ if (addr_eq(net, subnet -> net)) ++ break; ++ } ++ } ++ if (!subnet) ++ break; ++ ++ if (cnt) { ++ ++#if defined (MOBAC_MODE) ++ struct iaddr new_mobac_ip = {}; ++ new_mobac_ip.len = 4; ++ ++ /* Check if that unknown client is a mobAC-client. If so, hash its MAC ++ to an IP without using the normal IP-pool. */ ++ if (strcmp(packet -> interface -> name, mobac_interface) == 0) { ++ ++ log_debug("received DHCPDISCOVER-packet on mobAC-interface!"); ++ ++ mac2ip_mac_t clients_mac; ++ if (packet->haddr->hlen != 7) { ++ log_error("clients MAC-address length is not 6 byte!"); ++ int j = 0; ++ for (j; j < packet->haddr->hlen; j++) { ++ log_debug("HW[%d]: ", packet->haddr->hbuf[j]); ++ } ++ return 1; ++ } else { ++ int iter = 1; ++ for (iter; iter < 7; iter++) ++ clients_mac.x[iter-1] = packet->haddr->hbuf[iter]; ++ } ++ ++ /* Now read the bounds for the later generated IPs. */ ++ mac2ip_ipv4_t calculated_ip; ++ if (mac_to_ip(&clients_mac, &calculated_ip) != 0) ++ return 1; ++ ++ int k = 0; ++ for (k; k < 4; k++) ++ sprintf(&new_mobac_ip.iabuf[k], "%c", calculated_ip.x[k]); ++ ++ log_debug("hashed client's MAC to IP %s", piaddr(new_mobac_ip)); ++ ++ } ++ ++ ++ struct iaddr low = new_mobac_ip; ++ struct iaddr high = new_mobac_ip; ++#endif ++ ++ log_debug ("allocating range: %u.%u.%u.%u ~ %u.%u.%u.%u", ++ low.iabuf[0], low.iabuf[1], low.iabuf[2], low.iabuf[3], ++ high.iabuf[0], high.iabuf[1], high.iabuf[2], high.iabuf[3]); ++ cnt = new_address_range (NULL, low, high, subnet, pool, NULL, 1); ++ if (!cnt) break; ++ ++ range -> cnt -= 1; ++ } ++ ++ if (!range -> cnt) { ++ pool -> range = range -> next; ++ dfree (range, MDL); ++ } ++ break; ++ } ++#endif/*LARGE_SUBNET*/ ++ + if (pool -> free) + candl = pool -> free; + else +diff -ruN dhcp-3.1.3-orig/server/mac2ip.c dhcp-3.1.3/server/mac2ip.c +--- dhcp-3.1.3-orig/server/mac2ip.c 1970-01-01 01:00:00.000000000 +0100 ++++ dhcp-3.1.3/server/mac2ip.c 2011-03-21 21:44:00.439651699 +0100 +@@ -0,0 +1,276 @@ ++/** ++ * This Code calculates IPv4s based on Ethernet-addresses ++ * ++ * Author: Max Gelmroth ++ * ++ */ ++ ++#include "mac2ip.h" ++#include <stdlib.h> ++#include <string.h> ++#include <assert.h> ++#include <time.h> ++#include <stdio.h> ++ ++//mac2ip.conf file ++const char *CONFIG_FILE_LOCATION = "/etc/mac2ip.conf"; ++ ++ ++/******************************************************************************* ++ * HASH ALGORITHM ++ *******************************************************************************/ ++ ++ ++//Jenkins one-at-a-time hash (see http://burtleburtle.net/bob/hash/doobs.html) ++uint32_t jenkins_one_at_a_time_hash(const unsigned char *key, const size_t key_len) { ++ uint32_t hash = 0; ++ size_t i; ++ ++ for (i = 0; i < key_len; i++) { ++ hash += key[i]; ++ hash += (hash << 10); ++ hash ^= (hash >> 6); ++ } ++ hash += (hash << 3); ++ hash ^= (hash >> 11); ++ hash += (hash << 15); ++ return hash; ++} ++ ++ ++//hash mac random ip ++void hash_mac_to_rnd_ip_OAAT(const mac2ip_mac_t *mac, mac2ip_ipv4_t *ip){ ++ const uint8_t uint8_max_value = 255, max_string_len = 32; ++ time_t cur_time; ++ struct tm timestruct; ++ uint32_t hash; ++ mac2ip_mac_t mac_duplicate; ++ ++ memcpy(&mac_duplicate, mac, sizeof(mac_duplicate)); ++ ++ /* ++ * use day of the year in the hashfunction to avoid ++ * that two MAC-addresses that are hashed to the same ++ * IP today causes a collision tomorrow, too. ++ */ ++ cur_time = time(NULL); ++ gmtime_r(&cur_time, ×truct); ++ ++ mac_duplicate.x[3] = (mac_duplicate.x[3] + timestruct.tm_yday + 1) % (uint8_max_value + 1); ++ ++ //hash it! ++ hash = jenkins_one_at_a_time_hash((char *)mac_duplicate.x, sizeof(mac_duplicate.x)); ++ ++ *((uint32_t*)ip->x) = hash; ++ ++} ++ ++ ++//converts mac in hex_string_format to mac_t ++static void string_to_ipv4_t(const char *string, mac2ip_ipv4_t *ip) { ++ int i; ++ char *byte = NULL, *string_duplicate = NULL; ++ ++ string_duplicate = strdup(string); ++ ++ ++ byte = strtok(string_duplicate, "."); ++ ++ for (i=0; i < sizeof(ip->x); i++) { ++ ++ sscanf(byte, "%hhu", &ip->x[i]); ++ ++ byte = strtok(NULL, "."); ++ ++ } ++ ++ free(string_duplicate); ++} ++ ++ ++static char *readline(FILE * fp, char **buf, size_t *buflen) { ++ char *newline = NULL; ++ char *p; ++ char *line; /* The array that contains everything that has been read so far */ ++ char *idx; /* Read into this pointer, which points to an offset within line */ ++ size_t size, newsize; /* The size of the current array pointed to by line */ ++ size_t maxlen; /* Maximum number of characters that may be read with fgets. This is newsize - oldsize. */ ++ ++ if(feof(fp)) ++ return NULL; ++ ++ if(buf && buflen) { ++ size = *buflen; ++ line = *buf; ++ } else { ++ size = 100; ++ line = malloc(size); ++ } ++ ++ maxlen = size; ++ idx = line; ++ *idx = 0; ++ ++ for(;;) { ++ p = fgets(idx, maxlen, fp); ++ ++ if(!p) { /* EOF or error */ ++ if(feof(fp)) ++ break; ++ ++ /* otherwise: error; let the calling function print an error message if applicable */ ++ free(line); ++ return NULL; ++ } ++ ++ newline = strchr(p, '\n'); ++ ++ if(!newline) { /* We haven't yet read everything to the end of the line */ ++ newsize = size << 1; ++ line = realloc(line, newsize); ++ idx = &line[size - 1]; ++ maxlen = newsize - size + 1; ++ size = newsize; ++ } else { ++ *newline = '\0'; /* kill newline */ ++ if(newline > p && newline[-1] == '\r') /* and carriage return if necessary */ ++ newline[-1] = '\0'; ++ break; /* yay */ ++ } ++ } ++ ++ if(buf && buflen) { ++ *buflen = size; ++ *buf = line; ++ } ++ ++ return line; ++} ++ ++ ++/* Read IP-bounds from file ++ * return -1 if an error occured ++ * otherwise it returns the number of ++ * IPs that have been read ++ */ ++int read_ip_bounds(ip_bounds *bounds) { ++ int retval = 0; ++ FILE *fp = NULL; ++ char *buffer = NULL, *line = NULL; ++ char *variable = NULL, *value = NULL, *eol = NULL; ++ int len; ++ size_t buffsize = 100; ++ ++ fp = fopen(CONFIG_FILE_LOCATION, "r"); ++ ++ if(!fp) { ++ return -1; ++ } ++ ++ buffer = malloc(buffsize); ++ ++ for (;;) { ++ ++ if(feof(fp)) { ++ retval = -1; ++ printf("cannot open file %s to read IPs from!\n", CONFIG_FILE_LOCATION); ++ break; ++ } ++ ++ line = readline(fp, &buffer, &buffsize); ++ ++ if(!line) { ++ retval = -1; ++ break; ++ } ++ ++ variable = value = line; ++ ++ if (strcmp(line, "\n") == 0) ++ continue; ++ ++ eol = line + strlen(line); ++ while(strchr("\t ", *--eol)) ++ *eol = '\0'; ++ ++ len = strcspn(value, "\t ="); ++ value += len; ++ value += strspn(value, "\t "); ++ if(*value == '=') { ++ value++; ++ value += strspn(value, "\t "); ++ } ++ variable[len] = '\0'; ++ ++ ++ if(!*value) ++ continue; ++ ++ ++ if (strcmp(variable, "lower_client_ip_bound") == 0) { ++ string_to_ipv4_t(value, &bounds->bound[0]); ++ retval++; ++ continue; ++ } ++ ++ if (strcmp(variable, "upper_client_ip_bound") == 0) { ++ string_to_ipv4_t(value, &bounds->bound[1]); ++ retval++; ++ continue; ++ } ++ ++ if (strcmp(variable, "lower_service_ip_bound") == 0) { ++ string_to_ipv4_t(value, &bounds->bound[2]); ++ retval++; ++ continue; ++ } ++ ++ if (strcmp(variable, "upper_service_ip_bound") == 0) { ++ string_to_ipv4_t(value, &bounds->bound[3]); ++ retval++; ++ } ++ ++ } ++ ++ fclose(fp); ++ free(buffer); ++ ++ return retval; ++ ++} ++ ++ ++//adjusts the ip to the given bounds ++void adjust_ip_to_bounds(mac2ip_ipv4_t *ip, const mac2ip_ipv4_t *upper_bound, const mac2ip_ipv4_t *lower_bound) { ++ int i, ips_byte_len = 4; ++ ++ ++ for (i=0; i < ips_byte_len; i++) { ++ ++ //x % 0 is undefined :( ++ if (upper_bound->x[i] - lower_bound->x[i] == 0) { ++ ip->x[i] = lower_bound->x[i]; ++ } else { ++ ip->x[i] = (ip->x[i] % (upper_bound->x[i] - lower_bound->x[i])) + lower_bound->x[i]; ++ } ++ } ++} ++ ++ ++int mac_to_ip(const mac2ip_mac_t *mac, mac2ip_ipv4_t *ip) { ++ ip_bounds bounds; ++ ++ ++ hash_mac_to_rnd_ip_OAAT(mac, ip); ++ ++ //we want to read at least 4 IPs ++ if (read_ip_bounds(&bounds) >= 2) { ++ printf("ERROR reading ip-bounds!\n"); ++ return -1; ++ } ++ ++ adjust_ip_to_bounds(ip, &bounds.bound[1], &bounds.bound[0]); ++ ++ return 0; ++ ++} +diff -ruN dhcp-3.1.3-orig/server/Makefile.dist dhcp-3.1.3/server/Makefile.dist +--- dhcp-3.1.3-orig/server/Makefile.dist 2009-07-23 23:43:35.000000000 +0200 ++++ dhcp-3.1.3/server/Makefile.dist 2011-03-21 21:44:00.442626540 +0100 +@@ -25,9 +25,11 @@ + CATMANPAGES = dhcpd.cat8 dhcpd.conf.cat5 dhcpd.leases.cat5 + SEDMANPAGES = dhcpd.man8 dhcpd.conf.man5 dhcpd.leases.man5 + SRCS = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \ +- omapi.c mdb.c stables.c salloc.c ddns.c dhcpleasequery.c ++ omapi.c mdb.c stables.c salloc.c ddns.c dhcpleasequery.c \ ++ mac2ip.c + OBJS = dhcpd.o dhcp.o bootp.o confpars.o db.o class.o failover.o \ +- omapi.o mdb.o stables.o salloc.o ddns.o dhcpleasequery.o ++ omapi.o mdb.o stables.o salloc.o ddns.o dhcpleasequery.o \ ++ mac2ip.o + PROG = dhcpd + MAN = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5 + +diff -ruN dhcp-3.1.3-orig/server/mdb.c dhcp-3.1.3/server/mdb.c +--- dhcp-3.1.3-orig/server/mdb.c 2009-09-01 22:32:28.000000000 +0200 ++++ dhcp-3.1.3/server/mdb.c 2011-03-21 21:44:00.447584608 +0100 +@@ -525,12 +525,22 @@ + return 0; + } + ++#if defined (LARGE_SUBNET) ++int new_address_range (cfile, low, high, subnet, pool, lpchain, instantiate) ++ struct parse *cfile; ++ struct iaddr low, high; ++ struct subnet *subnet; ++ struct pool *pool; ++ struct lease **lpchain; ++ int instantiate; ++#else /*LARGE_SUBNET*/ + void new_address_range (cfile, low, high, subnet, pool, lpchain) + struct parse *cfile; + struct iaddr low, high; + struct subnet *subnet; + struct pool *pool; + struct lease **lpchain; ++#endif /*LARGE_SUBNET*/ + { + #if defined(COMPACT_LEASES) + struct lease *address_range; +@@ -594,6 +604,13 @@ + #if defined (COMPACT_LEASES) + address_range = new_leases (max - min + 1, MDL); + if (!address_range) { ++ ++#if defined (LARGE_SUBNET) ++ if (!cfile && instantiate) { ++ return 0; ++ } ++#endif /*LARGE_SUBNET*/ ++ + strcpy (lowbuf, piaddr (low)); + strcpy (highbuf, piaddr (high)); + log_fatal ("No memory for address range %s-%s.", +@@ -611,12 +628,20 @@ + lease_reference (&lp, &address_range [i], MDL); + #else + status = lease_allocate (&lp, MDL); +- if (status != ISC_R_SUCCESS) ++ if (status != ISC_R_SUCCESS) { ++ ++#if defined (LARGE_SUBNET) ++ if (!cfile && instantiate) { ++ return i; ++ } ++#endif/*LARGE_SUBNET*/ ++ + log_fatal ("No memory for lease %s: %s", + piaddr (ip_addr (subnet -> net, + subnet -> netmask, + i + min)), + isc_result_totext (status)); ++ } + #endif + lp -> ip_addr = ip_addr (subnet -> net, + subnet -> netmask, i + min); +@@ -631,16 +656,39 @@ + /* Remember the lease in the IP address hash. */ + if (find_lease_by_ip_addr (<, lp -> ip_addr, MDL)) { + if (lt -> pool) { ++ ++#if defined (LARGE_SUBNET) ++ if (!cfile) ++ log_error ("lease %s is declared twice!", ++ piaddr (lp -> ip_addr)); ++ else ++#endif /*LARGE_SUBNET*/ ++ + parse_warn (cfile, + "lease %s is declared twice!", + piaddr (lp -> ip_addr)); + } else + pool_reference (< -> pool, pool, MDL); + lease_dereference (<, MDL); ++ ++#if defined (LARGE_SUBNET) ++ } else { ++ lease_ip_hash_add (lease_ip_addr_hash, ++ lp -> ip_addr.iabuf, ++ lp -> ip_addr.len, lp, MDL); ++ if (instantiate) { ++ log_debug ("instantiating lease: %u.%u.%u.%u", ++ lp -> ip_addr.iabuf[0], lp -> ip_addr.iabuf[1], lp -> ip_addr.iabuf[2], lp -> ip_addr.iabuf[3]); ++ lease_instantiate (NULL, 0, lp); ++ } ++ } ++#else /*LARGE_SUBNET*/ + } else + lease_ip_hash_add(lease_ip_addr_hash, + lp->ip_addr.iabuf, lp->ip_addr.len, + lp, MDL); ++#endif/*LARGE_SUBNET*/ ++ + /* Put the lease on the chain for the caller. */ + if (lpchain) { + if (*lpchain) { +@@ -651,6 +699,10 @@ + } + lease_dereference (&lp, MDL); + } ++ ++#if defined (LARGE_SUBNET) ++ return i; ++#endif /*LARGE_SUBNET*/ + } + + int find_subnet (struct subnet **sp, +diff -ruN dhcp-3.1.3-orig/server/omapi.c dhcp-3.1.3/server/omapi.c +--- dhcp-3.1.3-orig/server/omapi.c 2009-07-23 23:43:35.000000000 +0200 ++++ dhcp-3.1.3/server/omapi.c 2011-03-21 21:44:00.453534289 +0100 +@@ -1682,6 +1682,14 @@ + pool -> prohibit_list = (struct permit *)0; + #endif + ++#if defined (LARGE_SUBNET) ++ while (pool -> range) { ++ struct range *next = pool -> range -> next; ++ dfree (pool -> range, MDL); ++ pool -> range = next; ++ } ++#endif /*LARGE_SUBNET*/ ++ + return ISC_R_SUCCESS; + } + -- This is the pisa developer mailing list. Please also subscribe to the main pisa list at: //www.freelists.org/list/pisa