diff options
author | james <james@e7ae566f-a301-0410-adde-c780ea21d3b5> | 2009-11-19 16:42:51 +0000 |
---|---|---|
committer | james <james@e7ae566f-a301-0410-adde-c780ea21d3b5> | 2009-11-19 16:42:51 +0000 |
commit | 5c30df12ae98c0289cdfb2a24aefba2a9d2cc52e (patch) | |
tree | b900adb66ca9a3c7d57fb89fe647f6772df027f9 /tun.c | |
parent | Increase MAX_CERT_DEPTH to 16 (from 8), and when exceeded, (diff) | |
download | openvpn-5c30df12ae98c0289cdfb2a24aefba2a9d2cc52e.tar.xz |
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.c | 96 |
1 files changed, 67 insertions, 29 deletions
@@ -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) { |