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

Thomas Guillem thomas at gllm.fr
Mon Aug 5 09:16:32 CEST 2019



On Sun, Aug 4, 2019, at 07:56, Roland Bewick wrote:
> 
> On 2/08/2019 4:19 PM, Marvin Scholz wrote:
> >
> >
> > On 2 Aug 2019, at 8:03, Thomas Guillem wrote:
> >
> >> On Wed, Jul 31, 2019, at 08:35, Roland Bewick wrote:
> >>>
> >>> On 27/07/2019 2:04 PM, Roland Bewick wrote:
> >>>>
> >>>> On 26/07/2019 1:07 AM, Rémi Denis-Courmont wrote:
> >>>>> Le torstaina 25. heinäkuuta 2019, 20.51.09 EEST Roland Bewick a 
> >>>>> écrit :
> >>>>>> On Fri, 26 Jul 2019 at 12:15 AM, Rémi Denis-Courmont 
> >>>>>> <remi at remlab.net>
> >>>>>>
> >>>>>> wrote:
> >>>>>>> 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.
> >>>>>> In this case we are responding to multicast (works currently as you
> >>>>>> mentioned above I think) BUT also we are providing a unicast ip
> >>>>>> address in
> >>>>>> the A/AAAA record in the response packet.
> >>>>>> The relationship between the unicast address and the multicast
> >>>>>> response is
> >>>>>> that they share the same interface. Right?
> >>>>> Multicast addresses do not have an interface; you can have the same
> >>>>> multicast
> >>>>> addresses on different interfaces referring to the same or to
> >>>>> different actual
> >>>>> group(s). AFAIK, you have to get the correct interface index from the
> >>>>> incoming
> >>>>> packet ancillary data.
> >>>> Ok, thanks for the information.
> >>>>
> >>>> libmicrodns scans all interface addresses on initialisation and for
> >>>> each valid one opens a socket.
> >>>>
> >>>> Each socket and interface [address (linux) / index (Windows)] are
> >>>> paired so when we get an incoming packet we know what interface it is.
> >>>> Therefore, I don't think we have to deal with packet ancillary data?
> >>>>
> >>>> The problem though is getting the unicast address for that interface
> >>>> so we can put it in the response body (A/AAAA record).
> >>>>
> >>>> If I'm correct, this needs to be calculated on Windows which will
> >>>> require OS-specific code. Then I will update libmicrodns to pass the
> >>>> IP address string to the callback so VLC can use it to populate the
> >>>> A/AAAA record.
> >>>>
> >>>> Does this sound like a valid approach?
> >>>>
> >>>> Thanks,
> >>>>
> >>>> Roland
> >>>
> >>>
> >>> Hi,
> >>>
> >>> I've made the necessary changes to libmicrodns. My pull request is
> >>> here:
> >>> https://github.com/videolabs/libmicrodns/pull/20/commits/fb58b2fffdce80be6381431845fc8e743920e054 
> >>>
> >>
> >> Hello, I will do the review on libmicrodns.
> Thanks Thomas
> >>
> >> I have one question though. Will it be possible to do the same with 
> >> avahi (used by default on linux Desktop) and bonjour (used by macOS) ?
> >>
> >
> > On macOS/iOS you would do something like:
> >
> >     NSNetService *service = [[NSNetService alloc] 
> > initWithDomain:@"local."
> > type:@"_http._tcp."
> > name:@"VLC media player something"
> > port:8080];
> >     [service publish];
> >
> > (We probably want to use CFNetServices instead as that is pure C, but 
> > it works really similar)
> >
> > It seems to work similar for avahi, see
> > https://www.avahi.org/doxygen/html/publish_8h.html#acb05a7d3d23a3b825ca77cb1c7d00ce4 
> >
> > When passing NULL for host, the daemon will use the local host name, 
> > just like what
> > happens in the above snippet for macOS/iOS.
> >
> > So we do not have to worry about which exact addresses to announce at 
> > all there.
> 
> 
> libmicrodns is our cross-platform solution for mDNS discovery / 
> advertisement. Why do we need to write specific code for Avahi / Bonjour 
> implementations?

No, libmicrodns is only used on mobile ports and windows.
Avahi is used on Linux, bonjour is used on macOS.

Therefore, Videolan doesn't package libmicrodns for macOS builds, and Linux distributions should not include both avahi and libmicrodns plugins.

> 
> I've tested service discovery on Linux and Windows and it works. I have 
> no access to macOS.
> 
> 
> >
> >>>
> >>> Please have a look and let me know if it's a viable solution.
> >>>
> >>> Thanks,
> >>>
> >>> Roland
> >>>
> >>> _______________________________________________
> >>> vlc-devel mailing list
> >>> To unsubscribe or modify your subscription options:
> >>> https://mailman.videolan.org/listinfo/vlc-devel
> >> _______________________________________________
> >> vlc-devel mailing list
> >> To unsubscribe or modify your subscription options:
> >> https://mailman.videolan.org/listinfo/vlc-devel
> > _______________________________________________
> > vlc-devel mailing list
> > To unsubscribe or modify your subscription options:
> > https://mailman.videolan.org/listinfo/vlc-devel
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list