aio-libs / aiodns

Simple DNS resolver for asyncio
https://pypi.python.org/pypi/aiodns
MIT License
538 stars 69 forks source link

Finding A requests that have been resolved via CNAME #63

Closed blark closed 3 years ago

blark commented 5 years ago

I don't know if this is a limitation of pycares, or if I'm missing something obvious.

Pycares seems to automatically follow CNAME entries to resolve the hostname to an IP address, but gives no indication of when it has done so. Is there any way to tell when this has happened, and if so what the CNAME was?

Thanks very much.

blark commented 5 years ago

An example for you:

 $ dig photos.google.ca

; <<>> DiG 9.14.2 <<>> photos.google.ca
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41107
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;photos.google.ca.              IN      A

;; ANSWER SECTION:
photos.google.ca.       10785   IN      CNAME   picasaweb.google.com.
picasaweb.google.com.   1580    IN      CNAME   picasaweb.l.google.com.
picasaweb.l.google.com. 900     IN      A       172.217.4.46

Will only return something like [<ares_query_a_result> host=172.217.4.46, ttl=62] with no indication that it was resolved via CNAME.

blark commented 5 years ago

Digging in to this further, it looks like gethostbyname kinda provides the information I am looking for.

The information returned (using the pycares asyncio example) is as follows when doing this request: resolver.gethostbyname('photos.google.ca', cb)

Result: <ares_host_result> name=picasaweb.l.google.com, aliases=['photos.google.ca', 'picasaweb.google.com'], addresses=['172.217.4.46'], Error: None

So while it doesn't directly indicate that a CNAME request was resolved, the presence of a name other than the original name requested along with the aliases list seems like enough indication that it happened. I have yet to inspect the aiodns source but I assume you're returning all the information from pycares...

One suggestion, perhaps you should make a note in the README.md file to this difference in the return values provided by the function? Could be helpful to anyone looking in the future!

saghul commented 5 years ago

Hi there!

I think this could be tackled if we pass an array of hostent entries here: https://github.com/saghul/pycares/blob/master/src/pycares/__init__.py#L150

That way we can get access to the aliases, like gethostbyname does. I'll try to take a look, but feel free to experiment and send a PR if you find it works!

nirvana-msu commented 5 years ago

I do miss this functionality very much. In my case, I want to know all (recursive) CNAME records even if they don't resolve to an IP. Dig gives all this information when doing A query. In this case even gethostbyname does not help - it only seems to return CNAME records when the domain actually resolves to an IP. The only way I can think of getting this information using aiodns right now is by manually doing recursive CNAME queries, which seems unnecessarily complex.

saghul commented 5 years ago

Last I checked that information is meeting in the c-ares structures so there is not much that we can do other than faking it by recursing if necessary in aiodns itself.

Parches to improve this are most welcome!