mirror of
https://github.com/OpenVPN/openvpn.git
synced 2024-09-20 03:52:28 +02:00
Added new 'autolocal' redirect-gateway flag. When enabled, the OpenVPN
client will examine the routing table and determine whether (a) the OpenVPN server is reachable via a locally connected interface, or (b) traffic to the server must be forwarded through the default router. Only add a special bypass route for the OpenVPN server if (b) is true. If (a) is true, behave as if the 'local' flag is specified, and do not add a bypass route. 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
This commit is contained in:
parent
b723833ba8
commit
775a6ac279
2
common.h
2
common.h
@ -79,7 +79,7 @@ typedef unsigned long ptr_type;
|
||||
* the full --push/--pull list. If you increase it, do so
|
||||
* on both server and client.
|
||||
*/
|
||||
#define TLS_CHANNEL_BUF_SIZE 1024
|
||||
#define TLS_CHANNEL_BUF_SIZE 2048
|
||||
|
||||
/*
|
||||
* A sort of pseudo-filename for data provided inline within
|
||||
|
16
errlevel.h
16
errlevel.h
@ -88,14 +88,13 @@
|
||||
#define D_BACKTRACK LOGLEV(3, 36, 0) /* show replay backtracks */
|
||||
#define D_AUTH LOGLEV(3, 37, 0) /* show user/pass auth info */
|
||||
#define D_MULTI_LOW LOGLEV(3, 38, 0) /* show point-to-multipoint low-freq debug info */
|
||||
#define D_MULTI_DROPPED LOGLEV(3, 39, 0) /* show point-to-multipoint packet drops */
|
||||
#define D_PLUGIN LOGLEV(3, 40, 0) /* show plugin calls */
|
||||
#define D_MANAGEMENT LOGLEV(3, 41, 0) /* show --management info */
|
||||
#define D_SCHED_EXIT LOGLEV(3, 42, 0) /* show arming of scheduled exit */
|
||||
#define D_ROUTE_QUOTA LOGLEV(3, 43, 0) /* show route quota exceeded messages */
|
||||
#define D_OSBUF LOGLEV(3, 44, 0) /* show socket/tun/tap buffer sizes */
|
||||
#define D_PS_PROXY LOGLEV(3, 45, 0) /* messages related to --port-share option */
|
||||
#define D_PF_INFO LOGLEV(3, 46, 0) /* packet filter informational messages */
|
||||
#define D_PLUGIN LOGLEV(3, 39, 0) /* show plugin calls */
|
||||
#define D_MANAGEMENT LOGLEV(3, 40, 0) /* show --management info */
|
||||
#define D_SCHED_EXIT LOGLEV(3, 41, 0) /* show arming of scheduled exit */
|
||||
#define D_ROUTE_QUOTA LOGLEV(3, 42, 0) /* show route quota exceeded messages */
|
||||
#define D_OSBUF LOGLEV(3, 43, 0) /* show socket/tun/tap buffer sizes */
|
||||
#define D_PS_PROXY LOGLEV(3, 44, 0) /* messages related to --port-share option */
|
||||
#define D_PF_INFO LOGLEV(3, 45, 0) /* packet filter informational messages */
|
||||
|
||||
#define D_SHOW_PARMS LOGLEV(4, 50, 0) /* show all parameters on program initiation */
|
||||
#define D_SHOW_OCC LOGLEV(4, 51, 0) /* show options compatibility string */
|
||||
@ -104,6 +103,7 @@
|
||||
#define D_MBUF LOGLEV(4, 54, 0) /* mbuf.[ch] routines */
|
||||
#define D_PACKET_TRUNC_ERR LOGLEV(4, 55, 0) /* PACKET_TRUNCATION_CHECK */
|
||||
#define D_PF_DROPPED LOGLEV(4, 56, 0) /* packet filter dropped a packet */
|
||||
#define D_MULTI_DROPPED LOGLEV(4, 57, 0) /* show point-to-multipoint packet drops */
|
||||
|
||||
#define D_LOG_RW LOGLEV(5, 0, 0) /* Print 'R' or 'W' to stdout for read/write */
|
||||
|
||||
|
@ -4404,6 +4404,8 @@ add_option (struct options *options,
|
||||
options->routes->flags |= RG_REROUTE_GW;
|
||||
if (streq (p[j], "local"))
|
||||
options->routes->flags |= RG_LOCAL;
|
||||
else if (streq (p[j], "autolocal"))
|
||||
options->routes->flags |= RG_AUTO_LOCAL;
|
||||
else if (streq (p[j], "def1"))
|
||||
options->routes->flags |= RG_DEF1;
|
||||
else if (streq (p[j], "bypass-dhcp"))
|
||||
|
117
route.c
117
route.c
@ -50,7 +50,7 @@ print_bypass_addresses (const struct route_bypass *rb)
|
||||
int i;
|
||||
for (i = 0; i < rb->n_bypass; ++i)
|
||||
{
|
||||
msg (D_ROUTE_DEBUG, "ROUTE DEBUG: bypass_host_route[%d]=%s",
|
||||
msg (D_ROUTE, "ROUTE: bypass_host_route[%d]=%s",
|
||||
i,
|
||||
print_in_addr_t (rb->bypass[i], 0, &gc));
|
||||
}
|
||||
@ -379,7 +379,7 @@ init_route_list (struct route_list *rl,
|
||||
}
|
||||
else
|
||||
{
|
||||
dmsg (D_ROUTE_DEBUG, "ROUTE DEBUG: default_gateway=UNDEF");
|
||||
dmsg (D_ROUTE, "ROUTE: default_gateway=UNDEF");
|
||||
}
|
||||
|
||||
if (rl->flags & RG_ENABLE)
|
||||
@ -531,14 +531,31 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u
|
||||
}
|
||||
else
|
||||
{
|
||||
/* route remote host to original default gateway */
|
||||
if (!(rl->flags & RG_LOCAL))
|
||||
add_route3 (rl->spec.remote_host,
|
||||
~0,
|
||||
rl->spec.net_gateway,
|
||||
tt,
|
||||
flags,
|
||||
es);
|
||||
bool local = BOOL_CAST(rl->flags & RG_LOCAL);
|
||||
if (rl->flags & RG_AUTO_LOCAL) {
|
||||
const int tla = test_local_addr (rl->spec.remote_host);
|
||||
if (tla == TLA_NONLOCAL)
|
||||
{
|
||||
dmsg (D_ROUTE, "ROUTE remote_host is NOT LOCAL");
|
||||
local = false;
|
||||
}
|
||||
else if (tla == TLA_LOCAL)
|
||||
{
|
||||
dmsg (D_ROUTE, "ROUTE remote_host is LOCAL");
|
||||
local = true;
|
||||
}
|
||||
}
|
||||
if (!local)
|
||||
{
|
||||
/* route remote host to original default gateway */
|
||||
add_route3 (rl->spec.remote_host,
|
||||
~0,
|
||||
rl->spec.net_gateway,
|
||||
tt,
|
||||
flags,
|
||||
es);
|
||||
rl->did_local = true;
|
||||
}
|
||||
|
||||
/* route DHCP/DNS server traffic through original default gateway */
|
||||
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 *
|
||||
if (rl->did_redirect_default_gateway)
|
||||
{
|
||||
/* delete remote host route */
|
||||
if (!(rl->flags & RG_LOCAL))
|
||||
del_route3 (rl->spec.remote_host,
|
||||
~0,
|
||||
rl->spec.net_gateway,
|
||||
tt,
|
||||
flags,
|
||||
es);
|
||||
if (rl->did_local)
|
||||
{
|
||||
del_route3 (rl->spec.remote_host,
|
||||
~0,
|
||||
rl->spec.net_gateway,
|
||||
tt,
|
||||
flags,
|
||||
es);
|
||||
rl->did_local = false;
|
||||
}
|
||||
|
||||
/* delete special DHCP/DNS bypass route */
|
||||
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
|
||||
#if defined(WIN32)
|
||||
|
||||
static void
|
||||
add_host_route_if_nonlocal (struct route_bypass *rb, const in_addr_t addr, const IP_ADAPTER_INFO *dgi)
|
||||
add_host_route_if_nonlocal (struct route_bypass *rb, const in_addr_t addr)
|
||||
{
|
||||
if (!is_ip_in_adapter_subnet (dgi, addr, NULL) && addr != 0 && addr != ~0)
|
||||
if (test_local_addr(addr) == TLA_NONLOCAL && addr != 0 && addr != ~0)
|
||||
add_bypass_address (rb, addr);
|
||||
}
|
||||
|
||||
static void
|
||||
add_host_route_array (struct route_bypass *rb, const IP_ADAPTER_INFO *dgi, const IP_ADDR_STRING *iplist)
|
||||
add_host_route_array (struct route_bypass *rb, const IP_ADDR_STRING *iplist)
|
||||
{
|
||||
while (iplist)
|
||||
{
|
||||
@ -2095,7 +2115,7 @@ add_host_route_array (struct route_bypass *rb, const IP_ADAPTER_INFO *dgi, const
|
||||
const in_addr_t ip = getaddr (GETADDR_HOST_ORDER, iplist->IpAddress.String, 0, &succeed, NULL);
|
||||
if (succeed)
|
||||
{
|
||||
add_host_route_if_nonlocal (rb, ip, dgi);
|
||||
add_host_route_if_nonlocal (rb, ip);
|
||||
}
|
||||
iplist = iplist->Next;
|
||||
}
|
||||
@ -2123,11 +2143,11 @@ get_bypass_addresses (struct route_bypass *rb, const unsigned int flags)
|
||||
|
||||
/* Bypass DHCP server address */
|
||||
if ((flags & RG_BYPASS_DHCP) && dgi && dgi->DhcpEnabled)
|
||||
add_host_route_array (rb, dgi, &dgi->DhcpServer);
|
||||
add_host_route_array (rb, &dgi->DhcpServer);
|
||||
|
||||
/* Bypass DNS server addresses */
|
||||
if ((flags & RG_BYPASS_DNS) && pai)
|
||||
add_host_route_array (rb, dgi, &pai->DnsServerList);
|
||||
add_host_route_array (rb, &pai->DnsServerList);
|
||||
}
|
||||
|
||||
gc_free (&gc);
|
||||
@ -2290,3 +2310,54 @@ get_default_gateway_mac_addr (unsigned char *macaddr)
|
||||
|
||||
#endif
|
||||
#endif /* AUTO_USERID */
|
||||
|
||||
/*
|
||||
* Test if addr is reachable via a local interface (return ILA_LOCAL),
|
||||
* or if it needs to be routed via the default gateway (return
|
||||
* ILA_NONLOCAL). If the target platform doesn't implement this
|
||||
* function, return ILA_NOT_IMPLEMENTED.
|
||||
*
|
||||
* Used by redirect-gateway autolocal feature
|
||||
*/
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
int
|
||||
test_local_addr (const in_addr_t addr)
|
||||
{
|
||||
struct gc_arena gc = gc_new ();
|
||||
const in_addr_t nonlocal_netmask = 0x80000000L; /* routes with netmask <= to this are considered non-local */
|
||||
bool ret = TLA_NONLOCAL;
|
||||
|
||||
/* get full routing table */
|
||||
const MIB_IPFORWARDTABLE *rt = get_windows_routing_table (&gc);
|
||||
if (rt)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < rt->dwNumEntries; ++i)
|
||||
{
|
||||
const MIB_IPFORWARDROW *row = &rt->table[i];
|
||||
const in_addr_t net = ntohl (row->dwForwardDest);
|
||||
const in_addr_t mask = ntohl (row->dwForwardMask);
|
||||
if (mask > nonlocal_netmask && (addr & mask) == net)
|
||||
{
|
||||
ret = TLA_LOCAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gc_free (&gc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
int
|
||||
test_local_addr (const in_addr_t addr)
|
||||
{
|
||||
return TLA_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
13
route.h
13
route.h
@ -83,6 +83,7 @@ struct route_option {
|
||||
#define RG_BYPASS_DHCP (1<<3)
|
||||
#define RG_BYPASS_DNS (1<<4)
|
||||
#define RG_REROUTE_GW (1<<5)
|
||||
#define RG_AUTO_LOCAL (1<<6)
|
||||
|
||||
struct route_option_list {
|
||||
int n;
|
||||
@ -105,6 +106,7 @@ struct route_list {
|
||||
struct route_special_addr spec;
|
||||
unsigned int flags;
|
||||
bool did_redirect_default_gateway;
|
||||
bool did_local;
|
||||
int n;
|
||||
struct route routes[MAX_ROUTES];
|
||||
};
|
||||
@ -159,6 +161,17 @@ bool is_special_addr (const char *addr_str);
|
||||
|
||||
bool get_default_gateway (in_addr_t *ip, in_addr_t *netmask);
|
||||
|
||||
/*
|
||||
* Test if addr is reachable via a local interface (return ILA_LOCAL),
|
||||
* or if it needs to be routed via the default gateway (return
|
||||
* ILA_NONLOCAL). If the current platform doesn't implement this
|
||||
* function, return ILA_NOT_IMPLEMENTED.
|
||||
*/
|
||||
#define TLA_NOT_IMPLEMENTED 0
|
||||
#define TLA_NONLOCAL 1
|
||||
#define TLA_LOCAL 2
|
||||
int test_local_addr (const in_addr_t addr);
|
||||
|
||||
#if AUTO_USERID
|
||||
bool get_default_gateway_mac_addr (unsigned char *macaddr);
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
dnl define the OpenVPN version
|
||||
define(PRODUCT_VERSION,[2.1_rc16])
|
||||
define(PRODUCT_VERSION,[2.1_rc16b])
|
||||
dnl define the TAP version
|
||||
define(PRODUCT_TAP_ID,[tap0901])
|
||||
define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])
|
||||
|
Loading…
Reference in New Issue
Block a user