[pisa-src] r2467 - trunk/openwrt/patches/120-dhcp-ma-ap.patch

  • From: Rene Hummen <Rene.Hummen@xxxxxxxxxxxxxxxxxxxxx>
  • To: pisa-src@xxxxxxxxxxxxx
  • Date: Wed, 23 Mar 2011 11:14:05 +0100

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, &timestruct);
++
++                      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, &timestruct);
++
++      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 (&lt, 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 (&lt -> pool, pool, MDL);
+                       lease_dereference (&lt, 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

Other related posts: