Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.
Bug 554305 - [RFE] add mdns support to c-ares
Summary: [RFE] add mdns support to c-ares
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Fedora
Classification: Fedora
Component: c-ares
Version: rawhide
Hardware: All
OS: Linux
low
medium
Target Milestone: ---
Assignee: Tom "spot" Callaway
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2010-01-11 11:01 UTC by Tomasz Torcz
Modified: 2014-01-21 23:13 UTC (History)
13 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2010-12-01 11:12:34 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
stracde output (deleted)
2010-01-11 16:33 UTC, Tomasz Torcz
no flags Details

Description Tomasz Torcz 2010-01-11 11:01:20 UTC
Description of problem:
It looks for me that yum in rawhide is ignoring /etc/nsswitch.conf settings. I have a proxy in LAN which I get access into using mDNS name:

# echo $http_proxy
http://sabretooth.local:8080

I have nss-mdns installed with correct entry:
# grep mdns /etc/nsswitch.conf
hosts:      files mdns4_minimal [NOTFOUND=return] dns

No application have problems with it, except for yum:

# ping sabretooth.local
PING sabretooth.local (192.168.6.9) 56(84) bytes of data.
64 bytes from 192.168.6.9: icmp_seq=1 ttl=64 time=0.596 ms
64 bytes from 192.168.6.9: icmp_seq=2 ttl=64 time=0.395 ms

# wget kernel.org
--2010-01-11 11:58:50--  http://kernel.org/
Resolving sabretooth.local... 192.168.6.9
Connecting to sabretooth.local|192.168.6.9|:8080... connected.
Proxy request sent, awaiting response... 200 OK


# yum install calamaris
[trimmed output]

Downloading Packages:
Setting up and reading Presto delta metadata
Processing delta metadata
Package(s) data still to download: 54 k
http://ftp.ps.pl/pub/Linux/fedora-linux/development/x86_64/os/Packages/calamaris-2.59-3.fc12.noarch.rpm: [Errno 14] PYCURL ERROR 6 - ""
Trying other mirror.
http://fedora.tu-chemnitz.de/pub/linux/fedora/linux/development/x86_64/os/Packages/calamaris-2.59-3.fc12.noarch.rpm: [Errno 14] PYCURL ERROR 6 - ""
Trying other mirror.
http://mirror.ovh.net/download.fedora.redhat.com/linux/development/x86_64/os/Packages/calamaris-2.59-3.fc12.noarch.rpm: [Errno 14] PYCURL ERROR 6 - ""
Trying other mirror.

[...]

Error Downloading Packages:
  calamaris-2.59-3.fc12.noarch: failure: Packages/calamaris-2.59-3.fc12.noarch.rpm from rawhide: [Errno 256] No more mirrors to try.


I've tracked it down to yum issuing DNS request to DNS resolver listed in /etc/resolv.conf. Here is snippet of tcpdump output intermixed with yum output:

---
1:52:12.311924 IP 192.168.6.11.35331 > 192.168.1.1.domain: 30019+ A? sabretooth.local. (34)
11:52:21.696674 IP 192.168.6.11.35331 > 192.168.1.1.domain: 30019+ A? sabretooth.local. (34)

http://ftp.ps.pl/pub/Linux/fedora-linux/development/x86_64/os/Packages/calamaris-2.59-3.fc12.noarch.rpm: [Errno 14] PYCURL ERROR 6 - ""
Trying other mirror.

11:52:32.316922 IP 192.168.6.11.41637 > 192.168.1.1.domain: 47568+ A? sabretooth.local. (34)
11:52:36.070998 IP 192.168.6.11.41637 > 192.168.1.1.domain: 47568+ A? sabretooth.local. (34)
---

 I see no mdns requests whatsoever on wire while yum is running. No application is supposed to ask DNS resolver server for *.local domains.



Version-Release number of selected component (if applicable):
# rpm -q yum; rpm -q python-urlgrabber; rpm -q libcurl; rpm -q nss-mdns
yum-3.2.25-8.fc13.noarch
python-urlgrabber-3.9.1-4.fc13.noarch
libcurl-7.19.7-9.fc13.x86_64
nss-mdns-0.10-8.fc12.x86_64


How reproducible:
Always.

Steps to Reproduce:
1. Set http_proxy variable to host in .local domain
2. do yum upgrade
3. observe failure.
  
Actual results:
nss-dns isn't consulted for *.local hosts.

Expected results:
Zeroconf names resolution.

Additional info:

Comment 1 seth vidal 2010-01-11 14:29:53 UTC
What version of curl do you have installed?

Comment 2 Tomasz Torcz 2010-01-11 15:58:43 UTC
# rpm -q curl libcurl
curl-7.19.7-9.fc13.x86_64
libcurl-7.19.7-9.fc13.x86_64

curl doesn't work, while wget has no problem:

# curl -v -S www.kernel.org; wget www.kernel.org

* Could not resolve host: www.kernel.org (Domain name not found)
* Closing connection #0
curl: (6) Could not resolve host: www.kernel.org (Domain name not found)


--2010-01-11 16:57:50--  http://www.kernel.org/
Translacja sabretooth.local... 192.168.6.9
Łączenie się z sabretooth.local|192.168.6.9|:8080... połączono.
Żądanie Proxy wysłano, oczekiwanie na odpowiedź... 200 OK

Comment 3 Kamil Dudka 2010-01-11 16:19:24 UTC
Could you please capture the following strace and attach?

$ strace -e trace=open -o strace.txt curl -svo/dev/null http://www.kernel.org

Comment 4 Tomasz Torcz 2010-01-11 16:33:16 UTC
Created attachment 383018 [details]
stracde output

Comment 5 Kamil Dudka 2010-01-11 16:57:51 UTC
Thanks for the strace, it works as expected.  Unfortunately mdns is not supported by c-ares for now. Only "dns" and "files" resources are supported for now.  Reassigning to c-ares as it is the place where this bug should be addressed.  Patches are welcome!

Comment 6 Tomasz Torcz 2010-01-11 17:24:00 UTC
It works in curl-7.19.7-6.fc12.x86_64 in F12. Shouldn't this bug be treated as a regression?

Comment 7 Kamil Dudka 2010-01-11 17:29:23 UTC
I think so.

Comment 8 Tom "spot" Callaway 2010-01-21 04:55:58 UTC
The initial work to support mdns as an option has been done here:

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=476735

However, that only adds mdns as an option, it doesn't actually enable c-ares to do mdns lookups/resolves. For that, you'd either need to add code to c-ares to let NSS do the work (which upstream has already said it does not want to do), or leverage avahi to handle mdns. I suspect the latter would be acceptable to upstream, but I'm very far from an expert in this space.

Adding Lennart Poettering to the CC, as he _is_ an expert in this space. :)

Comment 9 Lennart Poettering 2010-01-25 17:05:44 UTC
Uh. c-ares' approach is very questionnable. You really should not bypass the NSS stack when doing name resolving. Implementing your own DNS client stack adds a bunch of redundant code, adds a whole new set of security issues and makes it impossible to replace the name resolving protocol backend as this case shows.

There are better solutions, like using libasyncns, which is my own solution to the problem and which simply makes the NSS usable asynchronously without headaches (http://0pointer.de/lennart/projects/libasyncns/). libasyncns has been imported into the glib tree recently, since it is about the only solution for somewhat clean name resolution, if you don't want to run into issues like this.

So yepp, my recommendation is to drop c-ares, and adopt libasyncns for all asynchronous name resolution. But then, I wrote libasyncns. But I did so for a reason. And the glib folks adopted libasyncns for a reason, too.

The other options would be to implement your own mDNS stack in addition to the classic unicast DNS stack. However I can only strongly recommend not to do this since mDNS is highly optimized for reducing network traffic and does so by employing quite sophisticated cache coherency protocols. And you cannot implement that properly unless you are a constantly running mDNS daemon, which is Avahi for us.

The last option would be to talk directly to the /var/run/avahi-daemon/socket= socket. It speaks a very simple text based protocol for doing mDNS name resolution via Avahi. It's not really documented, but nss-mdns should give you an idea how to do this. If you really want to stick with c-ares then this is certainly the best solution.

Comment 10 Kamil Dudka 2010-01-25 18:35:39 UTC
> There are better solutions, like using libasyncns, which is my own solution to
> the problem and which simply makes the NSS usable asynchronously without
> headaches (http://0pointer.de/lennart/projects/libasyncns/). libasyncns has

I've never heard about libasyncns.  Thanks for the hint!  It looks pretty compact to me.  Do you think we can replace c-ares by libasyncns completely in libcurl?

> been imported into the glib tree recently, since it is about the only solution
> for somewhat clean name resolution, if you don't want to run into issues like
> this.

Does it mean libasyncns is now maintained at two places?

Looking into asyncns-test.c I am a bit scared by the signal(SIGCHLD, SIG_IGN) as the first command :-)  Is it really safe to do something like that in a library?

Comment 11 Lennart Poettering 2010-01-28 03:03:26 UTC
(In reply to comment #10)
> > There are better solutions, like using libasyncns, which is my own solution to
> > the problem and which simply makes the NSS usable asynchronously without
> > headaches (http://0pointer.de/lennart/projects/libasyncns/). libasyncns has
> 
> I've never heard about libasyncns.  Thanks for the hint!  It looks pretty
> compact to me.  Do you think we can replace c-ares by libasyncns completely in
> libcurl?

Yes, definitely.

You may either link against libasyncns or import asyncns.c and .h into your tree. If you do the latter, then you'll of course have to make sure to update it from time to time, however you don't have this additional dependency on a tiny library. I recommend to link instead of import.

I think all distros these days ship libasyncns these days anyway, so that dependency angst shouldn't matter too much.

> > been imported into the glib tree recently, since it is about the only solution
> > for somewhat clean name resolution, if you don't want to run into issues like
> > this.
> 
> Does it mean libasyncns is now maintained at two places?

Not really. The upstream version is the one that matters. I work with the glib folks to make sure the versions stay in sync and patches flow both ways. It works quite well in this case I guess, but of course if everyone imports asyncns.c into their trees this won't scale. 
 
> Looking into asyncns-test.c I am a bit scared by the signal(SIGCHLD, SIG_IGN)
> as the first command :-)  Is it really safe to do something like that in a
> library?    

No it certainly is not. However, you don't really need to put this there.

You can compile asyncns.c in two ways: either it runs the name resolving code in a seperate thread (default and how it is build in the distros) or in a seperate process. Only if you use the forking version the SIG_IGN matters. Because only then the other side of the internally used communication socket might die (maybe because someone killed the process explicitly or so) and thus if all bad things come together trigger a SIGPIPE because asyncns wrote to the disconnected socket right at that time.

Also, on Linux (i.e. where MSG_NOSIGNAL is available) the SIGPIPE madness isn't necessary at all.

So basically the SIG_IGN blocking matters only to be completely correct if you compile libasyncns in a non-default way, and only if you do so on non-Linux systems.

Comment 12 Kamil Dudka 2010-01-28 10:39:33 UTC
> I think all distros these days ship libasyncns these days anyway, so that
> dependency angst shouldn't matter too much.

I don't see any problems in the new dependency, too.

> You can compile asyncns.c in two ways: either it runs the name resolving code
> in a seperate thread (default and how it is build in the distros) or in a
> seperate process. Only if you use the forking version the SIG_IGN matters.
> Because only then the other side of the internally used communication socket
> might die (maybe because someone killed the process explicitly or so) and thus
> if all bad things come together trigger a SIGPIPE because asyncns wrote to the
> disconnected socket right at that time.

So is the library based on threading then?  The main advantage of c-ares over other libraries is that it is thread-safe, but does not use threading.  We have already thread-based name resolver in libcurl, but it's kind of not recommended.  So that I need to compare libasyncns with the built-in thread resolver at first.  Then I'll probably raise the issue at libcurl upstream since that's the place where the eventual enhancement should go.

Comment 13 Kamil Dudka 2010-01-28 11:18:47 UTC
The built-in thread resolver seems to be built only on Windows.  So there is some extra work needed in both cases.  I think the c-ares solution is a bit saner for a library in the first place since it does not require threading for itself.

I am only afraid the 'mdns' keyword is not the only one ignored by c-ares now.  We can write a patch for c-ares and close the bug ... and a new bug can be just opened for yet another glibc/nss plug-in.

FWIW I've just CC'd Daniel Stenberg as the upstream maintainer of libcurl and c-ares.

Comment 14 Lennart Poettering 2010-02-01 01:26:17 UTC
(In reply to comment #12)

> So is the library based on threading then?  The main advantage of c-ares over
> other libraries is that it is thread-safe, but does not use threading.  We have
> already thread-based name resolver in libcurl, but it's kind of not
> recommended.  So that I need to compare libasyncns with the built-in thread
> resolver at first.  Then I'll probably raise the issue at libcurl upstream
> since that's the place where the eventual enhancement should go.    

The library does use threading internally, but that is not seen on the outside. It is completely abstracted away, in a way, that -- as mentioned -- you can even replace that threading with a proper fork()ed off process if you wish.

Basically, from the outside you just have one opaque object (asyncns_t*) that allows you to get an fd (a single one) you can stick in your poll() loop.

This is the entire API:

http://0pointer.de/lennart/projects/libasyncns/doxygen/asyncns_8h.html

Comment 15 Lennart Poettering 2010-02-01 01:28:16 UTC
(In reply to comment #13)
> The built-in thread resolver seems to be built only on Windows.  So there is
> some extra work needed in both cases.  I think the c-ares solution is a bit
> saner for a library in the first place since it does not require threading for
> itself.

but it implements DNS natively and bypasses the NSS. That means it is unable to make use of any non-DNS name resolvers (mdns, ldap, yadda yadda), nor of any caching services available in the NSS or those resolvers (nscd, avahi, yadda yadda).

Really, c-ares is not a good choice.

Comment 16 Daniel Stenberg 2010-02-01 12:34:10 UTC
Due to c-ares' limitations in being a feature-complete replacement to the libc based resolver functions, we're working on a native threaded resolver that is already in the main code targeted for (lib)curl 7.20.0 but it is currently disabled by default and there actually isn't a current easy way to enable it.

The plan is to work on it and make it possible to enable it with configure starting sometime post-7.20.0.

To clarify: this is meant for POSIX systems. libcurl already has and builds with a threaded resolver for win32 systems by default.

Comment 17 Lennart Poettering 2010-02-04 23:26:11 UTC
Daniel, just out of curiosity, can you elaborate on that a little? i.e. I hope and assume you will base it on NSS, right? Are you planning to run those functions in a child process? or thread? What will this resolver code do that libasyncns doesn't do?

Comment 18 Kamil Dudka 2010-02-04 23:36:17 UTC
(In reply to comment #17)
> Daniel, just out of curiosity, can you elaborate on that a little? i.e. I hope
> and assume you will base it on NSS, right? Are you planning to run those
> functions in a child process? or thread? What will this resolver code do that
> libasyncns doesn't do?    

The code is already there - look into lib/hostthre.c in the curl sources.  It's only not supported on Linux for now because of some portability issues.

Comment 19 Daniel Stenberg 2010-02-05 08:22:13 UTC
(In reply to comment #17)
> Daniel, just out of curiosity, can you elaborate on that a little? i.e. I hope
> and assume you will base it on NSS, right? Are you planning to run those
> functions in a child process? or thread? What will this resolver code do that
> libasyncns doesn't do?    

I've not checked libasyncns at all (I didn't know it existed until this bug entry was brought to my attention), but I can only assume that if it is based on the regular name resolver functions and it uses threads, then the functionality should be equivalent.

The code for threaded resolving already in libcurl should work but it hasn't yet undergone extensive testing for POSIX systems and it won't do that until after the 7.20.0 release that is due to get shipped next week.

Comment 20 Tomasz Torcz 2010-04-23 08:26:02 UTC
7.20.1-2.fc14 seem to work with http_proxy=http://something.local:8080. Can we expect backport to F13?

Comment 21 Kamil Dudka 2010-04-23 09:59:43 UTC
(In reply to comment #20)
> 7.20.1-2.fc14 seem to work with http_proxy=http://something.local:8080. Can we
> expect backport to F13?    

Tomasz, thank you for your interest and the testing!

We can backport it to F13 at some point, but definitely _not_ now.  The threaded DNS resolver is even not supported by upstream beyond WIN32 yet.  It was experimentally enabled in rawhide two days ago and I don't consider the packages stable for now.  There are still some open questions which should be addressed before it hits stable Fedora.

For more details see the upstream thread:
http://curl.haxx.se/mail/lib-2010-04/0285.html

Comment 22 Kamil Dudka 2010-06-02 10:53:08 UTC
Starting by 7.20.1-1.fc13, libcurl no longer uses c-ares for name resolving.  It means that up2date libcurl is no more affected by this bug.

Comment 23 Kamil Dudka 2010-12-01 16:54:38 UTC
This bug is against c-ares and there has been nothing changed.  The support for mdns is still missing.  It should be closed as WONTFIX.


Note You need to log in before you can comment on or make changes to this bug.