git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@739 e7ae566f-a301-0410-adde-c780ea21d3b5
| ... | ... |
@@ -131,6 +131,7 @@ |
| 131 | 131 |
#define D_SHOW_PKCS11 LOGLEV(7, 70, M_DEBUG) /* show PKCS#11 actions */ |
| 132 | 132 |
#define D_ALIGN_DEBUG LOGLEV(7, 70, M_DEBUG) /* show verbose struct alignment info */ |
| 133 | 133 |
#define D_PACKET_TRUNC_DEBUG LOGLEV(7, 70, M_DEBUG) /* PACKET_TRUNCATION_CHECK verbose */ |
| 134 |
+#define D_PING LOGLEV(7, 70, M_DEBUG) /* PING send/receive messages */ |
|
| 134 | 135 |
|
| 135 | 136 |
#define D_HANDSHAKE_VERBOSE LOGLEV(8, 70, M_DEBUG) /* show detailed description of each handshake */ |
| 136 | 137 |
#define D_TLS_DEBUG_MED LOGLEV(8, 70, M_DEBUG) /* limited info from tls_session routines */ |
| ... | ... |
@@ -274,8 +274,12 @@ check_add_routes_dowork (struct context *c) |
| 274 | 274 |
else |
| 275 | 275 |
{
|
| 276 | 276 |
msg (D_ROUTE, "Route: Waiting for TUN/TAP interface to come up..."); |
| 277 |
+ if (c->c1.tuntap) |
|
| 278 |
+ tun_standby (c->c1.tuntap); |
|
| 279 |
+ update_time (); |
|
| 277 | 280 |
if (c->c2.route_wakeup.n != 1) |
| 278 | 281 |
event_timeout_init (&c->c2.route_wakeup, 1, now); |
| 282 |
+ event_timeout_reset (&c->c2.ping_rec_interval); |
|
| 279 | 283 |
} |
| 280 | 284 |
} |
| 281 | 285 |
|
| ... | ... |
@@ -773,7 +777,7 @@ process_incoming_link (struct context *c) |
| 773 | 773 |
#endif |
| 774 | 774 |
|
| 775 | 775 |
#ifdef PACKET_TRUNCATION_CHECK |
| 776 |
- /* if (c->c2.buf.len > 1) --c->c2.buf.len; JYFIXME */ |
|
| 776 |
+ /* if (c->c2.buf.len > 1) --c->c2.buf.len; */ |
|
| 777 | 777 |
ipv4_packet_size_verify (BPTR (&c->c2.buf), |
| 778 | 778 |
BLEN (&c->c2.buf), |
| 779 | 779 |
TUNNEL_TYPE (c->c1.tuntap), |
| ... | ... |
@@ -807,7 +811,7 @@ process_incoming_link (struct context *c) |
| 807 | 807 |
/* Did we just receive an openvpn ping packet? */ |
| 808 | 808 |
if (is_ping_msg (&c->c2.buf)) |
| 809 | 809 |
{
|
| 810 |
- dmsg (D_PACKET_CONTENT, "RECEIVED PING PACKET"); |
|
| 810 |
+ dmsg (D_PING, "RECEIVED PING PACKET"); |
|
| 811 | 811 |
c->c2.buf.len = 0; /* drop packet */ |
| 812 | 812 |
} |
| 813 | 813 |
|
| ... | ... |
@@ -911,7 +915,7 @@ process_incoming_tun (struct context *c) |
| 911 | 911 |
process_ipv4_header (c, PIPV4_PASSTOS|PIPV4_MSSFIX, &c->c2.buf); |
| 912 | 912 |
|
| 913 | 913 |
#ifdef PACKET_TRUNCATION_CHECK |
| 914 |
- /* if (c->c2.buf.len > 1) --c->c2.buf.len; JYFIXME */ |
|
| 914 |
+ /* if (c->c2.buf.len > 1) --c->c2.buf.len; */ |
|
| 915 | 915 |
ipv4_packet_size_verify (BPTR (&c->c2.buf), |
| 916 | 916 |
BLEN (&c->c2.buf), |
| 917 | 917 |
TUNNEL_TYPE (c->c1.tuntap), |
| ... | ... |
@@ -122,7 +122,7 @@ context_init_1 (struct context *c) |
| 122 | 122 |
} |
| 123 | 123 |
#endif |
| 124 | 124 |
|
| 125 |
-#if 0 /* JYFIXME -- test get_user_pass with GET_USER_PASS_NEED_OK flag */ |
|
| 125 |
+#if 0 /* test get_user_pass with GET_USER_PASS_NEED_OK flag */ |
|
| 126 | 126 |
{
|
| 127 | 127 |
/* |
| 128 | 128 |
* In the management interface, you can okay the request by entering "needok token-insertion-request ok" |
| ... | ... |
@@ -175,6 +175,8 @@ context_gc_free (struct context *c) |
| 175 | 175 |
bool |
| 176 | 176 |
init_static (void) |
| 177 | 177 |
{
|
| 178 |
+ configure_path (); |
|
| 179 |
+ |
|
| 178 | 180 |
#if defined(USE_CRYPTO) && defined(DMALLOC) |
| 179 | 181 |
openssl_dmalloc_init (); |
| 180 | 182 |
#endif |
| ... | ... |
@@ -964,6 +966,8 @@ do_up (struct context *c, bool pulled_options, unsigned int option_types_found) |
| 964 | 964 |
{
|
| 965 | 965 |
event_timeout_init (&c->c2.route_wakeup, c->options.route_delay, now); |
| 966 | 966 |
event_timeout_init (&c->c2.route_wakeup_expire, c->options.route_delay + c->options.route_delay_window, now); |
| 967 |
+ if (c->c1.tuntap) |
|
| 968 |
+ tun_standby_init (c->c1.tuntap); |
|
| 967 | 969 |
} |
| 968 | 970 |
else |
| 969 | 971 |
{
|
| ... | ... |
@@ -1372,3 +1372,33 @@ openvpn_sleep (const int n) |
| 1372 | 1372 |
#endif |
| 1373 | 1373 |
sleep (n); |
| 1374 | 1374 |
} |
| 1375 |
+ |
|
| 1376 |
+/* |
|
| 1377 |
+ * Configure PATH. On Windows, sometimes PATH is not set correctly |
|
| 1378 |
+ * by default. |
|
| 1379 |
+ */ |
|
| 1380 |
+void |
|
| 1381 |
+configure_path (void) |
|
| 1382 |
+{
|
|
| 1383 |
+#ifdef WIN32 |
|
| 1384 |
+ FILE *fp; |
|
| 1385 |
+ fp = fopen ("c:\\windows\\system32\\route.exe", "rb");
|
|
| 1386 |
+ if (fp) |
|
| 1387 |
+ {
|
|
| 1388 |
+ const int bufsiz = 512; |
|
| 1389 |
+ struct gc_arena gc = gc_new (); |
|
| 1390 |
+ struct buffer oldpath = alloc_buf_gc (bufsiz, &gc); |
|
| 1391 |
+ struct buffer newpath = alloc_buf_gc (bufsiz, &gc); |
|
| 1392 |
+ DWORD status; |
|
| 1393 |
+ fclose (fp); |
|
| 1394 |
+ status = GetEnvironmentVariable ("PATH", BPTR(&oldpath), (DWORD)BCAP(&oldpath));
|
|
| 1395 |
+ if (status > 0) |
|
| 1396 |
+ {
|
|
| 1397 |
+ buf_printf (&newpath, "C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;%s", BSTR(&oldpath)); |
|
| 1398 |
+ SetEnvironmentVariable ("PATH", BSTR(&newpath));
|
|
| 1399 |
+ /*printf ("PATH: %s\n", BSTR(&newpath));*/
|
|
| 1400 |
+ } |
|
| 1401 |
+ gc_free (&gc); |
|
| 1402 |
+ } |
|
| 1403 |
+#endif |
|
| 1404 |
+} |
| ... | ... |
@@ -612,7 +612,7 @@ init_options (struct options *o) |
| 612 | 612 |
o->tuntap_options.txqueuelen = 100; |
| 613 | 613 |
#endif |
| 614 | 614 |
#ifdef WIN32 |
| 615 |
- o->tuntap_options.ip_win32_type = IPW32_SET_DHCP_MASQ; |
|
| 615 |
+ o->tuntap_options.ip_win32_type = IPW32_SET_ADAPTIVE; |
|
| 616 | 616 |
o->tuntap_options.dhcp_lease_time = 31536000; /* one year */ |
| 617 | 617 |
o->tuntap_options.dhcp_masq_offset = 0; /* use network address as internal DHCP server address */ |
| 618 | 618 |
o->route_method = ROUTE_METHOD_IPAPI; |
| ... | ... |
@@ -1469,9 +1469,10 @@ options_postprocess (struct options *options, bool first_time) |
| 1469 | 1469 |
&& !(pull || (options->ifconfig_local && options->ifconfig_remote_netmask))) |
| 1470 | 1470 |
msg (M_USAGE, "On Windows, --ip-win32 doesn't make sense unless --ifconfig is also used"); |
| 1471 | 1471 |
|
| 1472 |
- if (options->tuntap_options.dhcp_options && |
|
| 1473 |
- options->tuntap_options.ip_win32_type != IPW32_SET_DHCP_MASQ) |
|
| 1474 |
- msg (M_USAGE, "--dhcp-options requires --ip-win32 dynamic"); |
|
| 1472 |
+ if (options->tuntap_options.dhcp_options |
|
| 1473 |
+ && options->tuntap_options.ip_win32_type != IPW32_SET_DHCP_MASQ |
|
| 1474 |
+ && options->tuntap_options.ip_win32_type != IPW32_SET_ADAPTIVE) |
|
| 1475 |
+ msg (M_USAGE, "--dhcp-options requires --ip-win32 dynamic or adaptive"); |
|
| 1475 | 1476 |
|
| 1476 | 1477 |
if ((dev == DEV_TYPE_TUN || dev == DEV_TYPE_TAP) && !options->route_delay_defined) |
| 1477 | 1478 |
{
|
| ... | ... |
@@ -4280,6 +4281,9 @@ add_option (struct options *options, |
| 4280 | 4280 |
goto err; |
| 4281 | 4281 |
} |
| 4282 | 4282 |
|
| 4283 |
+ if (index == IPW32_SET_ADAPTIVE) |
|
| 4284 |
+ options->route_delay_window = IPW32_SET_ADAPTIVE_DELAY_WINDOW; |
|
| 4285 |
+ |
|
| 4283 | 4286 |
if (index == IPW32_SET_DHCP_MASQ) |
| 4284 | 4287 |
{
|
| 4285 | 4288 |
if (p[2]) |
| ... | ... |
@@ -315,9 +315,7 @@ ssl_set_auth_nocache (void) |
| 315 | 315 |
void |
| 316 | 316 |
ssl_purge_auth (void) |
| 317 | 317 |
{
|
| 318 |
-#if 1 /* JYFIXME -- todo: bad private key should trigger a signal, then this code can be included */ |
|
| 319 | 318 |
purge_user_pass (&passbuf, true); |
| 320 |
-#endif |
|
| 321 | 319 |
purge_user_pass (&auth_user_pass, true); |
| 322 | 320 |
} |
| 323 | 321 |
|
| ... | ... |
@@ -47,6 +47,22 @@ |
| 47 | 47 |
|
| 48 | 48 |
#include "memdbg.h" |
| 49 | 49 |
|
| 50 |
+#ifdef WIN32 |
|
| 51 |
+ |
|
| 52 |
+#define NI_TEST_FIRST (1<<0) |
|
| 53 |
+#define NI_IP_NETMASK (1<<1) |
|
| 54 |
+#define NI_OPTIONS (1<<2) |
|
| 55 |
+ |
|
| 56 |
+static void netsh_ifconfig (const struct tuntap_options *to, |
|
| 57 |
+ const char *flex_name, |
|
| 58 |
+ const in_addr_t ip, |
|
| 59 |
+ const in_addr_t netmask, |
|
| 60 |
+ unsigned int flags); |
|
| 61 |
+ |
|
| 62 |
+static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc); |
|
| 63 |
+ |
|
| 64 |
+#endif |
|
| 65 |
+ |
|
| 50 | 66 |
#ifdef TARGET_SOLARIS |
| 51 | 67 |
static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual); |
| 52 | 68 |
#endif |
| ... | ... |
@@ -125,7 +141,7 @@ guess_tuntap_dev (const char *dev, |
| 125 | 125 |
const int dt = dev_type_enum (dev, dev_type); |
| 126 | 126 |
if (dt == DEV_TYPE_TUN || dt == DEV_TYPE_TAP) |
| 127 | 127 |
{
|
| 128 |
- return get_netsh_id (dev_node, gc); |
|
| 128 |
+ return netsh_get_id (dev_node, gc); |
|
| 129 | 129 |
} |
| 130 | 130 |
#endif |
| 131 | 131 |
|
| ... | ... |
@@ -768,8 +784,6 @@ do_ifconfig (struct tuntap *tt, |
| 768 | 768 |
|
| 769 | 769 |
#elif defined (WIN32) |
| 770 | 770 |
{
|
| 771 |
- const char *netmask; |
|
| 772 |
- |
|
| 773 | 771 |
/* |
| 774 | 772 |
* Make sure that both ifconfig addresses are part of the |
| 775 | 773 |
* same .252 subnet. |
| ... | ... |
@@ -778,36 +792,30 @@ do_ifconfig (struct tuntap *tt, |
| 778 | 778 |
{
|
| 779 | 779 |
verify_255_255_255_252 (tt->local, tt->remote_netmask); |
| 780 | 780 |
tt->adapter_netmask = ~3; |
| 781 |
- netmask = print_in_addr_t (tt->adapter_netmask, 0, &gc); |
|
| 782 | 781 |
} |
| 783 | 782 |
else |
| 784 | 783 |
{
|
| 785 |
- netmask = ifconfig_remote_netmask; |
|
| 786 | 784 |
tt->adapter_netmask = tt->remote_netmask; |
| 787 | 785 |
} |
| 788 | 786 |
|
| 789 |
- /* example: netsh interface ip set address my-tap static 10.3.0.1 255.255.255.0 */ |
|
| 790 |
- openvpn_snprintf (command_line, sizeof (command_line), |
|
| 791 |
- "netsh interface ip set address \"%s\" static %s %s", |
|
| 792 |
- actual, |
|
| 793 |
- ifconfig_local, |
|
| 794 |
- netmask); |
|
| 795 |
- |
|
| 796 | 787 |
switch (tt->options.ip_win32_type) |
| 797 | 788 |
{
|
| 798 | 789 |
case IPW32_SET_MANUAL: |
| 799 | 790 |
msg (M_INFO, "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)", |
| 800 | 791 |
actual, |
| 801 | 792 |
ifconfig_local, |
| 802 |
- netmask); |
|
| 793 |
+ print_in_addr_t (tt->adapter_netmask, 0, &gc)); |
|
| 803 | 794 |
break; |
| 804 | 795 |
case IPW32_SET_NETSH: |
| 805 | 796 |
if (!strcmp (actual, "NULL")) |
| 806 | 797 |
msg (M_FATAL, "Error: When using --ip-win32 netsh, if you have more than one TAP-Win32 adapter, you must also specify --dev-node"); |
| 807 |
- netcmd_semaphore_lock (); |
|
| 808 |
- msg (M_INFO, "%s", command_line); |
|
| 809 |
- system_check (command_line, es, S_FATAL, "ERROR: netsh command failed"); |
|
| 810 |
- netcmd_semaphore_release (); |
|
| 798 |
+ |
|
| 799 |
+ netsh_ifconfig (&tt->options, |
|
| 800 |
+ actual, |
|
| 801 |
+ tt->local, |
|
| 802 |
+ tt->adapter_netmask, |
|
| 803 |
+ NI_IP_NETMASK|NI_OPTIONS); |
|
| 804 |
+ |
|
| 811 | 805 |
break; |
| 812 | 806 |
} |
| 813 | 807 |
tt->did_ifconfig = true; |
| ... | ... |
@@ -2262,7 +2270,7 @@ get_unspecified_device_guid (const int device_number, |
| 2262 | 2262 |
if (act) |
| 2263 | 2263 |
buf_printf (&actual, "%s", act); |
| 2264 | 2264 |
else |
| 2265 |
- buf_printf (&actual, "NULL"); |
|
| 2265 |
+ buf_printf (&actual, "%s", tap_reg->guid); |
|
| 2266 | 2266 |
} |
| 2267 | 2267 |
|
| 2268 | 2268 |
/* Save GUID for return value */ |
| ... | ... |
@@ -2305,7 +2313,7 @@ get_device_guid (const char *name, |
| 2305 | 2305 |
if (act) |
| 2306 | 2306 |
buf_printf (&actual, "%s", act); |
| 2307 | 2307 |
else |
| 2308 |
- buf_printf (&actual, "NULL"); |
|
| 2308 |
+ buf_printf (&actual, "%s", name); |
|
| 2309 | 2309 |
return BSTR (&ret); |
| 2310 | 2310 |
} |
| 2311 | 2311 |
|
| ... | ... |
@@ -2324,39 +2332,6 @@ get_device_guid (const char *name, |
| 2324 | 2324 |
} |
| 2325 | 2325 |
|
| 2326 | 2326 |
/* |
| 2327 |
- * Return a TAP name for netsh commands. |
|
| 2328 |
- */ |
|
| 2329 |
-const char * |
|
| 2330 |
-get_netsh_id (const char *dev_node, struct gc_arena *gc) |
|
| 2331 |
-{
|
|
| 2332 |
- const struct tap_reg *tap_reg = get_tap_reg (gc); |
|
| 2333 |
- const struct panel_reg *panel_reg = get_panel_reg (gc); |
|
| 2334 |
- struct buffer actual = alloc_buf_gc (256, gc); |
|
| 2335 |
- const char *guid; |
|
| 2336 |
- |
|
| 2337 |
- at_least_one_tap_win32 (tap_reg); |
|
| 2338 |
- |
|
| 2339 |
- if (dev_node) |
|
| 2340 |
- {
|
|
| 2341 |
- guid = get_device_guid (dev_node, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc); |
|
| 2342 |
- } |
|
| 2343 |
- else |
|
| 2344 |
- {
|
|
| 2345 |
- guid = get_unspecified_device_guid (0, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc); |
|
| 2346 |
- |
|
| 2347 |
- if (get_unspecified_device_guid (1, NULL, 0, tap_reg, panel_reg, gc)) /* ambiguous if more than one TAP-Win32 adapter */ |
|
| 2348 |
- guid = NULL; |
|
| 2349 |
- } |
|
| 2350 |
- |
|
| 2351 |
- if (!guid) |
|
| 2352 |
- return "NULL"; /* not found */ |
|
| 2353 |
- else if (strcmp (BPTR (&actual), "NULL")) |
|
| 2354 |
- return BPTR (&actual); /* control panel name */ |
|
| 2355 |
- else |
|
| 2356 |
- return guid; /* no control panel name, return GUID instead */ |
|
| 2357 |
-} |
|
| 2358 |
- |
|
| 2359 |
-/* |
|
| 2360 | 2327 |
* Get adapter info list |
| 2361 | 2328 |
*/ |
| 2362 | 2329 |
const IP_ADAPTER_INFO * |
| ... | ... |
@@ -2394,23 +2369,26 @@ get_per_adapter_info (const DWORD index, struct gc_arena *gc) |
| 2394 | 2394 |
IP_PER_ADAPTER_INFO *pi = NULL; |
| 2395 | 2395 |
DWORD status; |
| 2396 | 2396 |
|
| 2397 |
- if ((status = GetPerAdapterInfo (index, NULL, &size)) != ERROR_BUFFER_OVERFLOW) |
|
| 2398 |
- {
|
|
| 2399 |
- msg (M_INFO, "GetPerAdapterInfo #1 failed (status=%u) : %s", |
|
| 2400 |
- (unsigned int)status, |
|
| 2401 |
- strerror_win32 (status, gc)); |
|
| 2402 |
- } |
|
| 2403 |
- else |
|
| 2397 |
+ if (index != ~0) |
|
| 2404 | 2398 |
{
|
| 2405 |
- pi = (PIP_PER_ADAPTER_INFO) gc_malloc (size, false, gc); |
|
| 2406 |
- if ((status = GetPerAdapterInfo ((ULONG)index, pi, &size)) == ERROR_SUCCESS) |
|
| 2407 |
- return pi; |
|
| 2408 |
- else |
|
| 2399 |
+ if ((status = GetPerAdapterInfo (index, NULL, &size)) != ERROR_BUFFER_OVERFLOW) |
|
| 2409 | 2400 |
{
|
| 2410 |
- msg (M_INFO, "GetPerAdapterInfo #2 failed (status=%u) : %s", |
|
| 2401 |
+ msg (M_INFO, "GetPerAdapterInfo #1 failed (status=%u) : %s", |
|
| 2411 | 2402 |
(unsigned int)status, |
| 2412 | 2403 |
strerror_win32 (status, gc)); |
| 2413 | 2404 |
} |
| 2405 |
+ else |
|
| 2406 |
+ {
|
|
| 2407 |
+ pi = (PIP_PER_ADAPTER_INFO) gc_malloc (size, false, gc); |
|
| 2408 |
+ if ((status = GetPerAdapterInfo ((ULONG)index, pi, &size)) == ERROR_SUCCESS) |
|
| 2409 |
+ return pi; |
|
| 2410 |
+ else |
|
| 2411 |
+ {
|
|
| 2412 |
+ msg (M_INFO, "GetPerAdapterInfo #2 failed (status=%u) : %s", |
|
| 2413 |
+ (unsigned int)status, |
|
| 2414 |
+ strerror_win32 (status, gc)); |
|
| 2415 |
+ } |
|
| 2416 |
+ } |
|
| 2414 | 2417 |
} |
| 2415 | 2418 |
return pi; |
| 2416 | 2419 |
} |
| ... | ... |
@@ -2547,6 +2525,20 @@ get_adapter_ip_netmask (const IP_ADAPTER_INFO *ai, const int n, in_addr_t *ip, i |
| 2547 | 2547 |
return ret; |
| 2548 | 2548 |
} |
| 2549 | 2549 |
|
| 2550 |
+static bool |
|
| 2551 |
+test_adapter_ip_netmask (const IP_ADAPTER_INFO *ai, const in_addr_t ip, const in_addr_t netmask) |
|
| 2552 |
+{
|
|
| 2553 |
+ if (ai) |
|
| 2554 |
+ {
|
|
| 2555 |
+ in_addr_t ip_adapter = 0; |
|
| 2556 |
+ in_addr_t netmask_adapter = 0; |
|
| 2557 |
+ const bool status = get_adapter_ip_netmask (ai, 0, &ip_adapter, &netmask_adapter); |
|
| 2558 |
+ return (status && ip_adapter == ip && netmask_adapter == netmask); |
|
| 2559 |
+ } |
|
| 2560 |
+ else |
|
| 2561 |
+ return false; |
|
| 2562 |
+} |
|
| 2563 |
+ |
|
| 2550 | 2564 |
const IP_ADAPTER_INFO * |
| 2551 | 2565 |
get_tun_adapter (const struct tuntap *tt, const IP_ADAPTER_INFO *list) |
| 2552 | 2566 |
{
|
| ... | ... |
@@ -2675,16 +2667,28 @@ adapter_index_of_ip (const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count |
| 2675 | 2675 |
* Given an adapter index, return true if the adapter |
| 2676 | 2676 |
* is DHCP disabled. |
| 2677 | 2677 |
*/ |
| 2678 |
-static bool |
|
| 2679 |
-dhcp_disabled (DWORD index) |
|
| 2678 |
+ |
|
| 2679 |
+#define DHCP_STATUS_UNDEF 0 |
|
| 2680 |
+#define DHCP_STATUS_ENABLED 1 |
|
| 2681 |
+#define DHCP_STATUS_DISABLED 2 |
|
| 2682 |
+ |
|
| 2683 |
+static int |
|
| 2684 |
+dhcp_status (DWORD index) |
|
| 2680 | 2685 |
{
|
| 2681 | 2686 |
struct gc_arena gc = gc_new (); |
| 2682 |
- const IP_ADAPTER_INFO *ai = get_adapter_info (index, &gc); |
|
| 2683 |
- bool ret = false; |
|
| 2684 |
- |
|
| 2685 |
- if (ai && !ai->DhcpEnabled) |
|
| 2686 |
- ret = true; |
|
| 2687 |
+ int ret = DHCP_STATUS_UNDEF; |
|
| 2688 |
+ if (index != ~0) |
|
| 2689 |
+ {
|
|
| 2690 |
+ const IP_ADAPTER_INFO *ai = get_adapter_info (index, &gc); |
|
| 2687 | 2691 |
|
| 2692 |
+ if (ai) |
|
| 2693 |
+ {
|
|
| 2694 |
+ if (ai->DhcpEnabled) |
|
| 2695 |
+ ret = DHCP_STATUS_ENABLED; |
|
| 2696 |
+ else |
|
| 2697 |
+ ret = DHCP_STATUS_DISABLED; |
|
| 2698 |
+ } |
|
| 2699 |
+ } |
|
| 2688 | 2700 |
gc_free (&gc); |
| 2689 | 2701 |
return ret; |
| 2690 | 2702 |
} |
| ... | ... |
@@ -2733,28 +2737,75 @@ delete_temp_addresses (DWORD index) |
| 2733 | 2733 |
* Get interface index for use with IP Helper API functions. |
| 2734 | 2734 |
*/ |
| 2735 | 2735 |
static DWORD |
| 2736 |
-get_interface_index (const char *guid) |
|
| 2736 |
+get_adapter_index_method_1 (const char *guid) |
|
| 2737 | 2737 |
{
|
| 2738 | 2738 |
struct gc_arena gc = gc_new (); |
| 2739 |
- ULONG index; |
|
| 2739 |
+ ULONG index = ~0; |
|
| 2740 | 2740 |
DWORD status; |
| 2741 | 2741 |
wchar_t wbuf[256]; |
| 2742 | 2742 |
snwprintf (wbuf, SIZE (wbuf), L"\\DEVICE\\TCPIP_%S", guid); |
| 2743 | 2743 |
wbuf [SIZE(wbuf) - 1] = 0; |
| 2744 | 2744 |
if ((status = GetAdapterIndex (wbuf, &index)) != NO_ERROR) |
| 2745 |
+ index = ~0; |
|
| 2746 |
+ gc_free (&gc); |
|
| 2747 |
+ return index; |
|
| 2748 |
+} |
|
| 2749 |
+ |
|
| 2750 |
+static DWORD |
|
| 2751 |
+get_adapter_index_method_2 (const char *guid) |
|
| 2752 |
+{
|
|
| 2753 |
+ struct gc_arena gc = gc_new (); |
|
| 2754 |
+ DWORD index = ~0; |
|
| 2755 |
+ |
|
| 2756 |
+ const IP_ADAPTER_INFO *list = get_adapter_info_list (&gc); |
|
| 2757 |
+ |
|
| 2758 |
+ while (list) |
|
| 2745 | 2759 |
{
|
| 2746 |
- msg (M_INFO, "NOTE: could not get adapter index for %S, status=%u : %s", |
|
| 2747 |
- wbuf, |
|
| 2748 |
- (unsigned int)status, |
|
| 2749 |
- strerror_win32 (status, &gc)); |
|
| 2750 |
- gc_free (&gc); |
|
| 2751 |
- return (DWORD)~0; |
|
| 2752 |
- } |
|
| 2753 |
- else |
|
| 2754 |
- {
|
|
| 2755 |
- gc_free (&gc); |
|
| 2756 |
- return index; |
|
| 2760 |
+ if (!strcmp (guid, list->AdapterName)) |
|
| 2761 |
+ {
|
|
| 2762 |
+ index = list->Index; |
|
| 2763 |
+ break; |
|
| 2764 |
+ } |
|
| 2765 |
+ list = list->Next; |
|
| 2757 | 2766 |
} |
| 2767 |
+ |
|
| 2768 |
+ gc_free (&gc); |
|
| 2769 |
+ return index; |
|
| 2770 |
+} |
|
| 2771 |
+ |
|
| 2772 |
+static DWORD |
|
| 2773 |
+get_adapter_index (const char *guid) |
|
| 2774 |
+{
|
|
| 2775 |
+ DWORD index; |
|
| 2776 |
+ index = get_adapter_index_method_1 (guid); |
|
| 2777 |
+ if (index == ~0) |
|
| 2778 |
+ index = get_adapter_index_method_2 (guid); |
|
| 2779 |
+ if (index == ~0) |
|
| 2780 |
+ msg (M_INFO, "NOTE: could not get adapter index for %s", guid); |
|
| 2781 |
+ return index; |
|
| 2782 |
+} |
|
| 2783 |
+ |
|
| 2784 |
+static DWORD |
|
| 2785 |
+get_adapter_index_flexible (const char *name) /* actual name or GUID */ |
|
| 2786 |
+{
|
|
| 2787 |
+ struct gc_arena gc = gc_new (); |
|
| 2788 |
+ DWORD index; |
|
| 2789 |
+ index = get_adapter_index_method_1 (name); |
|
| 2790 |
+ if (index == ~0) |
|
| 2791 |
+ index = get_adapter_index_method_2 (name); |
|
| 2792 |
+ if (index == ~0) |
|
| 2793 |
+ {
|
|
| 2794 |
+ const struct tap_reg *tap_reg = get_tap_reg (&gc); |
|
| 2795 |
+ const struct panel_reg *panel_reg = get_panel_reg (&gc); |
|
| 2796 |
+ const char *guid = name_to_guid (name, tap_reg, panel_reg); |
|
| 2797 |
+ index = get_adapter_index_method_1 (guid); |
|
| 2798 |
+ if (index == ~0) |
|
| 2799 |
+ index = get_adapter_index_method_2 (guid); |
|
| 2800 |
+ } |
|
| 2801 |
+ if (index == ~0) |
|
| 2802 |
+ msg (M_INFO, "NOTE: could not get adapter index for name/GUID '%s'", name); |
|
| 2803 |
+ gc_free (&gc); |
|
| 2804 |
+ return index; |
|
| 2758 | 2805 |
} |
| 2759 | 2806 |
|
| 2760 | 2807 |
/* |
| ... | ... |
@@ -2869,7 +2920,7 @@ tap_allow_nonadmin_access (const char *dev_node) |
| 2869 | 2869 |
const struct panel_reg *panel_reg = get_panel_reg (&gc); |
| 2870 | 2870 |
const char *device_guid = NULL; |
| 2871 | 2871 |
HANDLE hand; |
| 2872 |
- char guid_buffer[256]; |
|
| 2872 |
+ char actual_buffer[256]; |
|
| 2873 | 2873 |
char device_path[256]; |
| 2874 | 2874 |
|
| 2875 | 2875 |
at_least_one_tap_win32 (tap_reg); |
| ... | ... |
@@ -2877,7 +2928,7 @@ tap_allow_nonadmin_access (const char *dev_node) |
| 2877 | 2877 |
if (dev_node) |
| 2878 | 2878 |
{
|
| 2879 | 2879 |
/* Get the device GUID for the device specified with --dev-node. */ |
| 2880 |
- device_guid = get_device_guid (dev_node, guid_buffer, sizeof (guid_buffer), tap_reg, panel_reg, &gc); |
|
| 2880 |
+ device_guid = get_device_guid (dev_node, actual_buffer, sizeof (actual_buffer), tap_reg, panel_reg, &gc); |
|
| 2881 | 2881 |
|
| 2882 | 2882 |
if (!device_guid) |
| 2883 | 2883 |
msg (M_FATAL, "TAP-Win32 adapter '%s' not found", dev_node); |
| ... | ... |
@@ -2912,8 +2963,8 @@ tap_allow_nonadmin_access (const char *dev_node) |
| 2912 | 2912 |
while (true) |
| 2913 | 2913 |
{
|
| 2914 | 2914 |
device_guid = get_unspecified_device_guid (device_number, |
| 2915 |
- guid_buffer, |
|
| 2916 |
- sizeof (guid_buffer), |
|
| 2915 |
+ actual_buffer, |
|
| 2916 |
+ sizeof (actual_buffer), |
|
| 2917 | 2917 |
tap_reg, |
| 2918 | 2918 |
panel_reg, |
| 2919 | 2919 |
&gc); |
| ... | ... |
@@ -3008,6 +3059,149 @@ dhcp_renew (const struct tuntap *tt) |
| 3008 | 3008 |
} |
| 3009 | 3009 |
|
| 3010 | 3010 |
/* |
| 3011 |
+ * netsh functions |
|
| 3012 |
+ */ |
|
| 3013 |
+ |
|
| 3014 |
+static void |
|
| 3015 |
+netsh_command (const char *cmd, int n) |
|
| 3016 |
+{
|
|
| 3017 |
+ int i; |
|
| 3018 |
+ for (i = 0; i < n; ++i) |
|
| 3019 |
+ {
|
|
| 3020 |
+ bool status; |
|
| 3021 |
+ netcmd_semaphore_lock (); |
|
| 3022 |
+ msg (M_INFO, "NETSH: %s", cmd); |
|
| 3023 |
+ status = system_check (cmd, NULL, 0, "ERROR: netsh command failed"); |
|
| 3024 |
+ netcmd_semaphore_release (); |
|
| 3025 |
+ if (status) |
|
| 3026 |
+ return; |
|
| 3027 |
+ openvpn_sleep (5); |
|
| 3028 |
+ } |
|
| 3029 |
+ msg (M_FATAL, "NETSH: command failed"); |
|
| 3030 |
+} |
|
| 3031 |
+ |
|
| 3032 |
+static void |
|
| 3033 |
+netsh_ifconfig (const struct tuntap_options *to, |
|
| 3034 |
+ const char *flex_name, |
|
| 3035 |
+ const in_addr_t ip, |
|
| 3036 |
+ const in_addr_t netmask, |
|
| 3037 |
+ unsigned int flags) |
|
| 3038 |
+{
|
|
| 3039 |
+ struct gc_arena gc = gc_new (); |
|
| 3040 |
+ struct buffer out = alloc_buf_gc (256, &gc); |
|
| 3041 |
+ const IP_ADAPTER_INFO *ai = NULL; |
|
| 3042 |
+ const IP_PER_ADAPTER_INFO *pai = NULL; |
|
| 3043 |
+ |
|
| 3044 |
+ if (flags & NI_TEST_FIRST) |
|
| 3045 |
+ {
|
|
| 3046 |
+ const IP_ADAPTER_INFO *list = get_adapter_info_list (&gc); |
|
| 3047 |
+ const int index = get_adapter_index_flexible (flex_name); |
|
| 3048 |
+ ai = get_adapter (list, index); |
|
| 3049 |
+ pai = get_per_adapter_info (index, &gc); |
|
| 3050 |
+ } |
|
| 3051 |
+ |
|
| 3052 |
+ if (flags & NI_IP_NETMASK) |
|
| 3053 |
+ {
|
|
| 3054 |
+ if (test_adapter_ip_netmask (ai, ip, netmask)) |
|
| 3055 |
+ {
|
|
| 3056 |
+ msg (M_INFO, "NETSH: \"%s\" %s/%s [already set]", |
|
| 3057 |
+ flex_name, |
|
| 3058 |
+ print_in_addr_t (ip, 0, &gc), |
|
| 3059 |
+ print_in_addr_t (netmask, 0, &gc)); |
|
| 3060 |
+ } |
|
| 3061 |
+ else |
|
| 3062 |
+ {
|
|
| 3063 |
+ /* example: netsh interface ip set address my-tap static 10.3.0.1 255.255.255.0 */ |
|
| 3064 |
+ buf_init (&out, 0); |
|
| 3065 |
+ buf_printf (&out, |
|
| 3066 |
+ "netsh interface ip set address \"%s\" static %s %s", |
|
| 3067 |
+ flex_name, |
|
| 3068 |
+ print_in_addr_t (ip, 0, &gc), |
|
| 3069 |
+ print_in_addr_t (netmask, 0, &gc)); |
|
| 3070 |
+ |
|
| 3071 |
+ netsh_command (BSTR(&out), 4); |
|
| 3072 |
+ } |
|
| 3073 |
+ } |
|
| 3074 |
+ |
|
| 3075 |
+ gc_free (&gc); |
|
| 3076 |
+} |
|
| 3077 |
+ |
|
| 3078 |
+static void |
|
| 3079 |
+netsh_enable_dhcp (const struct tuntap_options *to, |
|
| 3080 |
+ const char *actual_name) |
|
| 3081 |
+{
|
|
| 3082 |
+ struct gc_arena gc = gc_new (); |
|
| 3083 |
+ struct buffer out = alloc_buf_gc (256, &gc); |
|
| 3084 |
+ |
|
| 3085 |
+ /* example: netsh interface ip set address my-tap dhcp */ |
|
| 3086 |
+ buf_printf (&out, |
|
| 3087 |
+ "netsh interface ip set address \"%s\" dhcp", |
|
| 3088 |
+ actual_name); |
|
| 3089 |
+ |
|
| 3090 |
+ netsh_command (BSTR(&out), 4); |
|
| 3091 |
+ |
|
| 3092 |
+ gc_free (&gc); |
|
| 3093 |
+} |
|
| 3094 |
+ |
|
| 3095 |
+/* |
|
| 3096 |
+ * Return a TAP name for netsh commands. |
|
| 3097 |
+ */ |
|
| 3098 |
+static const char * |
|
| 3099 |
+netsh_get_id (const char *dev_node, struct gc_arena *gc) |
|
| 3100 |
+{
|
|
| 3101 |
+ const struct tap_reg *tap_reg = get_tap_reg (gc); |
|
| 3102 |
+ const struct panel_reg *panel_reg = get_panel_reg (gc); |
|
| 3103 |
+ struct buffer actual = alloc_buf_gc (256, gc); |
|
| 3104 |
+ const char *guid; |
|
| 3105 |
+ |
|
| 3106 |
+ at_least_one_tap_win32 (tap_reg); |
|
| 3107 |
+ |
|
| 3108 |
+ if (dev_node) |
|
| 3109 |
+ {
|
|
| 3110 |
+ guid = get_device_guid (dev_node, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc); |
|
| 3111 |
+ } |
|
| 3112 |
+ else |
|
| 3113 |
+ {
|
|
| 3114 |
+ guid = get_unspecified_device_guid (0, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc); |
|
| 3115 |
+ |
|
| 3116 |
+ if (get_unspecified_device_guid (1, NULL, 0, tap_reg, panel_reg, gc)) /* ambiguous if more than one TAP-Win32 adapter */ |
|
| 3117 |
+ guid = NULL; |
|
| 3118 |
+ } |
|
| 3119 |
+ |
|
| 3120 |
+ if (!guid) |
|
| 3121 |
+ return "NULL"; /* not found */ |
|
| 3122 |
+ else if (strcmp (BPTR (&actual), "NULL")) |
|
| 3123 |
+ return BPTR (&actual); /* control panel name */ |
|
| 3124 |
+ else |
|
| 3125 |
+ return guid; /* no control panel name, return GUID instead */ |
|
| 3126 |
+} |
|
| 3127 |
+ |
|
| 3128 |
+/* |
|
| 3129 |
+ * Called iteratively on TAP-Win32 wait-for-initialization polling loop |
|
| 3130 |
+ */ |
|
| 3131 |
+void |
|
| 3132 |
+tun_standby_init (struct tuntap *tt) |
|
| 3133 |
+{
|
|
| 3134 |
+ tt->standby_iter = 0; |
|
| 3135 |
+} |
|
| 3136 |
+ |
|
| 3137 |
+void |
|
| 3138 |
+tun_standby (struct tuntap *tt) |
|
| 3139 |
+{
|
|
| 3140 |
+ ++tt->standby_iter; |
|
| 3141 |
+ if (tt->options.ip_win32_type == IPW32_SET_ADAPTIVE |
|
| 3142 |
+ && tt->standby_iter % IPW32_SET_ADAPTIVE_TRY_NETSH == 0) |
|
| 3143 |
+ {
|
|
| 3144 |
+ msg (M_INFO, "NOTE: --ip-win32 dynamic failed, now trying --ip-win32 netsh (this may take some time)"); |
|
| 3145 |
+ netsh_ifconfig (&tt->options, |
|
| 3146 |
+ tt->actual_name, |
|
| 3147 |
+ tt->local, |
|
| 3148 |
+ tt->adapter_netmask, |
|
| 3149 |
+ NI_TEST_FIRST|NI_IP_NETMASK|NI_OPTIONS); |
|
| 3150 |
+ } |
|
| 3151 |
+} |
|
| 3152 |
+ |
|
| 3153 |
+/* |
|
| 3011 | 3154 |
* Convert DHCP options from the command line / config file |
| 3012 | 3155 |
* into a raw DHCP-format options string. |
| 3013 | 3156 |
*/ |
| ... | ... |
@@ -3091,6 +3285,8 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 3091 | 3091 |
char device_path[256]; |
| 3092 | 3092 |
const char *device_guid = NULL; |
| 3093 | 3093 |
DWORD len; |
| 3094 |
+ bool dhcp_masq = false; |
|
| 3095 |
+ bool dhcp_masq_post = false; |
|
| 3094 | 3096 |
|
| 3095 | 3097 |
/*netcmd_semaphore_lock ();*/ |
| 3096 | 3098 |
|
| ... | ... |
@@ -3117,14 +3313,14 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 3117 | 3117 |
{
|
| 3118 | 3118 |
const struct tap_reg *tap_reg = get_tap_reg (&gc); |
| 3119 | 3119 |
const struct panel_reg *panel_reg = get_panel_reg (&gc); |
| 3120 |
- char guid_buffer[256]; |
|
| 3120 |
+ char actual_buffer[256]; |
|
| 3121 | 3121 |
|
| 3122 | 3122 |
at_least_one_tap_win32 (tap_reg); |
| 3123 | 3123 |
|
| 3124 | 3124 |
if (dev_node) |
| 3125 | 3125 |
{
|
| 3126 | 3126 |
/* Get the device GUID for the device specified with --dev-node. */ |
| 3127 |
- device_guid = get_device_guid (dev_node, guid_buffer, sizeof (guid_buffer), tap_reg, panel_reg, &gc); |
|
| 3127 |
+ device_guid = get_device_guid (dev_node, actual_buffer, sizeof (actual_buffer), tap_reg, panel_reg, &gc); |
|
| 3128 | 3128 |
|
| 3129 | 3129 |
if (!device_guid) |
| 3130 | 3130 |
msg (M_FATAL, "TAP-Win32 adapter '%s' not found", dev_node); |
| ... | ... |
@@ -3156,8 +3352,8 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 3156 | 3156 |
while (true) |
| 3157 | 3157 |
{
|
| 3158 | 3158 |
device_guid = get_unspecified_device_guid (device_number, |
| 3159 |
- guid_buffer, |
|
| 3160 |
- sizeof (guid_buffer), |
|
| 3159 |
+ actual_buffer, |
|
| 3160 |
+ sizeof (actual_buffer), |
|
| 3161 | 3161 |
tap_reg, |
| 3162 | 3162 |
panel_reg, |
| 3163 | 3163 |
&gc); |
| ... | ... |
@@ -3192,10 +3388,11 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 3192 | 3192 |
|
| 3193 | 3193 |
/* translate high-level device name into a device instance |
| 3194 | 3194 |
GUID using the registry */ |
| 3195 |
- tt->actual_name = string_alloc (guid_buffer, NULL); |
|
| 3195 |
+ tt->actual_name = string_alloc (actual_buffer, NULL); |
|
| 3196 | 3196 |
} |
| 3197 | 3197 |
|
| 3198 | 3198 |
msg (M_INFO, "TAP-WIN32 device [%s] opened: %s", tt->actual_name, device_path); |
| 3199 |
+ tt->adapter_index = get_adapter_index (device_guid); |
|
| 3199 | 3200 |
|
| 3200 | 3201 |
/* get driver version info */ |
| 3201 | 3202 |
{
|
| ... | ... |
@@ -3230,6 +3427,42 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 3230 | 3230 |
} |
| 3231 | 3231 |
} |
| 3232 | 3232 |
|
| 3233 |
+ /* |
|
| 3234 |
+ * Preliminaries for setting TAP-Win32 adapter TCP/IP |
|
| 3235 |
+ * properties via --ip-win32 dynamic or --ip-win32 adaptive. |
|
| 3236 |
+ */ |
|
| 3237 |
+ if (tt->did_ifconfig_setup) |
|
| 3238 |
+ {
|
|
| 3239 |
+ if (tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ) |
|
| 3240 |
+ {
|
|
| 3241 |
+ /* |
|
| 3242 |
+ * If adapter is set to non-DHCP, set to DHCP mode. |
|
| 3243 |
+ */ |
|
| 3244 |
+ if (dhcp_status (tt->adapter_index) == DHCP_STATUS_DISABLED) |
|
| 3245 |
+ netsh_enable_dhcp (&tt->options, tt->actual_name); |
|
| 3246 |
+ dhcp_masq = true; |
|
| 3247 |
+ dhcp_masq_post = true; |
|
| 3248 |
+ } |
|
| 3249 |
+ else if (tt->options.ip_win32_type == IPW32_SET_ADAPTIVE) |
|
| 3250 |
+ {
|
|
| 3251 |
+ /* |
|
| 3252 |
+ * If adapter is set to non-DHCP, use netsh right away. |
|
| 3253 |
+ */ |
|
| 3254 |
+ if (dhcp_status (tt->adapter_index) != DHCP_STATUS_ENABLED) |
|
| 3255 |
+ {
|
|
| 3256 |
+ netsh_ifconfig (&tt->options, |
|
| 3257 |
+ tt->actual_name, |
|
| 3258 |
+ tt->local, |
|
| 3259 |
+ tt->adapter_netmask, |
|
| 3260 |
+ NI_TEST_FIRST|NI_IP_NETMASK|NI_OPTIONS); |
|
| 3261 |
+ } |
|
| 3262 |
+ else |
|
| 3263 |
+ {
|
|
| 3264 |
+ dhcp_masq = true; |
|
| 3265 |
+ } |
|
| 3266 |
+ } |
|
| 3267 |
+ } |
|
| 3268 |
+ |
|
| 3233 | 3269 |
/* set point-to-point mode if TUN device */ |
| 3234 | 3270 |
|
| 3235 | 3271 |
if (tt->type == DEV_TYPE_TUN) |
| ... | ... |
@@ -3273,7 +3506,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 3273 | 3273 |
|
| 3274 | 3274 |
/* should we tell the TAP-Win32 driver to masquerade as a DHCP server as a means |
| 3275 | 3275 |
of setting the adapter address? */ |
| 3276 |
- if (tt->did_ifconfig_setup && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ) |
|
| 3276 |
+ if (dhcp_masq) |
|
| 3277 | 3277 |
{
|
| 3278 | 3278 |
uint32_t ep[4]; |
| 3279 | 3279 |
|
| ... | ... |
@@ -3320,6 +3553,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 3320 | 3320 |
|
| 3321 | 3321 |
ASSERT (ep[3] > 0); |
| 3322 | 3322 |
|
| 3323 |
+#if 1 /* TAP_IOCTL_CONFIG_DHCP_MASQ -- disable to simulate bad DHCP negotiation */ |
|
| 3323 | 3324 |
if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_DHCP_MASQ, |
| 3324 | 3325 |
ep, sizeof (ep), |
| 3325 | 3326 |
ep, sizeof (ep), &len, NULL)) |
| ... | ... |
@@ -3332,6 +3566,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 3332 | 3332 |
print_in_addr_t (ep[2], IA_NET_ORDER, &gc), |
| 3333 | 3333 |
ep[3] |
| 3334 | 3334 |
); |
| 3335 |
+#endif |
|
| 3335 | 3336 |
|
| 3336 | 3337 |
/* user-supplied DHCP options capability */ |
| 3337 | 3338 |
if (tt->options.dhcp_options) |
| ... | ... |
@@ -3368,8 +3603,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 3368 | 3368 |
|
| 3369 | 3369 |
/* possibly use IP Helper API to set IP address on adapter */ |
| 3370 | 3370 |
{
|
| 3371 |
- DWORD index = get_interface_index (device_guid); |
|
| 3372 |
- tt->adapter_index = index; |
|
| 3371 |
+ const DWORD index = tt->adapter_index; |
|
| 3373 | 3372 |
|
| 3374 | 3373 |
/* flush arp cache */ |
| 3375 | 3374 |
if (index != (DWORD)~0) |
| ... | ... |
@@ -3393,10 +3627,10 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 3393 | 3393 |
* make sure the TCP/IP properties for the adapter are |
| 3394 | 3394 |
* set correctly. |
| 3395 | 3395 |
*/ |
| 3396 |
- if (tt->did_ifconfig_setup && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ) |
|
| 3396 |
+ if (dhcp_masq_post) |
|
| 3397 | 3397 |
{
|
| 3398 | 3398 |
/* check dhcp enable status */ |
| 3399 |
- if (dhcp_disabled (index)) |
|
| 3399 |
+ if (dhcp_status (index) == DHCP_STATUS_DISABLED) |
|
| 3400 | 3400 |
msg (M_WARN, "WARNING: You have selected '--ip-win32 dynamic', which will not work unless the TAP-Win32 TCP/IP properties are set to 'Obtain an IP address automatically'"); |
| 3401 | 3401 |
|
| 3402 | 3402 |
/* force an explicit DHCP lease renewal on TAP adapter? */ |
| ... | ... |
@@ -3420,7 +3654,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 3420 | 3420 |
} |
| 3421 | 3421 |
|
| 3422 | 3422 |
/* check dhcp enable status */ |
| 3423 |
- if (dhcp_disabled (index)) |
|
| 3423 |
+ if (dhcp_status (index) == DHCP_STATUS_DISABLED) |
|
| 3424 | 3424 |
msg (M_WARN, "NOTE: You have selected (explicitly or by default) '--ip-win32 ipapi', which has a better chance of working correctly if the TAP-Win32 TCP/IP properties are set to 'Obtain an IP address automatically'"); |
| 3425 | 3425 |
|
| 3426 | 3426 |
/* delete previously added IP addresses which were not |
| ... | ... |
@@ -3556,7 +3790,8 @@ static const struct ipset_names ipset_names[] = {
|
| 3556 | 3556 |
{"manual"},
|
| 3557 | 3557 |
{"netsh"},
|
| 3558 | 3558 |
{"ipapi"},
|
| 3559 |
- {"dynamic"}
|
|
| 3559 |
+ {"dynamic"},
|
|
| 3560 |
+ {"adaptive"}
|
|
| 3560 | 3561 |
}; |
| 3561 | 3562 |
|
| 3562 | 3563 |
int |
| ... | ... |
@@ -40,6 +40,10 @@ |
| 40 | 40 |
|
| 41 | 41 |
#ifdef WIN32 |
| 42 | 42 |
|
| 43 |
+/* time constants for --ip-win32 adaptive */ |
|
| 44 |
+#define IPW32_SET_ADAPTIVE_DELAY_WINDOW 300 |
|
| 45 |
+#define IPW32_SET_ADAPTIVE_TRY_NETSH 20 |
|
| 46 |
+ |
|
| 43 | 47 |
struct tuntap_options {
|
| 44 | 48 |
/* --ip-win32 options */ |
| 45 | 49 |
bool ip_win32_defined; |
| ... | ... |
@@ -48,7 +52,8 @@ struct tuntap_options {
|
| 48 | 48 |
# define IPW32_SET_NETSH 1 /* "--ip-win32 netsh" */ |
| 49 | 49 |
# define IPW32_SET_IPAPI 2 /* "--ip-win32 ipapi" */ |
| 50 | 50 |
# define IPW32_SET_DHCP_MASQ 3 /* "--ip-win32 dynamic" */ |
| 51 |
-# define IPW32_SET_N 4 |
|
| 51 |
+# define IPW32_SET_ADAPTIVE 4 /* "--ip-win32 adaptive" */ |
|
| 52 |
+# define IPW32_SET_N 5 |
|
| 52 | 53 |
int ip_win32_type; |
| 53 | 54 |
|
| 54 | 55 |
/* --ip-win32 dynamic options */ |
| ... | ... |
@@ -155,6 +160,8 @@ struct tuntap |
| 155 | 155 |
/* Windows adapter index for TAP-Win32 adapter, |
| 156 | 156 |
~0 if undefined */ |
| 157 | 157 |
DWORD adapter_index; |
| 158 |
+ |
|
| 159 |
+ int standby_iter; |
|
| 158 | 160 |
#else |
| 159 | 161 |
int fd; /* file descriptor for TUN/TAP dev */ |
| 160 | 162 |
#endif |
| ... | ... |
@@ -318,12 +325,13 @@ void tun_show_debug (struct tuntap *tt); |
| 318 | 318 |
bool dhcp_release (const struct tuntap *tt); |
| 319 | 319 |
bool dhcp_renew (const struct tuntap *tt); |
| 320 | 320 |
|
| 321 |
+void tun_standby_init (struct tuntap *tt); |
|
| 322 |
+void tun_standby (struct tuntap *tt); |
|
| 323 |
+ |
|
| 321 | 324 |
int tun_read_queue (struct tuntap *tt, int maxsize); |
| 322 | 325 |
int tun_write_queue (struct tuntap *tt, struct buffer *buf); |
| 323 | 326 |
int tun_finalize (HANDLE h, struct overlapped_io *io, struct buffer *buf); |
| 324 | 327 |
|
| 325 |
-const char *get_netsh_id (const char *dev_node, struct gc_arena *gc); |
|
| 326 |
- |
|
| 327 | 328 |
static inline bool |
| 328 | 329 |
tuntap_stop (int status) |
| 329 | 330 |
{
|
| ... | ... |
@@ -379,6 +387,16 @@ tuntap_stop (int status) |
| 379 | 379 |
return false; |
| 380 | 380 |
} |
| 381 | 381 |
|
| 382 |
+static inline void |
|
| 383 |
+tun_standby_init (struct tuntap *tt) |
|
| 384 |
+{
|
|
| 385 |
+} |
|
| 386 |
+ |
|
| 387 |
+static inline void |
|
| 388 |
+tun_standby (struct tuntap *tt) |
|
| 389 |
+{
|
|
| 390 |
+} |
|
| 391 |
+ |
|
| 382 | 392 |
#endif |
| 383 | 393 |
|
| 384 | 394 |
/* |