Paul Gofman : iphlpapi: Mark adapter addresses as DNS eligible when interface has a gateway.

Alexandre Julliard julliard at winehq.org
Wed Jan 27 15:35:04 CST 2021


Module: wine
Branch: master
Commit: 5d046a780c61687aae8315b3032b91a630735dd2
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5d046a780c61687aae8315b3032b91a630735dd2

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Wed Jan 27 16:26:31 2021 +0300

iphlpapi: Mark adapter addresses as DNS eligible when interface has a gateway.

Fixes hang on attempt to enter a single player game in Kingdoms Reborn.

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/iphlpapi/iphlpapi_main.c  | 28 ++++++++++++++--------------
 dlls/iphlpapi/tests/iphlpapi.c |  6 ++++++
 include/iptypes.h              |  3 +++
 3 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index 81c4992ac73..bd1fea02e19 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -940,16 +940,19 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index
     DWORD *v4addrs = NULL, *v4masks = NULL;
     SOCKET_ADDRESS *v6addrs = NULL, *v6masks = NULL;
     PMIB_IPFORWARDTABLE routeTable = NULL;
+    BOOL output_gateways;
+
+    if ((flags & GAA_FLAG_INCLUDE_ALL_GATEWAYS) || !(flags & GAA_FLAG_SKIP_UNICAST))
+    {
+        ret = AllocateAndGetIpForwardTableFromStack(&routeTable, FALSE, GetProcessHeap(), 0);
+        if (ret) return ret;
+        num_v4_gateways = count_v4_gateways(index, routeTable);
+    }
+    output_gateways = (flags & GAA_FLAG_INCLUDE_ALL_GATEWAYS) && (family == WS_AF_INET || family == WS_AF_UNSPEC);
 
     if (family == WS_AF_INET)
     {
         ret = v4addressesFromIndex(index, &v4addrs, &num_v4addrs, &v4masks);
-
-        if (!ret && flags & GAA_FLAG_INCLUDE_ALL_GATEWAYS)
-        {
-            ret = AllocateAndGetIpForwardTableFromStack(&routeTable, FALSE, GetProcessHeap(), 0);
-            if (!ret) num_v4_gateways = count_v4_gateways(index, routeTable);
-        }
     }
     else if (family == WS_AF_INET6)
     {
@@ -958,12 +961,6 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index
     else if (family == WS_AF_UNSPEC)
     {
         ret = v4addressesFromIndex(index, &v4addrs, &num_v4addrs, &v4masks);
-
-        if (!ret && flags & GAA_FLAG_INCLUDE_ALL_GATEWAYS)
-        {
-            ret = AllocateAndGetIpForwardTableFromStack(&routeTable, FALSE, GetProcessHeap(), 0);
-            if (!ret) num_v4_gateways = count_v4_gateways(index, routeTable);
-        }
         if (!ret) ret = v6addressesFromIndex(index, &v6addrs, &num_v6addrs, &v6masks);
     }
     else
@@ -996,7 +993,8 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index
     }
     total_size += sizeof(IP_ADAPTER_UNICAST_ADDRESS) * num_v4addrs;
     total_size += sizeof(struct sockaddr_in) * num_v4addrs;
-    total_size += (sizeof(IP_ADAPTER_GATEWAY_ADDRESS) + sizeof(SOCKADDR_IN)) * num_v4_gateways;
+    if (output_gateways)
+        total_size += (sizeof(IP_ADAPTER_GATEWAY_ADDRESS) + sizeof(SOCKADDR_IN)) * num_v4_gateways;
     total_size += sizeof(IP_ADAPTER_UNICAST_ADDRESS) * num_v6addrs;
     total_size += sizeof(SOCKET_ADDRESS) * num_v6addrs;
     for (i = 0; i < num_v6addrs; i++)
@@ -1050,7 +1048,7 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index
         aa->Luid.Info.NetLuidIndex = index;
         aa->Luid.Info.IfType = aa->IfType;
 
-        if (num_v4_gateways)
+        if (output_gateways && num_v4_gateways)
         {
             PMIB_IPFORWARDROW adapterRow;
 
@@ -1089,6 +1087,8 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index
                 ua->u.s.Length              = sizeof(IP_ADAPTER_UNICAST_ADDRESS);
                 ua->Address.iSockaddrLength = sizeof(struct sockaddr_in);
                 ua->Address.lpSockaddr      = (SOCKADDR *)((char *)ua + ua->u.s.Length);
+                if (num_v4_gateways)
+                    ua->u.s.Flags |= IP_ADAPTER_ADDRESS_DNS_ELIGIBLE;
 
                 sa = (struct WS_sockaddr_in *)ua->Address.lpSockaddr;
                 sa->sin_family           = WS_AF_INET;
diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c
index 6cbe725bada..358084fde68 100644
--- a/dlls/iphlpapi/tests/iphlpapi.c
+++ b/dlls/iphlpapi/tests/iphlpapi.c
@@ -1277,6 +1277,7 @@ static void testWin2KFunctions(void)
 
 static void test_GetAdaptersAddresses(void)
 {
+    BOOL dns_eligible_found = FALSE;
     ULONG ret, size, osize, i;
     IP_ADAPTER_ADDRESSES *aa, *ptr;
     IP_ADAPTER_UNICAST_ADDRESS *ua;
@@ -1349,6 +1350,10 @@ static void test_GetAdaptersAddresses(void)
                   S(U(*ua)).Flags, ua->PrefixOrigin, ua->SuffixOrigin, ua->DadState,
                   ua->ValidLifetime, ua->PreferredLifetime, ua->LeaseLifetime,
                   S(U(*ua)).Length < sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH) ? 0 : ua->OnLinkPrefixLength);
+
+            if (ua->Flags & IP_ADAPTER_ADDRESS_DNS_ELIGIBLE)
+                dns_eligible_found = TRUE;
+
             ua = ua->Next;
         }
         for (i = 0, temp[0] = '\0'; i < ARRAY_SIZE(aa->ZoneIndices); i++)
@@ -1380,6 +1385,7 @@ static void test_GetAdaptersAddresses(void)
             ok(!strcasecmp(aa->AdapterName, buf), "expected '%s' got '%s'\n", aa->AdapterName, buf);
         }
     }
+    ok(dns_eligible_found, "Did not find any dns eligible addresses.\n");
     HeapFree(GetProcessHeap(), 0, ptr);
 }
 
diff --git a/include/iptypes.h b/include/iptypes.h
index c1a253d7b41..c1ee7322b01 100644
--- a/include/iptypes.h
+++ b/include/iptypes.h
@@ -94,6 +94,9 @@ typedef NL_DAD_STATE IP_DAD_STATE;
 
 #ifdef _WINSOCK2API_
 
+#define IP_ADAPTER_ADDRESS_DNS_ELIGIBLE 0x00000001
+#define IP_ADAPTER_ADDRESS_TRANSIENT    0x00000002
+
 typedef struct _IP_ADAPTER_UNICAST_ADDRESS_LH {
     union {
         struct {




More information about the wine-cvs mailing list