The new 'autolocal' flag depends on the non-portable test_local_addr()
function in route.c, which is currently only implemented for Windows.
The 'autolocal' flag will act as a no-op on platforms that have not
yet defined a test_local_addr() function.
Increased TLS_CHANNEL_BUF_SIZE to 2048 from 1024 (this will allow for
more option content to be pushed from server to client).
Raised D_MULTI_DROPPED debug level to 4 from 3.
Version 2.1_rc16b.
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@4446 e7ae566f-a301-0410-adde-c780ea21d3b5
... | ... |
@@ -79,7 +79,7 @@ typedef unsigned long ptr_type; |
79 | 79 |
* the full --push/--pull list. If you increase it, do so |
80 | 80 |
* on both server and client. |
81 | 81 |
*/ |
82 |
-#define TLS_CHANNEL_BUF_SIZE 1024 |
|
82 |
+#define TLS_CHANNEL_BUF_SIZE 2048 |
|
83 | 83 |
|
84 | 84 |
/* |
85 | 85 |
* A sort of pseudo-filename for data provided inline within |
... | ... |
@@ -88,14 +88,13 @@ |
88 | 88 |
#define D_BACKTRACK LOGLEV(3, 36, 0) /* show replay backtracks */ |
89 | 89 |
#define D_AUTH LOGLEV(3, 37, 0) /* show user/pass auth info */ |
90 | 90 |
#define D_MULTI_LOW LOGLEV(3, 38, 0) /* show point-to-multipoint low-freq debug info */ |
91 |
-#define D_MULTI_DROPPED LOGLEV(3, 39, 0) /* show point-to-multipoint packet drops */ |
|
92 |
-#define D_PLUGIN LOGLEV(3, 40, 0) /* show plugin calls */ |
|
93 |
-#define D_MANAGEMENT LOGLEV(3, 41, 0) /* show --management info */ |
|
94 |
-#define D_SCHED_EXIT LOGLEV(3, 42, 0) /* show arming of scheduled exit */ |
|
95 |
-#define D_ROUTE_QUOTA LOGLEV(3, 43, 0) /* show route quota exceeded messages */ |
|
96 |
-#define D_OSBUF LOGLEV(3, 44, 0) /* show socket/tun/tap buffer sizes */ |
|
97 |
-#define D_PS_PROXY LOGLEV(3, 45, 0) /* messages related to --port-share option */ |
|
98 |
-#define D_PF_INFO LOGLEV(3, 46, 0) /* packet filter informational messages */ |
|
91 |
+#define D_PLUGIN LOGLEV(3, 39, 0) /* show plugin calls */ |
|
92 |
+#define D_MANAGEMENT LOGLEV(3, 40, 0) /* show --management info */ |
|
93 |
+#define D_SCHED_EXIT LOGLEV(3, 41, 0) /* show arming of scheduled exit */ |
|
94 |
+#define D_ROUTE_QUOTA LOGLEV(3, 42, 0) /* show route quota exceeded messages */ |
|
95 |
+#define D_OSBUF LOGLEV(3, 43, 0) /* show socket/tun/tap buffer sizes */ |
|
96 |
+#define D_PS_PROXY LOGLEV(3, 44, 0) /* messages related to --port-share option */ |
|
97 |
+#define D_PF_INFO LOGLEV(3, 45, 0) /* packet filter informational messages */ |
|
99 | 98 |
|
100 | 99 |
#define D_SHOW_PARMS LOGLEV(4, 50, 0) /* show all parameters on program initiation */ |
101 | 100 |
#define D_SHOW_OCC LOGLEV(4, 51, 0) /* show options compatibility string */ |
... | ... |
@@ -104,6 +103,7 @@ |
104 | 104 |
#define D_MBUF LOGLEV(4, 54, 0) /* mbuf.[ch] routines */ |
105 | 105 |
#define D_PACKET_TRUNC_ERR LOGLEV(4, 55, 0) /* PACKET_TRUNCATION_CHECK */ |
106 | 106 |
#define D_PF_DROPPED LOGLEV(4, 56, 0) /* packet filter dropped a packet */ |
107 |
+#define D_MULTI_DROPPED LOGLEV(4, 57, 0) /* show point-to-multipoint packet drops */ |
|
107 | 108 |
|
108 | 109 |
#define D_LOG_RW LOGLEV(5, 0, 0) /* Print 'R' or 'W' to stdout for read/write */ |
109 | 110 |
|
... | ... |
@@ -4404,6 +4404,8 @@ add_option (struct options *options, |
4404 | 4404 |
options->routes->flags |= RG_REROUTE_GW; |
4405 | 4405 |
if (streq (p[j], "local")) |
4406 | 4406 |
options->routes->flags |= RG_LOCAL; |
4407 |
+ else if (streq (p[j], "autolocal")) |
|
4408 |
+ options->routes->flags |= RG_AUTO_LOCAL; |
|
4407 | 4409 |
else if (streq (p[j], "def1")) |
4408 | 4410 |
options->routes->flags |= RG_DEF1; |
4409 | 4411 |
else if (streq (p[j], "bypass-dhcp")) |
... | ... |
@@ -50,7 +50,7 @@ print_bypass_addresses (const struct route_bypass *rb) |
50 | 50 |
int i; |
51 | 51 |
for (i = 0; i < rb->n_bypass; ++i) |
52 | 52 |
{ |
53 |
- msg (D_ROUTE_DEBUG, "ROUTE DEBUG: bypass_host_route[%d]=%s", |
|
53 |
+ msg (D_ROUTE, "ROUTE: bypass_host_route[%d]=%s", |
|
54 | 54 |
i, |
55 | 55 |
print_in_addr_t (rb->bypass[i], 0, &gc)); |
56 | 56 |
} |
... | ... |
@@ -379,7 +379,7 @@ init_route_list (struct route_list *rl, |
379 | 379 |
} |
380 | 380 |
else |
381 | 381 |
{ |
382 |
- dmsg (D_ROUTE_DEBUG, "ROUTE DEBUG: default_gateway=UNDEF"); |
|
382 |
+ dmsg (D_ROUTE, "ROUTE: default_gateway=UNDEF"); |
|
383 | 383 |
} |
384 | 384 |
|
385 | 385 |
if (rl->flags & RG_ENABLE) |
... | ... |
@@ -531,14 +531,31 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u |
531 | 531 |
} |
532 | 532 |
else |
533 | 533 |
{ |
534 |
- /* route remote host to original default gateway */ |
|
535 |
- if (!(rl->flags & RG_LOCAL)) |
|
536 |
- add_route3 (rl->spec.remote_host, |
|
537 |
- ~0, |
|
538 |
- rl->spec.net_gateway, |
|
539 |
- tt, |
|
540 |
- flags, |
|
541 |
- es); |
|
534 |
+ bool local = BOOL_CAST(rl->flags & RG_LOCAL); |
|
535 |
+ if (rl->flags & RG_AUTO_LOCAL) { |
|
536 |
+ const int tla = test_local_addr (rl->spec.remote_host); |
|
537 |
+ if (tla == TLA_NONLOCAL) |
|
538 |
+ { |
|
539 |
+ dmsg (D_ROUTE, "ROUTE remote_host is NOT LOCAL"); |
|
540 |
+ local = false; |
|
541 |
+ } |
|
542 |
+ else if (tla == TLA_LOCAL) |
|
543 |
+ { |
|
544 |
+ dmsg (D_ROUTE, "ROUTE remote_host is LOCAL"); |
|
545 |
+ local = true; |
|
546 |
+ } |
|
547 |
+ } |
|
548 |
+ if (!local) |
|
549 |
+ { |
|
550 |
+ /* route remote host to original default gateway */ |
|
551 |
+ add_route3 (rl->spec.remote_host, |
|
552 |
+ ~0, |
|
553 |
+ rl->spec.net_gateway, |
|
554 |
+ tt, |
|
555 |
+ flags, |
|
556 |
+ es); |
|
557 |
+ rl->did_local = true; |
|
558 |
+ } |
|
542 | 559 |
|
543 | 560 |
/* route DHCP/DNS server traffic through original default gateway */ |
544 | 561 |
add_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es); |
... | ... |
@@ -595,13 +612,16 @@ undo_redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap * |
595 | 595 |
if (rl->did_redirect_default_gateway) |
596 | 596 |
{ |
597 | 597 |
/* delete remote host route */ |
598 |
- if (!(rl->flags & RG_LOCAL)) |
|
599 |
- del_route3 (rl->spec.remote_host, |
|
600 |
- ~0, |
|
601 |
- rl->spec.net_gateway, |
|
602 |
- tt, |
|
603 |
- flags, |
|
604 |
- es); |
|
598 |
+ if (rl->did_local) |
|
599 |
+ { |
|
600 |
+ del_route3 (rl->spec.remote_host, |
|
601 |
+ ~0, |
|
602 |
+ rl->spec.net_gateway, |
|
603 |
+ tt, |
|
604 |
+ flags, |
|
605 |
+ es); |
|
606 |
+ rl->did_local = false; |
|
607 |
+ } |
|
605 | 608 |
|
606 | 609 |
/* delete special DHCP/DNS bypass route */ |
607 | 610 |
del_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es); |
... | ... |
@@ -2080,14 +2100,14 @@ netmask_to_netbits (const in_addr_t network, const in_addr_t netmask, int *netbi |
2080 | 2080 |
#if defined(WIN32) |
2081 | 2081 |
|
2082 | 2082 |
static void |
2083 |
-add_host_route_if_nonlocal (struct route_bypass *rb, const in_addr_t addr, const IP_ADAPTER_INFO *dgi) |
|
2083 |
+add_host_route_if_nonlocal (struct route_bypass *rb, const in_addr_t addr) |
|
2084 | 2084 |
{ |
2085 |
- if (!is_ip_in_adapter_subnet (dgi, addr, NULL) && addr != 0 && addr != ~0) |
|
2085 |
+ if (test_local_addr(addr) == TLA_NONLOCAL && addr != 0 && addr != ~0) |
|
2086 | 2086 |
add_bypass_address (rb, addr); |
2087 | 2087 |
} |
2088 | 2088 |
|
2089 | 2089 |
static void |
2090 |
-add_host_route_array (struct route_bypass *rb, const IP_ADAPTER_INFO *dgi, const IP_ADDR_STRING *iplist) |
|
2090 |
+add_host_route_array (struct route_bypass *rb, const IP_ADDR_STRING *iplist) |
|
2091 | 2091 |
{ |
2092 | 2092 |
while (iplist) |
2093 | 2093 |
{ |
... | ... |
@@ -2095,7 +2115,7 @@ add_host_route_array (struct route_bypass *rb, const IP_ADAPTER_INFO *dgi, const |
2095 | 2095 |
const in_addr_t ip = getaddr (GETADDR_HOST_ORDER, iplist->IpAddress.String, 0, &succeed, NULL); |
2096 | 2096 |
if (succeed) |
2097 | 2097 |
{ |
2098 |
- add_host_route_if_nonlocal (rb, ip, dgi); |
|
2098 |
+ add_host_route_if_nonlocal (rb, ip); |
|
2099 | 2099 |
} |
2100 | 2100 |
iplist = iplist->Next; |
2101 | 2101 |
} |
... | ... |
@@ -2123,11 +2143,11 @@ get_bypass_addresses (struct route_bypass *rb, const unsigned int flags) |
2123 | 2123 |
|
2124 | 2124 |
/* Bypass DHCP server address */ |
2125 | 2125 |
if ((flags & RG_BYPASS_DHCP) && dgi && dgi->DhcpEnabled) |
2126 |
- add_host_route_array (rb, dgi, &dgi->DhcpServer); |
|
2126 |
+ add_host_route_array (rb, &dgi->DhcpServer); |
|
2127 | 2127 |
|
2128 | 2128 |
/* Bypass DNS server addresses */ |
2129 | 2129 |
if ((flags & RG_BYPASS_DNS) && pai) |
2130 |
- add_host_route_array (rb, dgi, &pai->DnsServerList); |
|
2130 |
+ add_host_route_array (rb, &pai->DnsServerList); |
|
2131 | 2131 |
} |
2132 | 2132 |
|
2133 | 2133 |
gc_free (&gc); |
... | ... |
@@ -2290,3 +2310,54 @@ get_default_gateway_mac_addr (unsigned char *macaddr) |
2290 | 2290 |
|
2291 | 2291 |
#endif |
2292 | 2292 |
#endif /* AUTO_USERID */ |
2293 |
+ |
|
2294 |
+/* |
|
2295 |
+ * Test if addr is reachable via a local interface (return ILA_LOCAL), |
|
2296 |
+ * or if it needs to be routed via the default gateway (return |
|
2297 |
+ * ILA_NONLOCAL). If the target platform doesn't implement this |
|
2298 |
+ * function, return ILA_NOT_IMPLEMENTED. |
|
2299 |
+ * |
|
2300 |
+ * Used by redirect-gateway autolocal feature |
|
2301 |
+ */ |
|
2302 |
+ |
|
2303 |
+#if defined(WIN32) |
|
2304 |
+ |
|
2305 |
+int |
|
2306 |
+test_local_addr (const in_addr_t addr) |
|
2307 |
+{ |
|
2308 |
+ struct gc_arena gc = gc_new (); |
|
2309 |
+ const in_addr_t nonlocal_netmask = 0x80000000L; /* routes with netmask <= to this are considered non-local */ |
|
2310 |
+ bool ret = TLA_NONLOCAL; |
|
2311 |
+ |
|
2312 |
+ /* get full routing table */ |
|
2313 |
+ const MIB_IPFORWARDTABLE *rt = get_windows_routing_table (&gc); |
|
2314 |
+ if (rt) |
|
2315 |
+ { |
|
2316 |
+ int i; |
|
2317 |
+ for (i = 0; i < rt->dwNumEntries; ++i) |
|
2318 |
+ { |
|
2319 |
+ const MIB_IPFORWARDROW *row = &rt->table[i]; |
|
2320 |
+ const in_addr_t net = ntohl (row->dwForwardDest); |
|
2321 |
+ const in_addr_t mask = ntohl (row->dwForwardMask); |
|
2322 |
+ if (mask > nonlocal_netmask && (addr & mask) == net) |
|
2323 |
+ { |
|
2324 |
+ ret = TLA_LOCAL; |
|
2325 |
+ break; |
|
2326 |
+ } |
|
2327 |
+ } |
|
2328 |
+ } |
|
2329 |
+ |
|
2330 |
+ gc_free (&gc); |
|
2331 |
+ return ret; |
|
2332 |
+} |
|
2333 |
+ |
|
2334 |
+#else |
|
2335 |
+ |
|
2336 |
+ |
|
2337 |
+int |
|
2338 |
+test_local_addr (const in_addr_t addr) |
|
2339 |
+{ |
|
2340 |
+ return TLA_NOT_IMPLEMENTED; |
|
2341 |
+} |
|
2342 |
+ |
|
2343 |
+#endif |
... | ... |
@@ -83,6 +83,7 @@ struct route_option { |
83 | 83 |
#define RG_BYPASS_DHCP (1<<3) |
84 | 84 |
#define RG_BYPASS_DNS (1<<4) |
85 | 85 |
#define RG_REROUTE_GW (1<<5) |
86 |
+#define RG_AUTO_LOCAL (1<<6) |
|
86 | 87 |
|
87 | 88 |
struct route_option_list { |
88 | 89 |
int n; |
... | ... |
@@ -105,6 +106,7 @@ struct route_list { |
105 | 105 |
struct route_special_addr spec; |
106 | 106 |
unsigned int flags; |
107 | 107 |
bool did_redirect_default_gateway; |
108 |
+ bool did_local; |
|
108 | 109 |
int n; |
109 | 110 |
struct route routes[MAX_ROUTES]; |
110 | 111 |
}; |
... | ... |
@@ -159,6 +161,17 @@ bool is_special_addr (const char *addr_str); |
159 | 159 |
|
160 | 160 |
bool get_default_gateway (in_addr_t *ip, in_addr_t *netmask); |
161 | 161 |
|
162 |
+/* |
|
163 |
+ * Test if addr is reachable via a local interface (return ILA_LOCAL), |
|
164 |
+ * or if it needs to be routed via the default gateway (return |
|
165 |
+ * ILA_NONLOCAL). If the current platform doesn't implement this |
|
166 |
+ * function, return ILA_NOT_IMPLEMENTED. |
|
167 |
+ */ |
|
168 |
+#define TLA_NOT_IMPLEMENTED 0 |
|
169 |
+#define TLA_NONLOCAL 1 |
|
170 |
+#define TLA_LOCAL 2 |
|
171 |
+int test_local_addr (const in_addr_t addr); |
|
172 |
+ |
|
162 | 173 |
#if AUTO_USERID |
163 | 174 |
bool get_default_gateway_mac_addr (unsigned char *macaddr); |
164 | 175 |
#endif |