Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

greendns: don't contact nameservers if one entry is returned from hosts file #512

Merged
merged 1 commit into from Aug 3, 2018

Conversation

danalsan
Copy link
Contributor

@danalsan danalsan commented Aug 2, 2018

getaddrinfo() behaves differently from the standard implementation as
it will try to contact nameservers if only one (IPv4 or IPv6) entry
is returned from /etc/hosts file.

This patch avoids getaddrinfo() querying nameservers if at least one
entry is fetched through the hosts file to match the behavior of
the original socket.getaddrinfo() implementation.

Closes #515

Signed-off-by: Daniel Alvarez dalvarez@redhat.com

@codecov-io
Copy link

codecov-io commented Aug 2, 2018

Codecov Report

Merging #512 into master will increase coverage by <1%.
The diff coverage is 86%.

Impacted file tree graph

@@          Coverage Diff           @@
##           master   #512    +/-   ##
======================================
+ Coverage      46%    46%   +<1%     
======================================
  Files          81     81            
  Lines        7945   7948     +3     
  Branches     1359   1361     +2     
======================================
+ Hits         3659   3661     +2     
- Misses       4033   4034     +1     
  Partials      253    253
Flag Coverage Δ
#ipv6 14% <6%> (-1%) ⬇️
#py27epolls 49% <86%> (ø) ⬆️
#py27poll 49% <86%> (-1%) ⬇️
#py27selects 48% <86%> (ø) ⬆️
#py34epolls 42% <86%> (-1%) ⬇️
#py34poll 42% <86%> (-1%) ⬇️
#py34selects 41% <86%> (-1%) ⬇️
#py35epolls 42% <86%> (-1%) ⬇️
#py35poll 41% <86%> (-1%) ⬇️
#py35selects 41% <86%> (ø) ⬆️
#py36epolls 42% <86%> (ø) ⬆️
#py36poll 41% <86%> (-1%) ⬇️
#py36selects 41% <86%> (ø) ⬆️
#py37epolls 42% <86%> (ø) ⬆️
#py37poll 41% <86%> (-1%) ⬇️
#py37selects 41% <86%> (ø) ⬆️
Impacted Files Coverage Δ
eventlet/support/greendns.py 71% <86%> (ø) ⬆️
eventlet/hubs/hub.py 88% <0%> (-1%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8b85489...27dc6d7. Read the comment docs.

@@ -398,10 +399,12 @@ def getaliases(self, hostname):
resolver = ResolverProxy(hosts_resolver=HostsResolver())


def resolve(name, family=socket.AF_INET, raises=True, _proxy=None):
def resolve(name, family=socket.AF_INET, raises=True, _proxy=None,
use_dns=True):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless this name is commonly known in other APIs, could you please rename it to use_network?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

if answer.rrset:
addrs.extend(rr.address for rr in answer.rrset)
if addrs:
break
if err is not None and not addrs:
raise err
elif family == socket.AF_INET6 and flags & socket.AI_V4MAPPED:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When resolve() family is specified, it works as before, going to network. Is that how getaddrinfo works also?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's another else block below too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When resolve() family is specified it works as before, ie. returning the entry on hosts file and not using network if it's there.
My change basically applies to getaddrinfo() where if a IPv4 or IPv6 entry was fetched from /etc/hosts it won't attempt to get it from the network. Before this patch, if for example only an IPv4 entry was found, it'll query the network for the IPv6 resolution. Makes sense?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sorry, I meant _getaddrinfo_lookup() with family not AF_UNSPEC.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes if family not AF_UNSPEC then my patch is not changing the behavior

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should, to match system getaddrinfo, right?

Copy link
Contributor Author

@danalsan danalsan Aug 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@temoto before my patch, individual calls to resolve() (ie. family not being AF_UNSPEC) were already checking hosts file first. Problem was that calls with AF_UNSPEC will call twice to resolve (one with AF_INET6 and one with AF_INET) and if only one (4 or 6) entry is present in hosts file, the other call will contact the network.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood now. Thanks.

@temoto
Copy link
Member

temoto commented Aug 2, 2018

Could you write a test for new behavior?

@danalsan
Copy link
Contributor Author

danalsan commented Aug 2, 2018

I sent a new version with the test

base.rr.address = addr_from_ns
base.rr6.address = addr6_from_ns
rp._resolver = base()
greendns.resolver = rp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This modifies global state for all other tests. Please use @/with mock.patch or isolated test or try/finally.

…ts file

getaddrinfo() behaves differently from the standard implementation as
it will try to contact nameservers if only one (IPv4 or IPv6) entry
is returned from /etc/hosts file.

This patch avoids getaddrinfo() querying nameservers if at least one
entry is fetched through the hosts file to match the behavior of
the original socket.getaddrinfo() implementation.

Closes eventlet#515

Signed-off-by: Daniel Alvarez <dalvarez@redhat.com>
@temoto
Copy link
Member

temoto commented Aug 2, 2018

@jstasiak review please

Copy link
Member

@temoto temoto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you

Copy link
Contributor

@jstasiak jstasiak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mangelajo
Copy link

Looks good to me! :)

@temoto temoto merged commit 10ff67f into eventlet:master Aug 3, 2018
@temoto temoto added this to the 0.25 milestone Aug 3, 2018
@temoto
Copy link
Member

temoto commented Aug 3, 2018

@danalsan thank you, merged in 10ff67f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants