This removes the need for the --max-routes option. Instead of
allocating a fixed size array for the route(-option)s they are
managed in linked lists instead.

Signed-off-by: Heiko Hund <heiko.h...@sophos.com>
---
 src/openvpn/init.c    |    4 +-
 src/openvpn/options.c |   33 ++-----
 src/openvpn/options.h |    3 +-
 src/openvpn/push.c    |    2 +-
 src/openvpn/route.c   |  227 ++++++++++++++++++++-----------------------------
 src/openvpn/route.h   |   38 ++++-----
 6 files changed, 123 insertions(+), 184 deletions(-)

diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index d324166..3b72b96 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -1167,9 +1167,9 @@ static void
 do_alloc_route_list (struct context *c)
 {
   if (!c->c1.route_list)
-    c->c1.route_list = new_route_list (c->options.max_routes, &c->gc);
+    ALLOC_OBJ_CLEAR_GC (c->c1.route_list, struct route_list, &c->gc);
   if (c->options.routes_ipv6 && !c->c1.route_ipv6_list)
-    c->c1.route_ipv6_list = new_route_ipv6_list (c->options.max_routes, 
&c->gc);
+    ALLOC_OBJ_CLEAR_GC (c->c1.route_ipv6_list, struct route_ipv6_list, &c->gc);
 }


diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 9e21d5a..ef6170c 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -218,8 +218,6 @@ static const char usage_message[] =
   "                  Add IPv6 route to routing table after connection\n"
   "                  is established.  Multiple routes can be specified.\n"
   "                  gateway default: taken from 'remote' in --ifconfig-ipv6\n"
-  "--max-routes n :  Specify the maximum number of routes that may be 
defined\n"
-  "                  or pulled from a server.\n"
   "--route-gateway gw|'dhcp' : Specify a default gateway for use with 
--route.\n"
   "--route-metric m : Specify a default metric for use with --route.\n"
   "--route-delay n [w] : Delay n seconds after connection initiation before\n"
@@ -796,7 +794,6 @@ init_options (struct options *o, const bool init_gc)
   o->ce.mtu_discover_type = -1;
   o->ce.mssfix = MSSFIX_DEFAULT;
   o->route_delay_window = 30;
-  o->max_routes = MAX_ROUTES_DEFAULT;
   o->resolve_retry_seconds = RESOLV_RETRY_INFINITE;
   o->proto_force = -1;
 #ifdef ENABLE_OCC
@@ -1340,14 +1337,14 @@ void
 rol_check_alloc (struct options *options)
 {
   if (!options->routes)
-    options->routes = new_route_option_list (options->max_routes, 
&options->gc);
+    options->routes = new_route_option_list (&options->gc);
 }

 void
 rol6_check_alloc (struct options *options)
 {
   if (!options->routes_ipv6)
-    options->routes_ipv6 = new_route_ipv6_option_list (options->max_routes, 
&options->gc);
+    options->routes_ipv6 = new_route_ipv6_option_list (&options->gc);
 }

 #ifdef ENABLE_CLIENT_NAT
@@ -1550,7 +1547,6 @@ show_settings (const struct options *o)
   SHOW_BOOL (route_delay_defined);
   SHOW_BOOL (route_nopull);
   SHOW_BOOL (route_gateway_via_dhcp);
-  SHOW_INT (max_routes);
   SHOW_BOOL (allow_pull_fqdn);
   if (o->routes)
     print_route_options (o->routes, D_SHOW_PARMS);
@@ -2829,7 +2825,7 @@ pre_pull_save (struct options *o)
 }

 void
-pre_pull_restore (struct options *o)
+pre_pull_restore (struct options *o, struct gc_arena *gc)
 {
   const struct options_pre_pull *pp = o->pre_pull;
   if (pp)
@@ -2841,7 +2837,7 @@ pre_pull_restore (struct options *o)
       if (pp->routes_defined)
        {
          rol_check_alloc (o);
-         copy_route_option_list (o->routes, pp->routes);
+         copy_route_option_list (o->routes, pp->routes, gc);
        }
       else
        o->routes = NULL;
@@ -2849,7 +2845,7 @@ pre_pull_restore (struct options *o)
       if (pp->routes_ipv6_defined)
        {
          rol6_check_alloc (o);
-         copy_route_ipv6_option_list (o->routes_ipv6, pp->routes_ipv6);
+         copy_route_ipv6_option_list (o->routes_ipv6, pp->routes_ipv6, gc);
        }
       else
        o->routes_ipv6 = NULL;
@@ -5227,23 +5223,10 @@ add_option (struct options *options,
        }
       add_route_ipv6_to_option_list (options->routes_ipv6, p[1], p[2], p[3]);
     }
-  else if (streq (p[0], "max-routes") && p[1])
+  else if (streq (p[0], "max-routes"))
     {
-      int max_routes;
-
-      VERIFY_PERMISSION (OPT_P_GENERAL);
-      max_routes = atoi (p[1]);
-      if (max_routes < 0 || max_routes > 100000000)
-       {
-         msg (msglevel, "--max-routes parameter is out of range");
-         goto err;
-       }
-      if (options->routes || options->routes_ipv6)
-        {
-          msg (msglevel, "--max-routes must to be specifed before any 
route/route-ipv6/redirect-gateway option");
-          goto err;
-        }
-      options->max_routes = max_routes;
+      msg (msglevel, "--max-routes option ignored. The number of routes is 
unlimited as of version 2.4. "
+           "This option will be removed in a future version, please remove it 
from your configuration.");
     }
   else if (streq (p[0], "route-gateway") && p[1])
     {
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index bf232f4..27bbc14 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -343,7 +343,6 @@ struct options
   int route_delay;
   int route_delay_window;
   bool route_delay_defined;
-  int max_routes;
   struct route_option_list *routes;
   struct route_ipv6_option_list *routes_ipv6;                  /* IPv6 */
   bool route_nopull;
@@ -715,7 +714,7 @@ void options_warning (char *actual, const char *expected);
 void options_postprocess (struct options *options);

 void pre_pull_save (struct options *o);
-void pre_pull_restore (struct options *o);
+void pre_pull_restore (struct options *o, struct gc_arena *gc);

 bool apply_push_options (struct options *options,
                         struct buffer *buf,
diff --git a/src/openvpn/push.c b/src/openvpn/push.c
index e971357..606bb05 100644
--- a/src/openvpn/push.c
+++ b/src/openvpn/push.c
@@ -456,7 +456,7 @@ process_incoming_push_msg (struct context *c,
            }
          if (!c->c2.did_pre_pull_restore)
            {
-             pre_pull_restore (&c->options);
+             pre_pull_restore (&c->options, &c->c2.gc);
              c->c2.did_pre_pull_restore = true;
            }
          if (apply_push_options (&c->options,
diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index d397f11..6b178f9 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -92,76 +92,55 @@ add_bypass_address (struct route_bypass *rb, const 
in_addr_t a)
 }

 struct route_option_list *
-new_route_option_list (const int max_routes, struct gc_arena *a)
+new_route_option_list (struct gc_arena *a)
 {
   struct route_option_list *ret;
-  ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_option_list, struct 
route_option, max_routes, a);
-  ret->capacity = max_routes;
+  ALLOC_OBJ_CLEAR_GC (ret, struct route_option_list, a);
+  ret->gc = a;
   return ret;
 }

 struct route_ipv6_option_list *
-new_route_ipv6_option_list (const int max_routes, struct gc_arena *a)
+new_route_ipv6_option_list (struct gc_arena *a)
 {
   struct route_ipv6_option_list *ret;
-  ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_option_list, struct 
route_ipv6_option, max_routes, a);
-  ret->capacity = max_routes;
+  ALLOC_OBJ_CLEAR_GC (ret, struct route_ipv6_option_list, a);
+  ret->gc = a;
   return ret;
 }

 struct route_option_list *
 clone_route_option_list (const struct route_option_list *src, struct gc_arena 
*a)
 {
-  const size_t rl_size = array_mult_safe (sizeof(struct route_option), 
src->capacity, sizeof(struct route_option_list));
-  struct route_option_list *ret = gc_malloc (rl_size, false, a);
-  memcpy (ret, src, rl_size);
+  struct route_option_list *ret;
+  ALLOC_OBJ_GC (ret, struct route_option_list, a);
+  *ret = *src;
   return ret;
 }

 struct route_ipv6_option_list *
 clone_route_ipv6_option_list (const struct route_ipv6_option_list *src, struct 
gc_arena *a)
 {
-  const size_t rl_size = array_mult_safe (sizeof(struct route_ipv6_option), 
src->capacity, sizeof(struct route_ipv6_option_list));
-  struct route_ipv6_option_list *ret = gc_malloc (rl_size, false, a);
-  memcpy (ret, src, rl_size);
+  struct route_ipv6_option_list *ret;
+  ALLOC_OBJ_GC (ret, struct route_ipv6_option_list, a);
+  *ret = *src;
   return ret;
 }

 void
-copy_route_option_list (struct route_option_list *dest, const struct 
route_option_list *src)
+copy_route_option_list (struct route_option_list *dest, const struct 
route_option_list *src, struct gc_arena *a)
 {
-  const size_t src_size = array_mult_safe (sizeof(struct route_option), 
src->capacity, sizeof(struct route_option_list));
-  if (src->capacity > dest->capacity)
-    msg (M_FATAL, PACKAGE_NAME " ROUTE: (copy) number of route options in src 
(%d) is greater than route list capacity in dest (%d)", src->capacity, 
dest->capacity);
-  memcpy (dest, src, src_size);
+  *dest = *src;
+  dest->gc = a;
 }

 void
 copy_route_ipv6_option_list (struct route_ipv6_option_list *dest,
-                            const struct route_ipv6_option_list *src)
-{
-  const size_t src_size = array_mult_safe (sizeof(struct route_ipv6_option), 
src->capacity, sizeof(struct route_ipv6_option_list));
-  if (src->capacity > dest->capacity)
-    msg (M_FATAL, PACKAGE_NAME " ROUTE: (copy) number of route options in src 
(%d) is greater than route list capacity in dest (%d)", src->capacity, 
dest->capacity);
-  memcpy (dest, src, src_size);
-}
-
-struct route_list *
-new_route_list (const int max_routes, struct gc_arena *a)
-{
-  struct route_list *ret;
-  ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_list, struct route_ipv4, 
max_routes, a);
-  ret->capacity = max_routes;
-  return ret;
-}
-
-struct route_ipv6_list *
-new_route_ipv6_list (const int max_routes, struct gc_arena *a)
+                             const struct route_ipv6_option_list *src,
+                             struct gc_arena *a)
 {
-  struct route_ipv6_list *ret;
-  ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_list, struct route_ipv6, 
max_routes, a);
-  ret->capacity = max_routes;
-  return ret;
+  *dest = *src;
+  dest->gc = a;
 }

 static const char *
@@ -452,15 +431,14 @@ add_route_to_option_list (struct route_option_list *l,
                          const char *metric)
 {
   struct route_option *ro;
-  if (l->n >= l->capacity)
-    msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d routes -- 
please increase the max-routes option in the client configuration file",
-        l->capacity);
-  ro = &l->routes[l->n];
+  ALLOC_OBJ_GC (ro, struct route_option, l->gc);
   ro->network = network;
   ro->netmask = netmask;
   ro->gateway = gateway;
   ro->metric = metric;
-  ++l->n;
+  ro->next = l->routes;
+  l->routes = ro;
+
 }

 void
@@ -470,32 +448,26 @@ add_route_ipv6_to_option_list (struct 
route_ipv6_option_list *l,
                          const char *metric)
 {
   struct route_ipv6_option *ro;
-  if (l->n >= l->capacity)
-    msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d IPv6 routes -- 
please increase the max-routes option in the client configuration file",
-        l->capacity);
-  ro = &l->routes_ipv6[l->n];
+  ALLOC_OBJ_GC (ro, struct route_ipv6_option, l->gc);
   ro->prefix = prefix;
   ro->gateway = gateway;
   ro->metric = metric;
-  ++l->n;
+  ro->next = l->routes_ipv6;
+  l->routes_ipv6 = ro;
 }

 void
 clear_route_list (struct route_list *rl)
 {
-  const int capacity = rl->capacity;
-  const size_t rl_size = array_mult_safe (sizeof(struct route_ipv4), capacity, 
sizeof(struct route_list));
-  memset(rl, 0, rl_size);
-  rl->capacity = capacity;
+  gc_free (&rl->gc);
+  CLEAR (*rl);
 }

 void
 clear_route_ipv6_list (struct route_ipv6_list *rl6)
 {
-  const int capacity = rl6->capacity;
-  const size_t rl6_size = array_mult_safe (sizeof(struct route_ipv6), 
capacity, sizeof(struct route_ipv6_list));
-  memset(rl6, 0, rl6_size);
-  rl6->capacity = capacity;
+  gc_free (&rl6->gc);
+  CLEAR (*rl6);
 }

 void
@@ -516,22 +488,27 @@ add_block_local_item (struct route_list *rl,
 {
   const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
   if ((rl->rgi.flags & rgi_needed) == rgi_needed
-      && rl->rgi.gateway.netmask < 0xFFFFFFFF
-      && (rl->n)+2 <= rl->capacity)
+      && rl->rgi.gateway.netmask < 0xFFFFFFFF)
     {
-      struct route_ipv4 r;
+      struct route_ipv4 *r1, *r2;
       unsigned int l2;

+      ALLOC_OBJ_GC (r1, struct route_ipv4, &rl->gc);
+      ALLOC_OBJ_GC (r2, struct route_ipv4, &rl->gc);
+
       /* split a route into two smaller blocking routes, and direct them to 
target */
-      CLEAR(r);
-      r.flags = RT_DEFINED;
-      r.gateway = target;
-      r.network = gateway->addr & gateway->netmask;
       l2 = ((~gateway->netmask)+1)>>1;
-      r.netmask = ~(l2-1);
-      rl->routes[rl->n++] = r;
-      r.network += l2;
-      rl->routes[rl->n++] = r;
+      r1->flags = RT_DEFINED;
+      r1->gateway = target;
+      r1->network = gateway->addr & gateway->netmask;
+      r1->netmask = ~(l2-1);
+      r1->next = rl->routes;
+      rl->routes = r1;
+
+      *r2 = *r1;
+      r2->network += l2;
+      r2->next = rl->routes;
+      rl->routes = r2;
     }
 }

@@ -643,42 +620,29 @@ init_route_list (struct route_list *rl,

   /* parse the routes from opt to rl */
   {
-    int i = 0;
-    int j = rl->n;
-    bool warned = false;
-    for (i = 0; i < opt->n; ++i)
+    struct route_option *ro;
+    for (ro = opt->routes; ro; ro = ro->next)
       {
         struct addrinfo* netlist;
        struct route_ipv4 r;

-       if (!init_route (&r,
-                        &netlist,
-                        &opt->routes[i],
-                        rl))
+       if (!init_route (&r, &netlist, ro, rl))
          ret = false;
        else
          {
             struct addrinfo* curele;
             for (curele        = netlist; curele; curele = curele->ai_next)
              {
-               if (j < rl->capacity)
-                 {
-                    r.network = ntohl(((struct 
sockaddr_in*)(curele)->ai_addr)->sin_addr.s_addr);
-                   rl->routes[j++] = r;
-                 }
-               else
-                 {
-                   if (!warned)
-                     {
-                       msg (M_WARN, PACKAGE_NAME " ROUTE: routes dropped 
because number of expanded routes is greater than route list capacity (%d)", 
rl->capacity);
-                       warned = true;
-                     }
-                 }
+                struct route_ipv4 *new;
+                ALLOC_OBJ_GC (new, struct route_ipv4, &rl->gc);
+                *new = r;
+                new->network = ntohl (((struct 
sockaddr_in*)curele->ai_addr)->sin_addr.s_addr);
+                new->next = rl->routes;
+                rl->routes = new;
              }
             freeaddrinfo(netlist);
          }
       }
-    rl->n = j;
   }

   gc_free (&gc);
@@ -729,22 +693,21 @@ init_route_ipv6_list (struct route_ipv6_list *rl6,
     rl6->remote_endpoint_defined = false;


-  if (!(opt6->n >= 0 && opt6->n <= rl6->capacity))
-    msg (M_FATAL, PACKAGE_NAME " ROUTE6: (init) number of route options (%d) 
is greater than route list capacity (%d)", opt6->n, rl6->capacity);
-
-  /* parse the routes from opt to rl6 */
+  /* parse the routes from opt6 to rl6 */
   {
-    int i, j = 0;
-    for (i = 0; i < opt6->n; ++i)
+    struct route_ipv6_option *ro6;
+    for (ro6 = opt6->routes_ipv6; ro6; ro6 = ro6->next)
       {
-       if (!init_route_ipv6 (&rl6->routes_ipv6[j],
-                             &opt6->routes_ipv6[i],
-                             rl6 ))
+        struct route_ipv6 *r6;
+        ALLOC_OBJ_GC (r6, struct route_ipv6, &rl6->gc);
+        if (!init_route_ipv6 (r6, ro6, rl6))
          ret = false;
        else
-         ++j;
+          {
+            r6->next = rl6->routes_ipv6;
+            rl6->routes_ipv6 = r6;
+          }
       }
-    rl6->n = j;
   }

   gc_free (&gc);
@@ -1013,10 +976,10 @@ add_routes (struct route_list *rl, struct 
route_ipv6_list *rl6, const struct tun
   redirect_default_route_to_vpn (rl, tt, flags, es);
   if ( rl && !(rl->iflags & RL_ROUTES_ADDED) )
     {
-      int i;
+      struct route_ipv4 *r;

 #ifdef ENABLE_MANAGEMENT
-      if (management && rl->n)
+      if (management && rl->routes)
        {
          management_set_state (management,
                                OPENVPN_STATE_ADD_ROUTES,
@@ -1025,10 +988,9 @@ add_routes (struct route_list *rl, struct route_ipv6_list 
*rl6, const struct tun
                                0);
        }
 #endif
-      
-      for (i = 0; i < rl->n; ++i)
+
+      for (r = rl->routes; r; r = r->next)
        {
-         struct route_ipv4 *r = &rl->routes[i];
          check_subnet_conflict (r->network, r->netmask, "route");
          if (flags & ROUTE_DELETE_FIRST)
            delete_route (r, tt, flags, &rl->rgi, es);
@@ -1038,11 +1000,9 @@ add_routes (struct route_list *rl, struct 
route_ipv6_list *rl6, const struct tun
     }
   if (rl6 && !rl6->routes_added)
     {
-      int i;
-
-      for (i = 0; i < rl6->n; ++i)
+      struct route_ipv6 *r;
+      for (r = rl6->routes_ipv6; r; r = r->next)
        {
-         struct route_ipv6 *r = &rl6->routes_ipv6[i];
          if (flags & ROUTE_DELETE_FIRST)
            delete_route_ipv6 (r, tt, flags, es);
          add_route_ipv6 (r, tt, flags, es);
@@ -1057,10 +1017,9 @@ delete_routes (struct route_list *rl, struct 
route_ipv6_list *rl6,
 {
   if ( rl && rl->iflags & RL_ROUTES_ADDED )
     {
-      int i;
-      for (i = rl->n - 1; i >= 0; --i)
+      struct route_ipv4 *r;
+      for (r = rl->routes; r; r = r->next)
        {
-         struct route_ipv4 * r = &rl->routes[i];
          delete_route (r, tt, flags, &rl->rgi, es);
        }
       rl->iflags &= ~RL_ROUTES_ADDED;
@@ -1075,10 +1034,9 @@ delete_routes (struct route_list *rl, struct 
route_ipv6_list *rl6,

   if ( rl6 && rl6->routes_added )
     {
-      int i;
-      for (i = rl6->n - 1; i >= 0; --i)
+      struct route_ipv6 *r6;
+      for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
        {
-         const struct route_ipv6 *r6 = &rl6->routes_ipv6[i];
          delete_route_ipv6 (r6, tt, flags, es);
        }
       rl6->routes_added = false;
@@ -1115,12 +1073,12 @@ void
 print_route_options (const struct route_option_list *rol,
                     int level)
 {
-  int i;
+  struct route_option *ro;
   if (rol->flags & RG_ENABLE)
     msg (level, "  [redirect_default_gateway local=%d]",
         (rol->flags & RG_LOCAL) != 0);
-  for (i = 0; i < rol->n; ++i)
-    print_route_option (&rol->routes[i], level);
+  for (ro = rol->routes; ro; ro = ro->next)
+    print_route_option (ro, level);
 }

 void
@@ -1165,9 +1123,9 @@ print_route (const struct route_ipv4 *r, int level)
 void
 print_routes (const struct route_list *rl, int level)
 {
-  int i;
-  for (i = 0; i < rl->n; ++i)
-    print_route (&rl->routes[i], level);
+  struct route_ipv4 *r;
+  for (r = rl->routes; r; r = r->next)
+    print_route (r, level);
 }

 static void
@@ -1193,9 +1151,10 @@ setenv_route (struct env_set *es, const struct 
route_ipv4 *r, int i)
 void
 setenv_routes (struct env_set *es, const struct route_list *rl)
 {
-  int i;
-  for (i = 0; i < rl->n; ++i)
-    setenv_route (es, &rl->routes[i], i + 1);
+  int i = 1;
+  struct route_ipv4 *r;
+  for (r = rl->routes; r; r = r->next)
+    setenv_route (es, r, i++);
 }

 static void
@@ -1221,9 +1180,10 @@ setenv_route_ipv6 (struct env_set *es, const struct 
route_ipv6 *r6, int i)
 void
 setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6)
 {
-  int i;
-  for (i = 0; i < rl6->n; ++i)
-    setenv_route_ipv6 (es, &rl6->routes_ipv6[i], i + 1);
+  int i = 1;
+  struct route_ipv6 *r6;
+  for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
+    setenv_route_ipv6 (es, r6, i++);
 }

 /*
@@ -2137,6 +2097,7 @@ test_routes (const struct route_list *rl, const struct 
tuntap *tt)
   int count = 0;
   int good = 0;
   int ambig = 0;
+  int len = -1;
   bool adapter_up = false;

   if (is_adapter_up (tt, adapters))
@@ -2146,9 +2107,9 @@ test_routes (const struct route_list *rl, const struct 
tuntap *tt)

       if (rl)
        {
-         int i;
-         for (i = 0; i < rl->n; ++i)
-           test_route_helper (&ret, &count, &good, &ambig, adapters, 
rl->routes[i].gateway);
+         struct route *r;
+         for (r = rl->routes, len = 0; r; r = r->next, ++len)
+           test_route_helper (&ret, &count, &good, &ambig, adapters, 
r->gateway);

          if ((rl->flags & RG_ENABLE) && (rl->spec.flags & 
RTSA_REMOTE_ENDPOINT))
            test_route_helper (&ret, &count, &good, &ambig, adapters, 
rl->spec.remote_endpoint);
@@ -2158,7 +2119,7 @@ test_routes (const struct route_list *rl, const struct 
tuntap *tt)
   msg (D_ROUTE, "TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s",
        good,
        count,
-       rl ? rl->n : -1,
+       len,
        (int)ret,
        ambig,
        adapter_up ? "up" : "down");
diff --git a/src/openvpn/route.h b/src/openvpn/route.h
index fe9b461..ffa101a 100644
--- a/src/openvpn/route.h
+++ b/src/openvpn/route.h
@@ -33,8 +33,6 @@
 #include "tun.h"
 #include "misc.h"

-#define MAX_ROUTES_DEFAULT 100
-
 #ifdef WIN32
 /*
  * Windows route methods
@@ -74,6 +72,7 @@ struct route_special_addr
 };

 struct route_option {
+  struct route_option *next;
   const char *network;
   const char *netmask;
   const char *gateway;
@@ -92,12 +91,12 @@ struct route_option {

 struct route_option_list {
   unsigned int flags;  /* RG_x flags */
-  int capacity;
-  int n;
-  struct route_option routes[EMPTY_ARRAY_SIZE];
+  struct route_option *routes;
+  struct gc_arena *gc;
 };

 struct route_ipv6_option {
+  struct route_ipv6_option *next;
   const char *prefix;          /* e.g. "2001:db8:1::/64" */
   const char *gateway;         /* e.g. "2001:db8:0::2" */
   const char *metric;          /* e.g. "5" */
@@ -105,15 +104,15 @@ struct route_ipv6_option {

 struct route_ipv6_option_list {
   unsigned int flags;
-  int capacity;
-  int n;
-  struct route_ipv6_option routes_ipv6[EMPTY_ARRAY_SIZE];
+  struct route_ipv6_option *routes_ipv6;
+  struct gc_arena *gc;
 };

 struct route_ipv4 {
 # define RT_DEFINED        (1<<0)
 # define RT_ADDED          (1<<1)
 # define RT_METRIC_DEFINED (1<<2)
+  struct route *next;
   unsigned int flags;
   const struct route_option *option;
   in_addr_t network;
@@ -123,6 +122,7 @@ struct route_ipv4 {
 };

 struct route_ipv6 {
+  struct route_ipv6 *next;
   bool defined;
   struct in6_addr network;
   unsigned int netbits;
@@ -140,9 +140,8 @@ struct route_ipv6_list {
   bool remote_endpoint_defined;
   bool did_redirect_default_gateway;                   /* TODO (?) */
   bool did_local;                                      /* TODO (?) */
-  int capacity;
-  int n;
-  struct route_ipv6 routes_ipv6[EMPTY_ARRAY_SIZE];
+  struct route_ipv6 *routes_ipv6;
+  struct gc_arena gc;
 };


@@ -188,9 +187,8 @@ struct route_list {
   struct route_special_addr spec;
   struct route_gateway_info rgi;
   unsigned int flags;     /* RG_x flags */
-  int capacity;
-  int n;
-  struct route_ipv4 routes[EMPTY_ARRAY_SIZE];
+  struct route_ipv4 *routes;
+  struct gc_arena gc;
 };

 #if P2MP
@@ -208,17 +206,15 @@ struct iroute_ipv6 {
 };
 #endif

-struct route_option_list *new_route_option_list (const int max_routes, struct 
gc_arena *a);
-struct route_ipv6_option_list *new_route_ipv6_option_list (const int 
max_routes, struct gc_arena *a);
+struct route_option_list *new_route_option_list (struct gc_arena *a);
+struct route_ipv6_option_list *new_route_ipv6_option_list (struct gc_arena *a);

 struct route_option_list *clone_route_option_list (const struct 
route_option_list *src, struct gc_arena *a);
 struct route_ipv6_option_list *clone_route_ipv6_option_list (const struct 
route_ipv6_option_list *src, struct gc_arena *a);
-void copy_route_option_list (struct route_option_list *dest, const struct 
route_option_list *src);
+void copy_route_option_list (struct route_option_list *dest, const struct 
route_option_list *src, struct gc_arena *a);
 void copy_route_ipv6_option_list (struct route_ipv6_option_list *dest,
-                                 const struct route_ipv6_option_list *src);
-
-struct route_list *new_route_list (const int max_routes, struct gc_arena *a);
-struct route_ipv6_list *new_route_ipv6_list (const int max_routes, struct 
gc_arena *a);
+                                  const struct route_ipv6_option_list *src,
+                                  struct gc_arena *a);

 void add_route_ipv6 (struct route_ipv6 *r, const struct tuntap *tt, unsigned 
int flags, const struct env_set *es);
 void delete_route_ipv6 (const struct route_ipv6 *r, const struct tuntap *tt, 
unsigned int flags, const struct env_set *es);
-- 
1.7.9.5


Reply via email to