[vlc-devel] [PATCH 6/7] mdns: Add basic ip address detection (Linux)
Rémi Denis-Courmont
remi at remlab.net
Sun Aug 4 16:13:42 CEST 2019
Hi,
How does libmicrodns work if there are multiple apps, multiple users and/or multiple instances of the same app running?
Le 4 août 2019 07:55:49 GMT+02:00, Roland Bewick <roland.bewick at gmail.com> a écrit :
>
>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?
>
>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
--
Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20190804/95156c77/attachment.html>
More information about the vlc-devel
mailing list