summaryrefslogtreecommitdiffstats
path: root/tun.c
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2009-11-19 16:42:51 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2009-11-19 16:42:51 +0000
commit5c30df12ae98c0289cdfb2a24aefba2a9d2cc52e (patch)
treeb900adb66ca9a3c7d57fb89fe647f6772df027f9 /tun.c
parentb9437c64ddd36c7c13508977e1a348d0e45d3187 (diff)
downloadopenvpn-5c30df12ae98c0289cdfb2a24aefba2a9d2cc52e.tar.gz
openvpn-5c30df12ae98c0289cdfb2a24aefba2a9d2cc52e.tar.xz
openvpn-5c30df12ae98c0289cdfb2a24aefba2a9d2cc52e.zip
Fixed a client-side bug that occurred when the "dhcp-pre-release"
or "dhcp-renew" options were combined with "route-gateway dhcp". The problem is that the IP Helper functions for DHCP release and renew are blocking, and so calling them from a single-threaded client stops tunnel traffic forwarding, and hence breaks "route-gateway dhcp" which requires an active tunnel. The fix is to call the IP Helper functions for DHCP release and renew from another process. Version 2.1_rc21b. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@5164 e7ae566f-a301-0410-adde-c780ea21d3b5
Diffstat (limited to 'tun.c')
-rw-r--r--tun.c96
1 files changed, 67 insertions, 29 deletions
diff --git a/tun.c b/tun.c
index 29278b8..d82ac49 100644
--- a/tun.c
+++ b/tun.c
@@ -3292,59 +3292,73 @@ tap_allow_nonadmin_access (const char *dev_node)
/*
* DHCP release/renewal
*/
-
bool
-dhcp_release (const struct tuntap *tt)
+dhcp_release_by_adapter_index(const DWORD adapter_index)
{
struct gc_arena gc = gc_new ();
bool ret = false;
- if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0)
+ const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (adapter_index, &gc);
+
+ if (inter)
{
- const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (tt->adapter_index, &gc);
- if (inter)
+ DWORD status = IpReleaseAddress ((IP_ADAPTER_INDEX_MAP *)inter);
+ if (status == NO_ERROR)
{
- DWORD status = IpReleaseAddress ((IP_ADAPTER_INDEX_MAP *)inter);
- if (status == NO_ERROR)
- {
- msg (D_TUNTAP_INFO, "TAP: DHCP address released");
- ret = true;
- }
- else
- msg (M_WARN, "NOTE: Release of DHCP-assigned IP address lease on TAP-Win32 adapter failed: %s (code=%u)",
- strerror_win32 (status, &gc),
- (unsigned int)status);
+ msg (D_TUNTAP_INFO, "TAP: DHCP address released");
+ ret = true;
}
+ else
+ msg (M_WARN, "NOTE: Release of DHCP-assigned IP address lease on TAP-Win32 adapter failed: %s (code=%u)",
+ strerror_win32 (status, &gc),
+ (unsigned int)status);
}
+
gc_free (&gc);
return ret;
}
+static bool
+dhcp_release (const struct tuntap *tt)
+{
+ if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0)
+ return dhcp_release_by_adapter_index (tt->adapter_index);
+ else
+ return false;
+}
+
bool
-dhcp_renew (const struct tuntap *tt)
+dhcp_renew_by_adapter_index (const DWORD adapter_index)
{
struct gc_arena gc = gc_new ();
bool ret = false;
- if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0)
+ const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (adapter_index, &gc);
+
+ if (inter)
{
- const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (tt->adapter_index, &gc);
- if (inter)
+ DWORD status = IpRenewAddress ((IP_ADAPTER_INDEX_MAP *)inter);
+ if (status == NO_ERROR)
{
- DWORD status = IpRenewAddress ((IP_ADAPTER_INDEX_MAP *)inter);
- if (status == NO_ERROR)
- {
- msg (D_TUNTAP_INFO, "TAP: DHCP address renewal succeeded");
- ret = true;
- }
- else
- msg (M_WARN, "WARNING: Failed to renew DHCP IP address lease on TAP-Win32 adapter: %s (code=%u)",
- strerror_win32 (status, &gc),
- (unsigned int)status);
+ msg (D_TUNTAP_INFO, "TAP: DHCP address renewal succeeded");
+ ret = true;
}
+ else
+ msg (M_WARN, "WARNING: Failed to renew DHCP IP address lease on TAP-Win32 adapter: %s (code=%u)",
+ strerror_win32 (status, &gc),
+ (unsigned int)status);
}
gc_free (&gc);
return ret;
}
+static bool
+dhcp_renew (const struct tuntap *tt)
+{
+ if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0)
+ return dhcp_renew_by_adapter_index (tt->adapter_index);
+ else
+ return false;
+}
+
/*
* netsh functions
*/
@@ -3788,6 +3802,28 @@ build_dhcp_options_string (struct buffer *buf, const struct tuntap_options *o)
return !error;
}
+static void
+fork_dhcp_action (struct tuntap *tt)
+{
+ if (tt->options.dhcp_pre_release || tt->options.dhcp_renew)
+ {
+ struct gc_arena gc = gc_new ();
+ struct buffer cmd = alloc_buf_gc (256, &gc);
+ const int verb = 3;
+ const int pre_sleep = 1;
+
+ buf_printf (&cmd, "openvpn --verb %d --tap-sleep %d", verb, pre_sleep);
+ if (tt->options.dhcp_pre_release)
+ buf_printf (&cmd, " --dhcp-pre-release");
+ if (tt->options.dhcp_renew)
+ buf_printf (&cmd, " --dhcp-renew");
+ buf_printf (&cmd, " --dhcp-rr %u", (unsigned int)tt->adapter_index);
+
+ fork_to_self (BSTR (&cmd));
+ gc_free (&gc);
+ }
+}
+
void
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
{
@@ -4152,6 +4188,8 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6
if (tt->options.dhcp_renew)
dhcp_renew (tt);
}
+ else
+ fork_dhcp_action (tt);
if (tt->did_ifconfig_setup && tt->options.ip_win32_type == IPW32_SET_IPAPI)
{