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

Rémi Denis-Courmont remi at remlab.net
Thu Jul 25 19:15:29 CEST 2019


Le torstaina 25. heinäkuuta 2019, 8.39.11 EEST Roland Bewick a écrit :
> 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!

You should never do detection.

For unsolicited announcements, you should either enumerate all eligible 
interfaces and spam all of them, or leave the IP stack routing table to pick 
the correct one at a given time.

For responses to unicast, you should copy the destination IP of the request as 
the source IP of the response.

And for responses to multicast, you should again let the IP stack routing 
table pick the correct source address for the inbound interface.

In any case, that can only work with packet info ancillary data. There are no 
reason to write OS-specific code here.

-- 
Реми Дёни-Курмон
http://www.remlab.net/





More information about the vlc-devel mailing list