[vlc-commits] [Git][videolan/vlc][master] 6 commits: sout: dlna: simplify `GetServerIPAddress`

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sun Apr 10 18:01:48 UTC 2022



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
e3d29038 by Alaric Senat at 2022-04-10T16:12:29+00:00
sout: dlna: simplify `GetServerIPAddress`

Prefer using the UPNP API calls to get the selected interface's IP
address.  The code removed is unnecessarily complex as the correct IP
address should already be available and exposed by libupnp.

Also avoids an unhandled `strdup(nullptr)` in case of error.

- - - - -
9fd11b9c by Alaric Senat at 2022-04-10T16:12:29+00:00
upnp: change required version to 1.8.3

This version gives access to `UpnpInit2` for both IPv6 and IPv4.
`UpnpInit` is deprecated since 1.6 and less safe than `UpnpInit2`.

Libupnp 1.8.3 has been out since 2017 and has been widely adopted in
most linux distributions now (available on debian since version 10).
Dropping support for lower versions will allow us to completely remove
`UpnpInit` from the codebase and simplify a lot the netintf selection
code.

- - - - -
8e05bad0 by Alaric Senat at 2022-04-10T16:12:29+00:00
upnp: exclusively use `UpnpInit2`

`UpnpInit` is deprecated and unmaintained since 1.6. It is known to be
vulnerable (CVE-2020-12695). Dropping its support simplifies a lot the
network code as solely a net interface name is required by `UpnpInit2`
now.

- - - - -
6eed7670 by Alaric Senat at 2022-04-10T16:12:29+00:00
upnp: removes code depending on libupnp < 1.8.3

Support for older versions was dropped by the previous commits.

- - - - -
7628be6b by Alaric Senat at 2022-04-10T16:12:29+00:00
upnp: win32: simplify IPv6 handling

Use specialized libupnp defines instead of a boolean since
`GetIpv4ForMulticast` was dropped before.

- - - - -
b9daafa9 by Alaric Senat at 2022-04-10T16:12:29+00:00
upnp: win32: accept net-intf that support both IPv4/6

Previously when libupnp was built with IPv6 enabled only the adapters
supporting IPv6 were accepted. libupnp does support IPv4 even when built
with IPv6, this commit accept both kinds of adapters instead of
excluding the ones that does not support IPv6 at all.

- - - - -


5 changed files:

- configure.ac
- contrib/src/upnp/rules.mak
- modules/services_discovery/upnp-wrapper.cpp
- modules/services_discovery/upnp-wrapper.hpp
- modules/stream_out/dlna/dlna.cpp


Changes:

=====================================
configure.ac
=====================================
@@ -4178,7 +4178,7 @@ PKG_ENABLE_MODULES_VLC([MTP], [mtp access_mtp], [libmtp >= 1.0.0], [MTP devices
 dnl
 dnl UPnP Plugin (Intel SDK)
 dnl
-PKG_ENABLE_MODULES_VLC([UPNP], [upnp], [libupnp], [Intel UPNP SDK],[auto])
+PKG_ENABLE_MODULES_VLC([UPNP], [upnp], [libupnp >= 1.8.3], [Intel UPNP SDK],[auto])
 
 dnl
 dnl mDNS using libmicrodns


=====================================
contrib/src/upnp/rules.mak
=====================================
@@ -5,7 +5,7 @@ UPNP_URL := $(GITHUB)/pupnp/pupnp/archive/refs/tags/release-$(UPNP_VERSION).tar.
 ifdef BUILD_NETWORK
 PKGS += upnp
 endif
-ifeq ($(call need_pkg,"libupnp >= 1.6.19"),)
+ifeq ($(call need_pkg,"libupnp >= 1.8.3"),)
 PKGS_FOUND += upnp
 endif
 


=====================================
modules/services_discovery/upnp-wrapper.cpp
=====================================
@@ -57,20 +57,17 @@ UpnpInstanceWrapper *UpnpInstanceWrapper::get(vlc_object_t *p_obj)
             return NULL;
         }
 
-        /* libupnp 1.8 deprecate `UpnpInit` and introduce `UpnpInit2` as a replacement. */
-    #if UPNP_VERSION >= 10800
-        char* psz_miface = var_InheritString( p_obj, "miface" );
-        if (psz_miface == NULL)
-            psz_miface = getPreferedAdapter();
-        msg_Info( p_obj, "Initializing libupnp on '%s' interface", psz_miface ? psz_miface : "default" );
-        int i_res = UpnpInit2( psz_miface, 0 );
-        free( psz_miface );
-    #else
-        /* If UpnpInit2 isn't available, initialize on first IPv4-capable interface */
-        char *psz_hostip = getIpv4ForMulticast();
-        int i_res = UpnpInit( psz_hostip, 0 );
-        free(psz_hostip);
-    #endif /* UPNP_VERSION >= 10800 */
+        char *net_iface = var_InheritString( p_obj, "miface" );
+        if ( net_iface == NULL )
+        {
+            // No forced multicast network interface, select one by default.
+            net_iface = getPreferedAdapter();
+        }
+        msg_Info( p_obj, "Initializing libupnp on '%s' interface",
+                  net_iface ? net_iface : "default" );
+        int i_res = UpnpInit2( net_iface, 0 );
+        free( net_iface );
+
         if( i_res != UPNP_E_SUCCESS )
         {
             msg_Err( p_obj, "Initialization failed: %s", UpnpGetErrorMessage( i_res ) );


=====================================
modules/services_discovery/upnp-wrapper.hpp
=====================================
@@ -39,11 +39,7 @@
 #include <upnp.h>
 #include <upnptools.h>
 
-#if UPNP_VERSION < 10800
-typedef void* UpnpEventPtr;
-#else
 typedef const void* UpnpEventPtr;
-#endif
 
 /**
  * libUpnp allows only one instance per process, so we create a wrapper
@@ -93,30 +89,6 @@ private:
 // Helper functions
 // **************************
 
-#if UPNP_VERSION < 10623
-/*
- * Compat functions and typedefs for libupnp prior to 1.8
- */
-
-typedef Upnp_Discovery UpnpDiscovery;
-typedef Upnp_Action_Complete UpnpActionComplete;
-
-inline const char* UpnpDiscovery_get_Location_cstr( const UpnpDiscovery* p_discovery )
-{
-  return p_discovery->Location;
-}
-
-inline const char* UpnpDiscovery_get_DeviceID_cstr( const UpnpDiscovery* p_discovery )
-{
-  return p_discovery->DeviceId;
-}
-
-inline static IXML_Document* UpnpActionComplete_get_ActionResult( const UpnpActionComplete* p_result )
-{
-  return p_result->ActionResult;
-}
-#endif
-
 /*
  * Returns the value of a child element, or NULL on error
  */
@@ -156,24 +128,29 @@ inline IP_ADAPTER_MULTICAST_ADDRESS* getMulticastAddress(IP_ADAPTER_ADDRESSES* p
     return NULL;
 }
 
-inline bool isAdapterSuitable(IP_ADAPTER_ADDRESSES* p_adapter, bool ipv6)
+inline bool isAdapterSuitable(IP_ADAPTER_ADDRESSES* p_adapter)
 {
     if ( p_adapter->OperStatus != IfOperStatusUp )
         return false;
     if (p_adapter->Length == sizeof(IP_ADAPTER_ADDRESSES_XP))
     {
         IP_ADAPTER_ADDRESSES_XP* p_adapter_xp = reinterpret_cast<IP_ADAPTER_ADDRESSES_XP*>( p_adapter );
-        // On Windows Server 2003 and Windows XP, this member is zero if IPv4 is not available on the interface.
-        if (ipv6)
-            return p_adapter_xp->Ipv6IfIndex != 0;
+        // On Windows Server 2003 and Windows XP, those members are zero if the IPv* implementation
+        // is not available on the interface.
+#if defined( UPNP_ENABLE_IPV6 )
+        return p_adapter_xp->Ipv6IfIndex != 0 || p_adapter_xp->IfIndex != 0;
+#else
         return p_adapter_xp->IfIndex != 0;
+#endif
     }
     IP_ADAPTER_ADDRESSES_LH* p_adapter_lh = reinterpret_cast<IP_ADAPTER_ADDRESSES_LH*>( p_adapter );
     if (p_adapter_lh->FirstGatewayAddress == NULL)
         return false;
-    if (ipv6)
-        return p_adapter_lh->Ipv6Enabled;
+#if defined( UPNP_ENABLE_IPV6 )
+    return p_adapter_lh->Ipv6Enabled || p_adapter_lh->Ipv4Enabled;
+#else
     return p_adapter_lh->Ipv4Enabled;
+#endif
 }
 
 inline IP_ADAPTER_ADDRESSES* ListAdapters()
@@ -220,7 +197,7 @@ inline char* getPreferedAdapter()
     p_adapter = addresses;
     while (p_adapter != NULL)
     {
-        if (isAdapterSuitable( p_adapter, true ))
+        if (isAdapterSuitable( p_adapter ))
         {
             /* make sure it supports 239.255.255.250 */
             IP_ADAPTER_MULTICAST_ADDRESS *p_multicast = getMulticastAddress( p_adapter );
@@ -236,93 +213,6 @@ inline char* getPreferedAdapter()
     free(addresses);
     return NULL;
 }
-
-inline char *getIpv4ForMulticast()
-{
-    IP_ADAPTER_UNICAST_ADDRESS *p_best_ip = NULL;
-    wchar_t psz_uri[32];
-    DWORD strSize;
-    IP_ADAPTER_ADDRESSES *p_adapter, *addresses;
-
-    addresses = ListAdapters();
-    if (addresses == NULL)
-        return NULL;
-
-    /* find one with multicast capabilities */
-    p_adapter = addresses;
-    while (p_adapter != NULL)
-    {
-        if (isAdapterSuitable( p_adapter, false ))
-        {
-            /* make sure it supports 239.255.255.250 */
-            IP_ADAPTER_MULTICAST_ADDRESS *p_multicast = getMulticastAddress( p_adapter );
-            if (p_multicast != NULL)
-            {
-                /* get an IPv4 address */
-                IP_ADAPTER_UNICAST_ADDRESS *p_unicast = p_adapter->FirstUnicastAddress;
-                while (p_unicast != NULL)
-                {
-                    strSize = sizeof( psz_uri ) / sizeof( wchar_t );
-                    if( WSAAddressToString( p_unicast->Address.lpSockaddr,
-                                            p_unicast->Address.iSockaddrLength,
-                                            NULL, psz_uri, &strSize ) == 0 )
-                    {
-                        if ( p_best_ip == NULL ||
-                             p_best_ip->ValidLifetime > p_unicast->ValidLifetime )
-                        {
-                            p_best_ip = p_unicast;
-                        }
-                    }
-                    p_unicast = p_unicast->Next;
-                }
-            }
-        }
-        p_adapter = p_adapter->Next;
-    }
-
-    if ( p_best_ip != NULL )
-        goto done;
-
-    /* find any with IPv4 */
-    p_adapter = addresses;
-    while (p_adapter != NULL)
-    {
-        if (isAdapterSuitable(p_adapter, false))
-        {
-            /* get an IPv4 address */
-            IP_ADAPTER_UNICAST_ADDRESS *p_unicast = p_adapter->FirstUnicastAddress;
-            while (p_unicast != NULL)
-            {
-                strSize = sizeof( psz_uri ) / sizeof( wchar_t );
-                if( WSAAddressToString( p_unicast->Address.lpSockaddr,
-                                        p_unicast->Address.iSockaddrLength,
-                                        NULL, psz_uri, &strSize ) == 0 )
-                {
-                    if ( p_best_ip == NULL ||
-                         p_best_ip->ValidLifetime > p_unicast->ValidLifetime )
-                    {
-                        p_best_ip = p_unicast;
-                    }
-                }
-                p_unicast = p_unicast->Next;
-            }
-        }
-        p_adapter = p_adapter->Next;
-    }
-
-done:
-    if (p_best_ip != NULL)
-    {
-        strSize = sizeof( psz_uri ) / sizeof( wchar_t );
-        WSAAddressToString( p_best_ip->Address.lpSockaddr,
-                            p_best_ip->Address.iSockaddrLength,
-                            NULL, psz_uri, &strSize );
-        free(addresses);
-        return FromWide( psz_uri );
-    }
-    free(addresses);
-    return NULL;
-}
 #else /* _WIN32 */
 
 #ifdef __APPLE__
@@ -400,59 +290,6 @@ inline char *getPreferedAdapter()
 
 #endif
 
-#ifdef __APPLE__
-
-inline bool necessaryFlagsSetOnInterface(struct ifaddrs *anInterface)
-{
-    unsigned int flags = anInterface->ifa_flags;
-    if( (flags & IFF_UP) && (flags & IFF_RUNNING) && !(flags & IFF_LOOPBACK) && !(flags & IFF_POINTOPOINT) ) {
-        return true;
-    }
-    return false;
-}
-
-static char *getIpv4ForMulticast()
-{
-    struct ifaddrs *listOfInterfaces;
-    struct ifaddrs *anInterface;
-    int ret = getifaddrs(&listOfInterfaces);
-    char *bestIP = NULL;
-
-    if (ret != 0) {
-        return NULL;
-    }
-
-    anInterface = listOfInterfaces;
-    while (anInterface != NULL) {
-        if (anInterface->ifa_addr->sa_family == AF_INET) {
-            bool ret = necessaryFlagsSetOnInterface(anInterface);
-            if (ret) {
-                /* ignore sockets connecting to the touchbar on MacBooks */
-                if (strncmp(anInterface->ifa_name, "bridge", 6) != 0) {
-                    if (bestIP) {
-                        FREENULL(bestIP);
-                    }
-                    bestIP = strdup(inet_ntoa(((struct sockaddr_in *)anInterface->ifa_addr)->sin_addr));
-                }
-            }
-        }
-
-        anInterface = anInterface->ifa_next;
-    }
-    freeifaddrs(listOfInterfaces);
-
-    return bestIP;
-}
-
-#else
-
-static char *getIpv4ForMulticast()
-{
-    return NULL;
-}
-
-#endif
-
 #endif /* _WIN32 */
 
 #endif


=====================================
modules/stream_out/dlna/dlna.cpp
=====================================
@@ -95,64 +95,12 @@ private:
 
 };
 
-char *getServerIPAddress() {
-    char *ip = nullptr;
-#ifdef UPNP_ENABLE_IPV6
-#ifdef _WIN32
-    IP_ADAPTER_UNICAST_ADDRESS *p_best_ip = nullptr;
-    wchar_t psz_uri[32];
-    DWORD strSize;
-    IP_ADAPTER_ADDRESSES *p_adapter, *addresses;
-
-    addresses = ListAdapters();
-    if (addresses == nullptr)
-        return nullptr;
-
-    p_adapter = addresses;
-    while (p_adapter != nullptr)
-    {
-        if (isAdapterSuitable(p_adapter, false))
-        {
-            IP_ADAPTER_UNICAST_ADDRESS *p_unicast = p_adapter->FirstUnicastAddress;
-            while (p_unicast != nullptr)
-            {
-                strSize = sizeof( psz_uri ) / sizeof( wchar_t );
-                if( WSAAddressToString( p_unicast->Address.lpSockaddr,
-                                        p_unicast->Address.iSockaddrLength,
-                                        nullptr, psz_uri, &strSize ) == 0 )
-                {
-                    if ( p_best_ip == nullptr ||
-                         p_best_ip->ValidLifetime > p_unicast->ValidLifetime )
-                    {
-                        p_best_ip = p_unicast;
-                    }
-                }
-                p_unicast = p_unicast->Next;
-            }
-        }
-        p_adapter = p_adapter->Next;
-    }
-
-    if (p_best_ip != nullptr)
-    {
-        strSize = sizeof( psz_uri ) / sizeof( wchar_t );
-        WSAAddressToString( p_best_ip->Address.lpSockaddr,
-                            p_best_ip->Address.iSockaddrLength,
-                            nullptr, psz_uri, &strSize );
-        free(addresses);
-        return FromWide( psz_uri );
-    }
-    free(addresses);
-    return nullptr;
-#endif /* _WIN32 */
-#else /* UPNP_ENABLE_IPV6 */
-    ip = getIpv4ForMulticast();
-#endif /* UPNP_ENABLE_IPV6 */
-    if (ip == nullptr)
-    {
-        ip = strdup(UpnpGetServerIpAddress());
+static char *getServerIPAddress() {
+    const char *ip = UpnpGetServerIpAddress();
+    if (ip == nullptr) {
+        ip = UpnpGetServerIp6Address();
     }
-    return ip;
+    return ip != nullptr ? strdup(ip) : nullptr;
 }
 
 std::string dlna_write_protocol_info (const protocol_info_t info)



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e3e0854b6dd61d0dde8017257b9e04713a00670a...b9daafa91b053bac65c365e459b6ac3c96388f2d

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e3e0854b6dd61d0dde8017257b9e04713a00670a...b9daafa91b053bac65c365e459b6ac3c96388f2d
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list