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

Marvin Scholz epirat07 at gmail.com
Sun Aug 4 14:51:58 CEST 2019



On 4 Aug 2019, at 7:55, 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?
>
> I've tested service discovery on Linux and Windows and it works. I 
> have no access to macOS.
>

It can not work if another mDNS daemon like avahi or bonjour is running 
as that is already
bound to the port. See https://github.com/videolabs/libmicrodns/issues/9

>
>>
>>>>
>>>> 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