[vlc-devel] [PATCH 6/7] mdns: Add basic ip address detection (Linux)
Thomas Guillem
thomas at gllm.fr
Fri Aug 2 08:03:42 CEST 2019
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.
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) ?
>
> 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
More information about the vlc-devel
mailing list