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.hund@sophos.com>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1392746395-19246-1-git-send-email-heiko.hund@sophos.com>
URL: http://article.gmane.org/gmane.network.openvpn.devel/8295
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -1167,9 +1167,9 @@ static void |
1167 | 1167 |
do_alloc_route_list (struct context *c) |
1168 | 1168 |
{ |
1169 | 1169 |
if (!c->c1.route_list) |
1170 |
- c->c1.route_list = new_route_list (c->options.max_routes, &c->gc); |
|
1170 |
+ ALLOC_OBJ_CLEAR_GC (c->c1.route_list, struct route_list, &c->gc); |
|
1171 | 1171 |
if (c->options.routes_ipv6 && !c->c1.route_ipv6_list) |
1172 |
- c->c1.route_ipv6_list = new_route_ipv6_list (c->options.max_routes, &c->gc); |
|
1172 |
+ ALLOC_OBJ_CLEAR_GC (c->c1.route_ipv6_list, struct route_ipv6_list, &c->gc); |
|
1173 | 1173 |
} |
1174 | 1174 |
|
1175 | 1175 |
|
... | ... |
@@ -218,8 +218,6 @@ static const char usage_message[] = |
218 | 218 |
" Add IPv6 route to routing table after connection\n" |
219 | 219 |
" is established. Multiple routes can be specified.\n" |
220 | 220 |
" gateway default: taken from 'remote' in --ifconfig-ipv6\n" |
221 |
- "--max-routes n : Specify the maximum number of routes that may be defined\n" |
|
222 |
- " or pulled from a server.\n" |
|
223 | 221 |
"--route-gateway gw|'dhcp' : Specify a default gateway for use with --route.\n" |
224 | 222 |
"--route-metric m : Specify a default metric for use with --route.\n" |
225 | 223 |
"--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) |
796 | 796 |
o->ce.mtu_discover_type = -1; |
797 | 797 |
o->ce.mssfix = MSSFIX_DEFAULT; |
798 | 798 |
o->route_delay_window = 30; |
799 |
- o->max_routes = MAX_ROUTES_DEFAULT; |
|
800 | 799 |
o->resolve_retry_seconds = RESOLV_RETRY_INFINITE; |
801 | 800 |
o->proto_force = -1; |
802 | 801 |
#ifdef ENABLE_OCC |
... | ... |
@@ -1340,14 +1337,14 @@ void |
1340 | 1340 |
rol_check_alloc (struct options *options) |
1341 | 1341 |
{ |
1342 | 1342 |
if (!options->routes) |
1343 |
- options->routes = new_route_option_list (options->max_routes, &options->gc); |
|
1343 |
+ options->routes = new_route_option_list (&options->gc); |
|
1344 | 1344 |
} |
1345 | 1345 |
|
1346 | 1346 |
void |
1347 | 1347 |
rol6_check_alloc (struct options *options) |
1348 | 1348 |
{ |
1349 | 1349 |
if (!options->routes_ipv6) |
1350 |
- options->routes_ipv6 = new_route_ipv6_option_list (options->max_routes, &options->gc); |
|
1350 |
+ options->routes_ipv6 = new_route_ipv6_option_list (&options->gc); |
|
1351 | 1351 |
} |
1352 | 1352 |
|
1353 | 1353 |
#ifdef ENABLE_CLIENT_NAT |
... | ... |
@@ -1550,7 +1547,6 @@ show_settings (const struct options *o) |
1550 | 1550 |
SHOW_BOOL (route_delay_defined); |
1551 | 1551 |
SHOW_BOOL (route_nopull); |
1552 | 1552 |
SHOW_BOOL (route_gateway_via_dhcp); |
1553 |
- SHOW_INT (max_routes); |
|
1554 | 1553 |
SHOW_BOOL (allow_pull_fqdn); |
1555 | 1554 |
if (o->routes) |
1556 | 1555 |
print_route_options (o->routes, D_SHOW_PARMS); |
... | ... |
@@ -2829,7 +2825,7 @@ pre_pull_save (struct options *o) |
2829 | 2829 |
} |
2830 | 2830 |
|
2831 | 2831 |
void |
2832 |
-pre_pull_restore (struct options *o) |
|
2832 |
+pre_pull_restore (struct options *o, struct gc_arena *gc) |
|
2833 | 2833 |
{ |
2834 | 2834 |
const struct options_pre_pull *pp = o->pre_pull; |
2835 | 2835 |
if (pp) |
... | ... |
@@ -2841,7 +2837,7 @@ pre_pull_restore (struct options *o) |
2841 | 2841 |
if (pp->routes_defined) |
2842 | 2842 |
{ |
2843 | 2843 |
rol_check_alloc (o); |
2844 |
- copy_route_option_list (o->routes, pp->routes); |
|
2844 |
+ copy_route_option_list (o->routes, pp->routes, gc); |
|
2845 | 2845 |
} |
2846 | 2846 |
else |
2847 | 2847 |
o->routes = NULL; |
... | ... |
@@ -2849,7 +2845,7 @@ pre_pull_restore (struct options *o) |
2849 | 2849 |
if (pp->routes_ipv6_defined) |
2850 | 2850 |
{ |
2851 | 2851 |
rol6_check_alloc (o); |
2852 |
- copy_route_ipv6_option_list (o->routes_ipv6, pp->routes_ipv6); |
|
2852 |
+ copy_route_ipv6_option_list (o->routes_ipv6, pp->routes_ipv6, gc); |
|
2853 | 2853 |
} |
2854 | 2854 |
else |
2855 | 2855 |
o->routes_ipv6 = NULL; |
... | ... |
@@ -5227,23 +5223,10 @@ add_option (struct options *options, |
5227 | 5227 |
} |
5228 | 5228 |
add_route_ipv6_to_option_list (options->routes_ipv6, p[1], p[2], p[3]); |
5229 | 5229 |
} |
5230 |
- else if (streq (p[0], "max-routes") && p[1]) |
|
5230 |
+ else if (streq (p[0], "max-routes")) |
|
5231 | 5231 |
{ |
5232 |
- int max_routes; |
|
5233 |
- |
|
5234 |
- VERIFY_PERMISSION (OPT_P_GENERAL); |
|
5235 |
- max_routes = atoi (p[1]); |
|
5236 |
- if (max_routes < 0 || max_routes > 100000000) |
|
5237 |
- { |
|
5238 |
- msg (msglevel, "--max-routes parameter is out of range"); |
|
5239 |
- goto err; |
|
5240 |
- } |
|
5241 |
- if (options->routes || options->routes_ipv6) |
|
5242 |
- { |
|
5243 |
- msg (msglevel, "--max-routes must to be specifed before any route/route-ipv6/redirect-gateway option"); |
|
5244 |
- goto err; |
|
5245 |
- } |
|
5246 |
- options->max_routes = max_routes; |
|
5232 |
+ msg (msglevel, "--max-routes option ignored. The number of routes is unlimited as of version 2.4. " |
|
5233 |
+ "This option will be removed in a future version, please remove it from your configuration."); |
|
5247 | 5234 |
} |
5248 | 5235 |
else if (streq (p[0], "route-gateway") && p[1]) |
5249 | 5236 |
{ |
... | ... |
@@ -343,7 +343,6 @@ struct options |
343 | 343 |
int route_delay; |
344 | 344 |
int route_delay_window; |
345 | 345 |
bool route_delay_defined; |
346 |
- int max_routes; |
|
347 | 346 |
struct route_option_list *routes; |
348 | 347 |
struct route_ipv6_option_list *routes_ipv6; /* IPv6 */ |
349 | 348 |
bool route_nopull; |
... | ... |
@@ -715,7 +714,7 @@ void options_warning (char *actual, const char *expected); |
715 | 715 |
void options_postprocess (struct options *options); |
716 | 716 |
|
717 | 717 |
void pre_pull_save (struct options *o); |
718 |
-void pre_pull_restore (struct options *o); |
|
718 |
+void pre_pull_restore (struct options *o, struct gc_arena *gc); |
|
719 | 719 |
|
720 | 720 |
bool apply_push_options (struct options *options, |
721 | 721 |
struct buffer *buf, |
... | ... |
@@ -456,7 +456,7 @@ process_incoming_push_msg (struct context *c, |
456 | 456 |
} |
457 | 457 |
if (!c->c2.did_pre_pull_restore) |
458 | 458 |
{ |
459 |
- pre_pull_restore (&c->options); |
|
459 |
+ pre_pull_restore (&c->options, &c->c2.gc); |
|
460 | 460 |
c->c2.did_pre_pull_restore = true; |
461 | 461 |
} |
462 | 462 |
if (apply_push_options (&c->options, |
... | ... |
@@ -92,76 +92,62 @@ add_bypass_address (struct route_bypass *rb, const in_addr_t a) |
92 | 92 |
} |
93 | 93 |
|
94 | 94 |
struct route_option_list * |
95 |
-new_route_option_list (const int max_routes, struct gc_arena *a) |
|
95 |
+new_route_option_list (struct gc_arena *a) |
|
96 | 96 |
{ |
97 | 97 |
struct route_option_list *ret; |
98 |
- ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_option_list, struct route_option, max_routes, a); |
|
99 |
- ret->capacity = max_routes; |
|
98 |
+ ALLOC_OBJ_CLEAR_GC (ret, struct route_option_list, a); |
|
99 |
+ ret->gc = a; |
|
100 | 100 |
return ret; |
101 | 101 |
} |
102 | 102 |
|
103 | 103 |
struct route_ipv6_option_list * |
104 |
-new_route_ipv6_option_list (const int max_routes, struct gc_arena *a) |
|
104 |
+new_route_ipv6_option_list (struct gc_arena *a) |
|
105 | 105 |
{ |
106 | 106 |
struct route_ipv6_option_list *ret; |
107 |
- ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_option_list, struct route_ipv6_option, max_routes, a); |
|
108 |
- ret->capacity = max_routes; |
|
107 |
+ ALLOC_OBJ_CLEAR_GC (ret, struct route_ipv6_option_list, a); |
|
108 |
+ ret->gc = a; |
|
109 | 109 |
return ret; |
110 | 110 |
} |
111 | 111 |
|
112 |
+/* |
|
113 |
+ * NOTE: structs are cloned/copied shallow by design. |
|
114 |
+ * The routes list from src will stay intact since it is allocated using |
|
115 |
+ * the options->gc. The cloned/copied lists will share this common tail |
|
116 |
+ * to avoid copying the data around between pulls. Pulled routes use |
|
117 |
+ * the c2->gc so they get freed immediately after a reconnect. |
|
118 |
+ */ |
|
112 | 119 |
struct route_option_list * |
113 | 120 |
clone_route_option_list (const struct route_option_list *src, struct gc_arena *a) |
114 | 121 |
{ |
115 |
- const size_t rl_size = array_mult_safe (sizeof(struct route_option), src->capacity, sizeof(struct route_option_list)); |
|
116 |
- struct route_option_list *ret = gc_malloc (rl_size, false, a); |
|
117 |
- memcpy (ret, src, rl_size); |
|
122 |
+ struct route_option_list *ret; |
|
123 |
+ ALLOC_OBJ_GC (ret, struct route_option_list, a); |
|
124 |
+ *ret = *src; |
|
118 | 125 |
return ret; |
119 | 126 |
} |
120 | 127 |
|
121 | 128 |
struct route_ipv6_option_list * |
122 | 129 |
clone_route_ipv6_option_list (const struct route_ipv6_option_list *src, struct gc_arena *a) |
123 | 130 |
{ |
124 |
- const size_t rl_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list)); |
|
125 |
- struct route_ipv6_option_list *ret = gc_malloc (rl_size, false, a); |
|
126 |
- memcpy (ret, src, rl_size); |
|
131 |
+ struct route_ipv6_option_list *ret; |
|
132 |
+ ALLOC_OBJ_GC (ret, struct route_ipv6_option_list, a); |
|
133 |
+ *ret = *src; |
|
127 | 134 |
return ret; |
128 | 135 |
} |
129 | 136 |
|
130 | 137 |
void |
131 |
-copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src) |
|
138 |
+copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src, struct gc_arena *a) |
|
132 | 139 |
{ |
133 |
- const size_t src_size = array_mult_safe (sizeof(struct route_option), src->capacity, sizeof(struct route_option_list)); |
|
134 |
- if (src->capacity > dest->capacity) |
|
135 |
- 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); |
|
136 |
- memcpy (dest, src, src_size); |
|
140 |
+ *dest = *src; |
|
141 |
+ dest->gc = a; |
|
137 | 142 |
} |
138 | 143 |
|
139 | 144 |
void |
140 | 145 |
copy_route_ipv6_option_list (struct route_ipv6_option_list *dest, |
141 |
- const struct route_ipv6_option_list *src) |
|
146 |
+ const struct route_ipv6_option_list *src, |
|
147 |
+ struct gc_arena *a) |
|
142 | 148 |
{ |
143 |
- const size_t src_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list)); |
|
144 |
- if (src->capacity > dest->capacity) |
|
145 |
- 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); |
|
146 |
- memcpy (dest, src, src_size); |
|
147 |
-} |
|
148 |
- |
|
149 |
-struct route_list * |
|
150 |
-new_route_list (const int max_routes, struct gc_arena *a) |
|
151 |
-{ |
|
152 |
- struct route_list *ret; |
|
153 |
- ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_list, struct route_ipv4, max_routes, a); |
|
154 |
- ret->capacity = max_routes; |
|
155 |
- return ret; |
|
156 |
-} |
|
157 |
- |
|
158 |
-struct route_ipv6_list * |
|
159 |
-new_route_ipv6_list (const int max_routes, struct gc_arena *a) |
|
160 |
-{ |
|
161 |
- struct route_ipv6_list *ret; |
|
162 |
- ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_list, struct route_ipv6, max_routes, a); |
|
163 |
- ret->capacity = max_routes; |
|
164 |
- return ret; |
|
149 |
+ *dest = *src; |
|
150 |
+ dest->gc = a; |
|
165 | 151 |
} |
166 | 152 |
|
167 | 153 |
static const char * |
... | ... |
@@ -452,15 +438,14 @@ add_route_to_option_list (struct route_option_list *l, |
452 | 452 |
const char *metric) |
453 | 453 |
{ |
454 | 454 |
struct route_option *ro; |
455 |
- if (l->n >= l->capacity) |
|
456 |
- msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d routes -- please increase the max-routes option in the client configuration file", |
|
457 |
- l->capacity); |
|
458 |
- ro = &l->routes[l->n]; |
|
455 |
+ ALLOC_OBJ_GC (ro, struct route_option, l->gc); |
|
459 | 456 |
ro->network = network; |
460 | 457 |
ro->netmask = netmask; |
461 | 458 |
ro->gateway = gateway; |
462 | 459 |
ro->metric = metric; |
463 |
- ++l->n; |
|
460 |
+ ro->next = l->routes; |
|
461 |
+ l->routes = ro; |
|
462 |
+ |
|
464 | 463 |
} |
465 | 464 |
|
466 | 465 |
void |
... | ... |
@@ -470,32 +455,26 @@ add_route_ipv6_to_option_list (struct route_ipv6_option_list *l, |
470 | 470 |
const char *metric) |
471 | 471 |
{ |
472 | 472 |
struct route_ipv6_option *ro; |
473 |
- if (l->n >= l->capacity) |
|
474 |
- msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d IPv6 routes -- please increase the max-routes option in the client configuration file", |
|
475 |
- l->capacity); |
|
476 |
- ro = &l->routes_ipv6[l->n]; |
|
473 |
+ ALLOC_OBJ_GC (ro, struct route_ipv6_option, l->gc); |
|
477 | 474 |
ro->prefix = prefix; |
478 | 475 |
ro->gateway = gateway; |
479 | 476 |
ro->metric = metric; |
480 |
- ++l->n; |
|
477 |
+ ro->next = l->routes_ipv6; |
|
478 |
+ l->routes_ipv6 = ro; |
|
481 | 479 |
} |
482 | 480 |
|
483 | 481 |
void |
484 | 482 |
clear_route_list (struct route_list *rl) |
485 | 483 |
{ |
486 |
- const int capacity = rl->capacity; |
|
487 |
- const size_t rl_size = array_mult_safe (sizeof(struct route_ipv4), capacity, sizeof(struct route_list)); |
|
488 |
- memset(rl, 0, rl_size); |
|
489 |
- rl->capacity = capacity; |
|
484 |
+ gc_free (&rl->gc); |
|
485 |
+ CLEAR (*rl); |
|
490 | 486 |
} |
491 | 487 |
|
492 | 488 |
void |
493 | 489 |
clear_route_ipv6_list (struct route_ipv6_list *rl6) |
494 | 490 |
{ |
495 |
- const int capacity = rl6->capacity; |
|
496 |
- const size_t rl6_size = array_mult_safe (sizeof(struct route_ipv6), capacity, sizeof(struct route_ipv6_list)); |
|
497 |
- memset(rl6, 0, rl6_size); |
|
498 |
- rl6->capacity = capacity; |
|
491 |
+ gc_free (&rl6->gc); |
|
492 |
+ CLEAR (*rl6); |
|
499 | 493 |
} |
500 | 494 |
|
501 | 495 |
void |
... | ... |
@@ -516,22 +495,27 @@ add_block_local_item (struct route_list *rl, |
516 | 516 |
{ |
517 | 517 |
const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED); |
518 | 518 |
if ((rl->rgi.flags & rgi_needed) == rgi_needed |
519 |
- && rl->rgi.gateway.netmask < 0xFFFFFFFF |
|
520 |
- && (rl->n)+2 <= rl->capacity) |
|
519 |
+ && rl->rgi.gateway.netmask < 0xFFFFFFFF) |
|
521 | 520 |
{ |
522 |
- struct route_ipv4 r; |
|
521 |
+ struct route_ipv4 *r1, *r2; |
|
523 | 522 |
unsigned int l2; |
524 | 523 |
|
524 |
+ ALLOC_OBJ_GC (r1, struct route_ipv4, &rl->gc); |
|
525 |
+ ALLOC_OBJ_GC (r2, struct route_ipv4, &rl->gc); |
|
526 |
+ |
|
525 | 527 |
/* split a route into two smaller blocking routes, and direct them to target */ |
526 |
- CLEAR(r); |
|
527 |
- r.flags = RT_DEFINED; |
|
528 |
- r.gateway = target; |
|
529 |
- r.network = gateway->addr & gateway->netmask; |
|
530 | 528 |
l2 = ((~gateway->netmask)+1)>>1; |
531 |
- r.netmask = ~(l2-1); |
|
532 |
- rl->routes[rl->n++] = r; |
|
533 |
- r.network += l2; |
|
534 |
- rl->routes[rl->n++] = r; |
|
529 |
+ r1->flags = RT_DEFINED; |
|
530 |
+ r1->gateway = target; |
|
531 |
+ r1->network = gateway->addr & gateway->netmask; |
|
532 |
+ r1->netmask = ~(l2-1); |
|
533 |
+ r1->next = rl->routes; |
|
534 |
+ rl->routes = r1; |
|
535 |
+ |
|
536 |
+ *r2 = *r1; |
|
537 |
+ r2->network += l2; |
|
538 |
+ r2->next = rl->routes; |
|
539 |
+ rl->routes = r2; |
|
535 | 540 |
} |
536 | 541 |
} |
537 | 542 |
|
... | ... |
@@ -643,42 +627,29 @@ init_route_list (struct route_list *rl, |
643 | 643 |
|
644 | 644 |
/* parse the routes from opt to rl */ |
645 | 645 |
{ |
646 |
- int i = 0; |
|
647 |
- int j = rl->n; |
|
648 |
- bool warned = false; |
|
649 |
- for (i = 0; i < opt->n; ++i) |
|
646 |
+ struct route_option *ro; |
|
647 |
+ for (ro = opt->routes; ro; ro = ro->next) |
|
650 | 648 |
{ |
651 | 649 |
struct addrinfo* netlist; |
652 | 650 |
struct route_ipv4 r; |
653 | 651 |
|
654 |
- if (!init_route (&r, |
|
655 |
- &netlist, |
|
656 |
- &opt->routes[i], |
|
657 |
- rl)) |
|
652 |
+ if (!init_route (&r, &netlist, ro, rl)) |
|
658 | 653 |
ret = false; |
659 | 654 |
else |
660 | 655 |
{ |
661 | 656 |
struct addrinfo* curele; |
662 | 657 |
for (curele = netlist; curele; curele = curele->ai_next) |
663 | 658 |
{ |
664 |
- if (j < rl->capacity) |
|
665 |
- { |
|
666 |
- r.network = ntohl(((struct sockaddr_in*)(curele)->ai_addr)->sin_addr.s_addr); |
|
667 |
- rl->routes[j++] = r; |
|
668 |
- } |
|
669 |
- else |
|
670 |
- { |
|
671 |
- if (!warned) |
|
672 |
- { |
|
673 |
- msg (M_WARN, PACKAGE_NAME " ROUTE: routes dropped because number of expanded routes is greater than route list capacity (%d)", rl->capacity); |
|
674 |
- warned = true; |
|
675 |
- } |
|
676 |
- } |
|
659 |
+ struct route_ipv4 *new; |
|
660 |
+ ALLOC_OBJ_GC (new, struct route_ipv4, &rl->gc); |
|
661 |
+ *new = r; |
|
662 |
+ new->network = ntohl (((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr); |
|
663 |
+ new->next = rl->routes; |
|
664 |
+ rl->routes = new; |
|
677 | 665 |
} |
678 | 666 |
freeaddrinfo(netlist); |
679 | 667 |
} |
680 | 668 |
} |
681 |
- rl->n = j; |
|
682 | 669 |
} |
683 | 670 |
|
684 | 671 |
gc_free (&gc); |
... | ... |
@@ -729,22 +700,21 @@ init_route_ipv6_list (struct route_ipv6_list *rl6, |
729 | 729 |
rl6->remote_endpoint_defined = false; |
730 | 730 |
|
731 | 731 |
|
732 |
- if (!(opt6->n >= 0 && opt6->n <= rl6->capacity)) |
|
733 |
- msg (M_FATAL, PACKAGE_NAME " ROUTE6: (init) number of route options (%d) is greater than route list capacity (%d)", opt6->n, rl6->capacity); |
|
734 |
- |
|
735 |
- /* parse the routes from opt to rl6 */ |
|
732 |
+ /* parse the routes from opt6 to rl6 */ |
|
736 | 733 |
{ |
737 |
- int i, j = 0; |
|
738 |
- for (i = 0; i < opt6->n; ++i) |
|
734 |
+ struct route_ipv6_option *ro6; |
|
735 |
+ for (ro6 = opt6->routes_ipv6; ro6; ro6 = ro6->next) |
|
739 | 736 |
{ |
740 |
- if (!init_route_ipv6 (&rl6->routes_ipv6[j], |
|
741 |
- &opt6->routes_ipv6[i], |
|
742 |
- rl6 )) |
|
737 |
+ struct route_ipv6 *r6; |
|
738 |
+ ALLOC_OBJ_GC (r6, struct route_ipv6, &rl6->gc); |
|
739 |
+ if (!init_route_ipv6 (r6, ro6, rl6)) |
|
743 | 740 |
ret = false; |
744 | 741 |
else |
745 |
- ++j; |
|
742 |
+ { |
|
743 |
+ r6->next = rl6->routes_ipv6; |
|
744 |
+ rl6->routes_ipv6 = r6; |
|
745 |
+ } |
|
746 | 746 |
} |
747 |
- rl6->n = j; |
|
748 | 747 |
} |
749 | 748 |
|
750 | 749 |
gc_free (&gc); |
... | ... |
@@ -1013,10 +983,10 @@ add_routes (struct route_list *rl, struct route_ipv6_list *rl6, const struct tun |
1013 | 1013 |
redirect_default_route_to_vpn (rl, tt, flags, es); |
1014 | 1014 |
if ( rl && !(rl->iflags & RL_ROUTES_ADDED) ) |
1015 | 1015 |
{ |
1016 |
- int i; |
|
1016 |
+ struct route_ipv4 *r; |
|
1017 | 1017 |
|
1018 | 1018 |
#ifdef ENABLE_MANAGEMENT |
1019 |
- if (management && rl->n) |
|
1019 |
+ if (management && rl->routes) |
|
1020 | 1020 |
{ |
1021 | 1021 |
management_set_state (management, |
1022 | 1022 |
OPENVPN_STATE_ADD_ROUTES, |
... | ... |
@@ -1025,10 +995,9 @@ add_routes (struct route_list *rl, struct route_ipv6_list *rl6, const struct tun |
1025 | 1025 |
0); |
1026 | 1026 |
} |
1027 | 1027 |
#endif |
1028 |
- |
|
1029 |
- for (i = 0; i < rl->n; ++i) |
|
1028 |
+ |
|
1029 |
+ for (r = rl->routes; r; r = r->next) |
|
1030 | 1030 |
{ |
1031 |
- struct route_ipv4 *r = &rl->routes[i]; |
|
1032 | 1031 |
check_subnet_conflict (r->network, r->netmask, "route"); |
1033 | 1032 |
if (flags & ROUTE_DELETE_FIRST) |
1034 | 1033 |
delete_route (r, tt, flags, &rl->rgi, es); |
... | ... |
@@ -1038,11 +1007,9 @@ add_routes (struct route_list *rl, struct route_ipv6_list *rl6, const struct tun |
1038 | 1038 |
} |
1039 | 1039 |
if (rl6 && !rl6->routes_added) |
1040 | 1040 |
{ |
1041 |
- int i; |
|
1042 |
- |
|
1043 |
- for (i = 0; i < rl6->n; ++i) |
|
1041 |
+ struct route_ipv6 *r; |
|
1042 |
+ for (r = rl6->routes_ipv6; r; r = r->next) |
|
1044 | 1043 |
{ |
1045 |
- struct route_ipv6 *r = &rl6->routes_ipv6[i]; |
|
1046 | 1044 |
if (flags & ROUTE_DELETE_FIRST) |
1047 | 1045 |
delete_route_ipv6 (r, tt, flags, es); |
1048 | 1046 |
add_route_ipv6 (r, tt, flags, es); |
... | ... |
@@ -1057,10 +1024,9 @@ delete_routes (struct route_list *rl, struct route_ipv6_list *rl6, |
1057 | 1057 |
{ |
1058 | 1058 |
if ( rl && rl->iflags & RL_ROUTES_ADDED ) |
1059 | 1059 |
{ |
1060 |
- int i; |
|
1061 |
- for (i = rl->n - 1; i >= 0; --i) |
|
1060 |
+ struct route_ipv4 *r; |
|
1061 |
+ for (r = rl->routes; r; r = r->next) |
|
1062 | 1062 |
{ |
1063 |
- struct route_ipv4 * r = &rl->routes[i]; |
|
1064 | 1063 |
delete_route (r, tt, flags, &rl->rgi, es); |
1065 | 1064 |
} |
1066 | 1065 |
rl->iflags &= ~RL_ROUTES_ADDED; |
... | ... |
@@ -1075,10 +1041,9 @@ delete_routes (struct route_list *rl, struct route_ipv6_list *rl6, |
1075 | 1075 |
|
1076 | 1076 |
if ( rl6 && rl6->routes_added ) |
1077 | 1077 |
{ |
1078 |
- int i; |
|
1079 |
- for (i = rl6->n - 1; i >= 0; --i) |
|
1078 |
+ struct route_ipv6 *r6; |
|
1079 |
+ for (r6 = rl6->routes_ipv6; r6; r6 = r6->next) |
|
1080 | 1080 |
{ |
1081 |
- const struct route_ipv6 *r6 = &rl6->routes_ipv6[i]; |
|
1082 | 1081 |
delete_route_ipv6 (r6, tt, flags, es); |
1083 | 1082 |
} |
1084 | 1083 |
rl6->routes_added = false; |
... | ... |
@@ -1115,12 +1080,12 @@ void |
1115 | 1115 |
print_route_options (const struct route_option_list *rol, |
1116 | 1116 |
int level) |
1117 | 1117 |
{ |
1118 |
- int i; |
|
1118 |
+ struct route_option *ro; |
|
1119 | 1119 |
if (rol->flags & RG_ENABLE) |
1120 | 1120 |
msg (level, " [redirect_default_gateway local=%d]", |
1121 | 1121 |
(rol->flags & RG_LOCAL) != 0); |
1122 |
- for (i = 0; i < rol->n; ++i) |
|
1123 |
- print_route_option (&rol->routes[i], level); |
|
1122 |
+ for (ro = rol->routes; ro; ro = ro->next) |
|
1123 |
+ print_route_option (ro, level); |
|
1124 | 1124 |
} |
1125 | 1125 |
|
1126 | 1126 |
void |
... | ... |
@@ -1165,9 +1130,9 @@ print_route (const struct route_ipv4 *r, int level) |
1165 | 1165 |
void |
1166 | 1166 |
print_routes (const struct route_list *rl, int level) |
1167 | 1167 |
{ |
1168 |
- int i; |
|
1169 |
- for (i = 0; i < rl->n; ++i) |
|
1170 |
- print_route (&rl->routes[i], level); |
|
1168 |
+ struct route_ipv4 *r; |
|
1169 |
+ for (r = rl->routes; r; r = r->next) |
|
1170 |
+ print_route (r, level); |
|
1171 | 1171 |
} |
1172 | 1172 |
|
1173 | 1173 |
static void |
... | ... |
@@ -1193,9 +1158,10 @@ setenv_route (struct env_set *es, const struct route_ipv4 *r, int i) |
1193 | 1193 |
void |
1194 | 1194 |
setenv_routes (struct env_set *es, const struct route_list *rl) |
1195 | 1195 |
{ |
1196 |
- int i; |
|
1197 |
- for (i = 0; i < rl->n; ++i) |
|
1198 |
- setenv_route (es, &rl->routes[i], i + 1); |
|
1196 |
+ int i = 1; |
|
1197 |
+ struct route_ipv4 *r; |
|
1198 |
+ for (r = rl->routes; r; r = r->next) |
|
1199 |
+ setenv_route (es, r, i++); |
|
1199 | 1200 |
} |
1200 | 1201 |
|
1201 | 1202 |
static void |
... | ... |
@@ -1221,9 +1187,10 @@ setenv_route_ipv6 (struct env_set *es, const struct route_ipv6 *r6, int i) |
1221 | 1221 |
void |
1222 | 1222 |
setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6) |
1223 | 1223 |
{ |
1224 |
- int i; |
|
1225 |
- for (i = 0; i < rl6->n; ++i) |
|
1226 |
- setenv_route_ipv6 (es, &rl6->routes_ipv6[i], i + 1); |
|
1224 |
+ int i = 1; |
|
1225 |
+ struct route_ipv6 *r6; |
|
1226 |
+ for (r6 = rl6->routes_ipv6; r6; r6 = r6->next) |
|
1227 |
+ setenv_route_ipv6 (es, r6, i++); |
|
1227 | 1228 |
} |
1228 | 1229 |
|
1229 | 1230 |
/* |
... | ... |
@@ -2137,6 +2104,7 @@ test_routes (const struct route_list *rl, const struct tuntap *tt) |
2137 | 2137 |
int count = 0; |
2138 | 2138 |
int good = 0; |
2139 | 2139 |
int ambig = 0; |
2140 |
+ int len = -1; |
|
2140 | 2141 |
bool adapter_up = false; |
2141 | 2142 |
|
2142 | 2143 |
if (is_adapter_up (tt, adapters)) |
... | ... |
@@ -2146,9 +2114,9 @@ test_routes (const struct route_list *rl, const struct tuntap *tt) |
2146 | 2146 |
|
2147 | 2147 |
if (rl) |
2148 | 2148 |
{ |
2149 |
- int i; |
|
2150 |
- for (i = 0; i < rl->n; ++i) |
|
2151 |
- test_route_helper (&ret, &count, &good, &ambig, adapters, rl->routes[i].gateway); |
|
2149 |
+ struct route *r; |
|
2150 |
+ for (r = rl->routes, len = 0; r; r = r->next, ++len) |
|
2151 |
+ test_route_helper (&ret, &count, &good, &ambig, adapters, r->gateway); |
|
2152 | 2152 |
|
2153 | 2153 |
if ((rl->flags & RG_ENABLE) && (rl->spec.flags & RTSA_REMOTE_ENDPOINT)) |
2154 | 2154 |
test_route_helper (&ret, &count, &good, &ambig, adapters, rl->spec.remote_endpoint); |
... | ... |
@@ -2158,7 +2126,7 @@ test_routes (const struct route_list *rl, const struct tuntap *tt) |
2158 | 2158 |
msg (D_ROUTE, "TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s", |
2159 | 2159 |
good, |
2160 | 2160 |
count, |
2161 |
- rl ? rl->n : -1, |
|
2161 |
+ len, |
|
2162 | 2162 |
(int)ret, |
2163 | 2163 |
ambig, |
2164 | 2164 |
adapter_up ? "up" : "down"); |
... | ... |
@@ -33,8 +33,6 @@ |
33 | 33 |
#include "tun.h" |
34 | 34 |
#include "misc.h" |
35 | 35 |
|
36 |
-#define MAX_ROUTES_DEFAULT 100 |
|
37 |
- |
|
38 | 36 |
#ifdef WIN32 |
39 | 37 |
/* |
40 | 38 |
* Windows route methods |
... | ... |
@@ -74,6 +72,7 @@ struct route_special_addr |
74 | 74 |
}; |
75 | 75 |
|
76 | 76 |
struct route_option { |
77 |
+ struct route_option *next; |
|
77 | 78 |
const char *network; |
78 | 79 |
const char *netmask; |
79 | 80 |
const char *gateway; |
... | ... |
@@ -92,12 +91,12 @@ struct route_option { |
92 | 92 |
|
93 | 93 |
struct route_option_list { |
94 | 94 |
unsigned int flags; /* RG_x flags */ |
95 |
- int capacity; |
|
96 |
- int n; |
|
97 |
- struct route_option routes[EMPTY_ARRAY_SIZE]; |
|
95 |
+ struct route_option *routes; |
|
96 |
+ struct gc_arena *gc; |
|
98 | 97 |
}; |
99 | 98 |
|
100 | 99 |
struct route_ipv6_option { |
100 |
+ struct route_ipv6_option *next; |
|
101 | 101 |
const char *prefix; /* e.g. "2001:db8:1::/64" */ |
102 | 102 |
const char *gateway; /* e.g. "2001:db8:0::2" */ |
103 | 103 |
const char *metric; /* e.g. "5" */ |
... | ... |
@@ -105,15 +104,15 @@ struct route_ipv6_option { |
105 | 105 |
|
106 | 106 |
struct route_ipv6_option_list { |
107 | 107 |
unsigned int flags; |
108 |
- int capacity; |
|
109 |
- int n; |
|
110 |
- struct route_ipv6_option routes_ipv6[EMPTY_ARRAY_SIZE]; |
|
108 |
+ struct route_ipv6_option *routes_ipv6; |
|
109 |
+ struct gc_arena *gc; |
|
111 | 110 |
}; |
112 | 111 |
|
113 | 112 |
struct route_ipv4 { |
114 | 113 |
# define RT_DEFINED (1<<0) |
115 | 114 |
# define RT_ADDED (1<<1) |
116 | 115 |
# define RT_METRIC_DEFINED (1<<2) |
116 |
+ struct route_ipv4 *next; |
|
117 | 117 |
unsigned int flags; |
118 | 118 |
const struct route_option *option; |
119 | 119 |
in_addr_t network; |
... | ... |
@@ -123,6 +122,7 @@ struct route_ipv4 { |
123 | 123 |
}; |
124 | 124 |
|
125 | 125 |
struct route_ipv6 { |
126 |
+ struct route_ipv6 *next; |
|
126 | 127 |
bool defined; |
127 | 128 |
struct in6_addr network; |
128 | 129 |
unsigned int netbits; |
... | ... |
@@ -140,9 +140,8 @@ struct route_ipv6_list { |
140 | 140 |
bool remote_endpoint_defined; |
141 | 141 |
bool did_redirect_default_gateway; /* TODO (?) */ |
142 | 142 |
bool did_local; /* TODO (?) */ |
143 |
- int capacity; |
|
144 |
- int n; |
|
145 |
- struct route_ipv6 routes_ipv6[EMPTY_ARRAY_SIZE]; |
|
143 |
+ struct route_ipv6 *routes_ipv6; |
|
144 |
+ struct gc_arena gc; |
|
146 | 145 |
}; |
147 | 146 |
|
148 | 147 |
|
... | ... |
@@ -188,9 +187,8 @@ struct route_list { |
188 | 188 |
struct route_special_addr spec; |
189 | 189 |
struct route_gateway_info rgi; |
190 | 190 |
unsigned int flags; /* RG_x flags */ |
191 |
- int capacity; |
|
192 |
- int n; |
|
193 |
- struct route_ipv4 routes[EMPTY_ARRAY_SIZE]; |
|
191 |
+ struct route_ipv4 *routes; |
|
192 |
+ struct gc_arena gc; |
|
194 | 193 |
}; |
195 | 194 |
|
196 | 195 |
#if P2MP |
... | ... |
@@ -208,17 +206,15 @@ struct iroute_ipv6 { |
208 | 208 |
}; |
209 | 209 |
#endif |
210 | 210 |
|
211 |
-struct route_option_list *new_route_option_list (const int max_routes, struct gc_arena *a); |
|
212 |
-struct route_ipv6_option_list *new_route_ipv6_option_list (const int max_routes, struct gc_arena *a); |
|
211 |
+struct route_option_list *new_route_option_list (struct gc_arena *a); |
|
212 |
+struct route_ipv6_option_list *new_route_ipv6_option_list (struct gc_arena *a); |
|
213 | 213 |
|
214 | 214 |
struct route_option_list *clone_route_option_list (const struct route_option_list *src, struct gc_arena *a); |
215 | 215 |
struct route_ipv6_option_list *clone_route_ipv6_option_list (const struct route_ipv6_option_list *src, struct gc_arena *a); |
216 |
-void copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src); |
|
216 |
+void copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src, struct gc_arena *a); |
|
217 | 217 |
void copy_route_ipv6_option_list (struct route_ipv6_option_list *dest, |
218 |
- const struct route_ipv6_option_list *src); |
|
219 |
- |
|
220 |
-struct route_list *new_route_list (const int max_routes, struct gc_arena *a); |
|
221 |
-struct route_ipv6_list *new_route_ipv6_list (const int max_routes, struct gc_arena *a); |
|
218 |
+ const struct route_ipv6_option_list *src, |
|
219 |
+ struct gc_arena *a); |
|
222 | 220 |
|
223 | 221 |
void add_route_ipv6 (struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es); |
224 | 222 |
void delete_route_ipv6 (const struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es); |