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

Roland Bewick roland.bewick at gmail.com
Thu Jul 25 07:39:11 CEST 2019


On 24/07/2019 11:18 PM, Rémi Denis-Courmont wrote:
> Le keskiviikkona 24. heinäkuuta 2019, 19.10.50 EEST Roland Bewick a écrit :
>> Hi Rémi,
>>
>> Thanks for the reply.
>>
>> On 24/07/2019 10:59 PM, Rémi Denis-Courmont wrote:
>>> Le keskiviikkona 24. heinäkuuta 2019, 18.43.49 EEST Roland Bewick a écrit
> :
>>>> ---
>>>>
>>>>    modules/services_discovery/microdns.c | 62
>>>>
>>>> +++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3
>>>> deletions(-)
>>>>
>>>> diff --git a/modules/services_discovery/microdns.c
>>>> b/modules/services_discovery/microdns.c index c460126b58..fa34ffa8d8
>>>> 100644
>>>> --- a/modules/services_discovery/microdns.c
>>>> +++ b/modules/services_discovery/microdns.c
>>>> @@ -28,6 +28,12 @@
>>>>
>>>>    #include <stdatomic.h>
>>>>    #include <assert.h>
>>>>
>>>> +#if defined( _WIN32 )
>>>> +
>>>> +#else
>>>> +    #include <ifaddrs.h>
>>>> +#endif
>>>> +
>>>>
>>>>    #include <vlc_common.h>
>>>>    #include <vlc_plugin.h>
>>>>    #include <vlc_modules.h>
>>>>
>>>> @@ -868,9 +874,59 @@ CloseRD( vlc_object_t *p_this )
>>>>
>>>>        CleanDiscoveryCommon( p_sys );
>>>>    
>>>>    }
>>>>
>>>> -static char * detect_ip_address()
>>>> +static char * detect_ip_address( vlc_object_t *p_obj )
>>>>
>>>>    {
>>>>
>>>> -    return strdup("127.0.0.1"); /* TODO: actually detect ip address */
>>>> +    char result[16] = "127.0.0.1";
>>>> +    bool found = false;
>>>> +#if defined( _WIN32 )
>>>> +
>>>> +#else
>>>> +    struct ifaddrs *id;
>>>> +    if( getifaddrs( &id ) == 0 )
>>>> +    {
>>>> +        int selected_priority = 0;
>>>> +
>>>> +        for( ; id != NULL; id = id->ifa_next )
>>>> +        {
>>>> +            if( id->ifa_addr->sa_family == AF_INET )
>>>> +            {
>>>> +                struct sockaddr_in *addr_in = (struct sockaddr_in
>>>> *)id->ifa_addr; +
>>>> +                char *ip_address = inet_ntoa( addr_in->sin_addr );
>>>> +
>>>> +                /* TODO: smarter priority function. */
>>>> +                int priority = 0;
>>>> +                if( strncmp( "eth0", id->ifa_name, strlen( "eth0" ) ) ==
>>>> 0
>>>> ) +                {
>>>> +                    priority = 1000;
>>>> +                }
>>>> +                else if( strncmp( "wifi0", id->ifa_name, strlen( "wifi0"
>>>> )
>>>> ) == 0 ) +                {
>>>> +                    priority = 2000;
>>>> +                }
>>>> +
>>>> +                msg_Dbg( p_obj, "Assigned interface %s priority %d",
>>>> +                         id->ifa_name, priority);
>>>> +
>>>> +                if( priority > selected_priority )
>>>> +                {
>>>> +                    strcpy( result, ip_address );
>>>> +                    selected_priority = priority;
>>>> +                    found = true;
>>>> +                }
>>>> +            }
>>>> +        }
>>>> +    }
>>>> +    else
>>>> +    {
>>>> +        msg_Err( p_obj, "Couldn't get interface addresses");
>>>> +    }
>>> That could have worked in the nineties. Machines, especially laptops,
>>> change IP addresses and have multiple addresses routinely nowadays, and
>>> Linux desktops interfaces are not always called eth0 or wifi0.
>> I will take Alexandre's suggestion.
>>
>>> Besides, you need to respond with the correct IP address for the interface
>>> on which the request came, usually with IP_PKTINFO/IP6_PKTINFO if you use
>>> UDP.
>> Respond to what? I don't understand.
> Typically, discovery protocols wait for inbound client requests.

Oh - so I don't even have to do the detection myself. Great!

I had another look at libmicrodns - it actually does the work of 
figuring out which interfaces are valid to listen on already (doh) but 
doesn't pass the address to the callback function when there's a request.

In linux this is easy - libmicrodns already stores the sockaddr for each 
connection.

On Windows it's storing the interface index instead which isn't useful 
for this scenario.


So I think I need to update libmicrodns:

1. Modify how it currently retrieves Windows interfaces 
(GetAdaptersAddresses) to also include unicast addresses (currently 
ignored) and store the unicast address for each valid interface.

2. Pass the interface address (preferably as a string so Windows and 
Linux are handled the same) to the callback.

I can then remove Patch #6 and #7 and use the address provided by the 
callback.

Does this sound like a good way to go?

Thanks,

Roland




More information about the vlc-devel mailing list