aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rozman <simon@rozman.si>2020-11-17 15:30:00 +0100
committerSimon Rozman <simon@rozman.si>2020-11-17 15:30:00 +0100
commitf7c2ea4ded0ed0376efe27d8d5e3b5ef4ac0d1bd (patch)
tree53d522ed4a2131f35ee7565f83b0b7ab3e0ef80b
parentapi: remove useless line (diff)
downloadwintun-f7c2ea4ded0ed0376efe27d8d5e3b5ef4ac0d1bd.tar.xz
wintun-f7c2ea4ded0ed0376efe27d8d5e3b5ef4ac0d1bd.zip
api: retry on ERROR_TRANSACTION_NOT_ACTIVE when disabling dead GW detect
There seems to be a race in the TCP/IP adapter registry key. Sometimes, the adapter TCP/IP key is created, but setting the value EnableDeadGWDetect fails with ERROR_TRANSACTION_NOT_ACTIVE. Signed-off-by: Simon Rozman <simon@rozman.si>
-rw-r--r--api/adapter.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/api/adapter.c b/api/adapter.c
index 774433a..8cbd76d 100644
--- a/api/adapter.c
+++ b/api/adapter.c
@@ -1497,34 +1497,45 @@ static _Return_type_success_(return != NULL) WINTUN_ADAPTER *CreateAdapter(
}
Free(DummyStr);
- HKEY TcpipInterfaceRegKey;
WCHAR TcpipInterfaceRegPath[MAX_REG_PATH];
if (!GetTcpipInterfaceRegPath(Adapter, TcpipInterfaceRegPath))
{
LastError = LOG(WINTUN_LOG_ERR, L"Failed to determine interface-specific TCP/IP network registry key path");
goto cleanupTcpipAdapterRegKey;
}
- TcpipInterfaceRegKey = RegistryOpenKeyWait(
- HKEY_LOCAL_MACHINE, TcpipInterfaceRegPath, KEY_QUERY_VALUE | KEY_SET_VALUE, WAIT_FOR_REGISTRY_TIMEOUT);
- if (!TcpipInterfaceRegKey)
+ for (int Tries = 0; Tries < 300; ++Tries)
{
- LastError = LOG(WINTUN_LOG_ERR, L"Failed to open interface-specific TCP/IP network registry key");
- goto cleanupTcpipAdapterRegKey;
- }
+ HKEY TcpipInterfaceRegKey = RegistryOpenKeyWait(
+ HKEY_LOCAL_MACHINE, TcpipInterfaceRegPath, KEY_QUERY_VALUE | KEY_SET_VALUE, WAIT_FOR_REGISTRY_TIMEOUT);
+ if (!TcpipInterfaceRegKey)
+ {
+ LastError = LOG(WINTUN_LOG_ERR, L"Failed to open interface-specific TCP/IP network registry key");
+ goto cleanupTcpipAdapterRegKey;
+ }
- static const DWORD EnableDeadGWDetect = 0;
- LastError = RegSetKeyValueW(
- TcpipInterfaceRegKey, NULL, L"EnableDeadGWDetect", REG_DWORD, &EnableDeadGWDetect, sizeof(EnableDeadGWDetect));
- if (LastError != ERROR_SUCCESS)
- {
- LOG_ERROR(L"Failed to set EnableDeadGWDetect", LastError);
- goto cleanupTcpipInterfaceRegKey;
+ static const DWORD EnableDeadGWDetect = 0;
+ LastError = RegSetKeyValueW(
+ TcpipInterfaceRegKey,
+ NULL,
+ L"EnableDeadGWDetect",
+ REG_DWORD,
+ &EnableDeadGWDetect,
+ sizeof(EnableDeadGWDetect));
+ RegCloseKey(TcpipInterfaceRegKey);
+ if (LastError == ERROR_SUCCESS)
+ break;
+ if (LastError != ERROR_TRANSACTION_NOT_ACTIVE || Tries == 299)
+ {
+ LOG_ERROR(L"Failed to set EnableDeadGWDetect", LastError);
+ goto cleanupTcpipAdapterRegKey;
+ }
+ Sleep(10);
}
if (!WintunSetAdapterName(Adapter, Name))
{
LastError = LOG(WINTUN_LOG_ERR, L"Failed to set adapter name");
- goto cleanupTcpipInterfaceRegKey;
+ goto cleanupTcpipAdapterRegKey;
}
DEVPROPTYPE PropertyType;
@@ -1547,7 +1558,7 @@ static _Return_type_success_(return != NULL) WINTUN_ADAPTER *CreateAdapter(
if (ProblemStatus != STATUS_PNP_DEVICE_CONFIGURATION_PENDING || Tries == 999)
{
LOG_ERROR(L"Failed to setup adapter", LastError);
- goto cleanupTcpipInterfaceRegKey;
+ goto cleanupTcpipAdapterRegKey;
}
Sleep(10);
}
@@ -1556,8 +1567,6 @@ static _Return_type_success_(return != NULL) WINTUN_ADAPTER *CreateAdapter(
}
LastError = ERROR_SUCCESS;
-cleanupTcpipInterfaceRegKey:
- RegCloseKey(TcpipInterfaceRegKey);
cleanupTcpipAdapterRegKey:
RegCloseKey(TcpipAdapterRegKey);
cleanupAdapter: