[vlc-devel] [PATCH 7/7] mdns: Add basic ip address detection (Windows)

Roland Bewick roland.bewick at gmail.com
Wed Jul 24 17:43:50 CEST 2019


---
 modules/services_discovery/microdns.c | 105 +++++++++++++++++++++++++++++++++-
 1 file changed, 104 insertions(+), 1 deletion(-)

diff --git a/modules/services_discovery/microdns.c b/modules/services_discovery/microdns.c
index fa34ffa8d8..e9c7680ccf 100644
--- a/modules/services_discovery/microdns.c
+++ b/modules/services_discovery/microdns.c
@@ -29,7 +29,12 @@
 #include <assert.h>
 
 #if defined( _WIN32 )
-
+    #include <winsock2.h>
+    #include <ws2tcpip.h>
+    #include <wincrypt.h>
+    #include <iphlpapi.h>
+    #define IP_DETECTION_WORKING_BUFFER_SIZE 15000
+    #define IP_DETECTION_MAX_TRIES 3
 #else
     #include <ifaddrs.h>
 #endif
@@ -879,7 +884,105 @@ static char * detect_ip_address( vlc_object_t *p_obj )
     char result[16] = "127.0.0.1";
     bool found = false;
 #if defined( _WIN32 )
+    /* Set the flags to pass to GetAdaptersAddresses */
+    ULONG flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST |
+        GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
+
+    DWORD r = 0;
+    PIP_ADAPTER_ADDRESSES addresses = NULL;
+    ULONG buffer_size = IP_DETECTION_WORKING_BUFFER_SIZE;
+    ULONG iterations = 0;
+
+    do
+    {
+        addresses = (IP_ADAPTER_ADDRESSES *) malloc(buffer_size);
+        if( addresses )
+        {
+            r = GetAdaptersAddresses( AF_INET, flags, NULL, addresses, &buffer_size );
+
+            if( r == ERROR_BUFFER_OVERFLOW )
+            {
+                free(addresses);
+                addresses = NULL;
+            }
+            else
+            {
+                break;
+            }
+            iterations++;
+        }
+        else
+        {
+            break;
+        }
+    }
+    while( ( r == ERROR_BUFFER_OVERFLOW ) &&
+         ( iterations < IP_DETECTION_MAX_TRIES ) );
 
+    if( addresses && r == NO_ERROR )
+    {
+        int selected_priority = 0;
+        PIP_ADAPTER_ADDRESSES address_parser = addresses;
+        while( address_parser )
+        {
+            PIP_ADAPTER_UNICAST_ADDRESS p_unicast = address_parser->FirstUnicastAddress;
+            while( p_unicast )
+            {
+                struct sockaddr_in* si = (struct sockaddr_in*) p_unicast->Address.lpSockaddr;
+                char address_buf[INET_ADDRSTRLEN];
+                const char *ip_address = inet_ntop( AF_INET, &(si->sin_addr), 
+                                                    address_buf, sizeof( address_buf ) );
+
+                char description[256];
+                wcstombs( description, address_parser->Description, sizeof( description ) );
+
+                int priority = 1000;
+
+                /* TODO: smarter priority function. Will this work with non-English locale? */
+                const char *ignore[] = {"Virtual", "Bluetooth", "Loopback"};
+                const char *boost[] = {"Wireless"};
+
+                for( unsigned int i = 0; i < sizeof(ignore) / sizeof(char*); i++ )
+                {
+                    if( strstr( description, ignore[i] ) != NULL )
+                    {
+                        priority = 0;
+                    }
+                }
+                if( priority > 0 )
+                {
+                    for( unsigned int i = 0; i < sizeof(boost) / sizeof(char*); i++ )
+                    {
+                        if( strstr( description, boost[i] ) != NULL )
+                        {
+                            priority += 1000;
+                        }
+                    }
+                }
+
+                msg_Dbg( p_obj, "Assigned interface %s priority %d",
+                         description, priority);
+
+                if( priority > selected_priority )
+                {
+                    strcpy( result, ip_address );
+                    selected_priority = priority;
+                    found = true;
+                }
+                p_unicast = p_unicast->Next;
+            }
+            address_parser = address_parser->Next;
+        }
+    }
+    else
+    {
+        msg_Err( p_obj, "Couldn't get interface addresses");
+    }
+
+    if( addresses )
+    {
+        free(addresses);
+    }
 #else
     struct ifaddrs *id;
     if( getifaddrs( &id ) == 0 )
-- 
2.11.0



More information about the vlc-devel mailing list