From e2b1a7157e3ba7b3cb342582acbdeb22033d7b84 Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Thu, 5 Jan 2017 11:43:26 -0800 Subject: [PATCH 1/2] Potential fix for routing issue on Windows Move setting _initialized = true until after WindowsEthernetTap::threadMain() has actually created and brought up the adapter. Also in OneService::nodeVirtualNetworkConfigFunction(), wait up to 5 seconds for WindowsEthernatTap::isInitialized() to return true before attempting to configure the interface and managed routes. Without this, the adapter doesnt actually exist yet when trying to add routes --- osdep/WindowsEthernetTap.cpp | 6 +++++- osdep/WindowsEthernetTap.hpp | 5 +++++ service/OneService.cpp | 10 ++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/osdep/WindowsEthernetTap.cpp b/osdep/WindowsEthernetTap.cpp index a9ff31d37..8ee088bb8 100644 --- a/osdep/WindowsEthernetTap.cpp +++ b/osdep/WindowsEthernetTap.cpp @@ -640,7 +640,7 @@ WindowsEthernetTap::WindowsEthernetTap( if (ConvertInterfaceGuidToLuid(&_deviceGuid,&_deviceLuid) != NO_ERROR) throw std::runtime_error("unable to convert device interface GUID to LUID"); - _initialized = true; + //_initialized = true; if (friendlyName) setFriendlyName(friendlyName); @@ -1007,6 +1007,10 @@ void WindowsEthernetTap::threadMain() ReadFile(_tap,tapReadBuf,sizeof(tapReadBuf),NULL,&tapOvlRead); bool writeInProgress = false; ULONGLONG timeOfLastBorkCheck = GetTickCount64(); + + + _initialized = true; + while (_run) { DWORD waitResult = WaitForMultipleObjectsEx(writeInProgress ? 3 : 2,wait4,FALSE,2500,TRUE); if (!_run) break; // will also break outer while(_run) diff --git a/osdep/WindowsEthernetTap.hpp b/osdep/WindowsEthernetTap.hpp index 0bbb17d82..74b37f8c3 100644 --- a/osdep/WindowsEthernetTap.hpp +++ b/osdep/WindowsEthernetTap.hpp @@ -110,12 +110,17 @@ public: void threadMain() throw(); + bool isInitialized() const { return _initialized; }; + private: NET_IFINDEX _getDeviceIndex(); // throws on failure std::vector _getRegistryIPv4Value(const char *regKey); void _setRegistryIPv4Value(const char *regKey,const std::vector &value); void _syncIps(); + // clean up invalid values put into the windows registry + // void _cleanRegistry(); + void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); void *_arg; MAC _mac; diff --git a/service/OneService.cpp b/service/OneService.cpp index 3a7edacb5..96b3a9605 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -1666,6 +1666,16 @@ public: case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: memcpy(&(n.config),nwc,sizeof(ZT_VirtualNetworkConfig)); if (n.tap) { // sanity check +#ifdef __WINDOWS__ + // wait for up to 5 seconds for the WindowsEthernetTap to actually be initialized + // + // without WindowsEthernetTap::isInitialized() returning true, the won't actually + // be online yet and setting managed routes on it will fail. + const int MAX_SLEEP_COUNT = 500; + for (int i = 0; !n.tap->isInitialized() && i < MAX_SLEEP_COUNT; i++) { + Sleep(10); + } +#endif syncManagedStuff(n,true,true); } else { _nets.erase(nwid); From 0f6c53589eb9f4faf0b2025f9e1e19c0d30b7ebb Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Thu, 5 Jan 2017 11:46:33 -0800 Subject: [PATCH 2/2] remove commented out function declaration --- osdep/WindowsEthernetTap.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/osdep/WindowsEthernetTap.hpp b/osdep/WindowsEthernetTap.hpp index 74b37f8c3..53bba3e92 100644 --- a/osdep/WindowsEthernetTap.hpp +++ b/osdep/WindowsEthernetTap.hpp @@ -118,9 +118,6 @@ private: void _setRegistryIPv4Value(const char *regKey,const std::vector &value); void _syncIps(); - // clean up invalid values put into the windows registry - // void _cleanRegistry(); - void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); void *_arg; MAC _mac;