Package: python-gevent Version: 0.13.6-1 Severity: grave Tags: patch
Dear maintainer,as somewhere else upstream stated themselves (I have forgotten the URL where they did) that gevent.dns is somewhat completely broken in 0.13.6 (which is based on libevent, and they say it is broken there), I recommend using 1.0b1 for wheezy instead.
I use python-gevent for python-x2go intensively and the performance is much better with 1.0b1 and stability has also improved (the used event library is libev now).
One issue is that IPv6 DNS resolution does not work with 0.13.6 at all. As the world moves towards IPv6 (esp. in non-US and non-European parts of the world) I consider this issue as somewhat grave.
Attached is a patch that tries to fix this behaviour for gevent 0.13.6. The patch is not perfect, sometimes you have to wait quite long for name resolution of IPv6 addresses, but at the end they finally resolve. Much better would be a transition to 1.0b1 for wheezy (though the RT may not like this...).
Reproduce (IPv6-only host): =========================== """ mike@fylgja:~ python Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) [GCC 4.4.5] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import gevent.socket gevent.socket.gethostbyname("minobo.das-netzwerkteam.de")
Traceback (most recent call last): File "<stdin>", line 1, in <module>File "/usr/lib/pymodules/python2.6/gevent/socket.py", line 683, in gethostbyname
_ttl, addrs = resolve_ipv4(hostname) File "/usr/lib/pymodules/python2.6/gevent/dns.py", line 59, in resolve_ipv4 raise DNSError(result) gevent.dns.DNSError: [Errno 67] request timed out """ Should be::: """ mike@fylgja:~$ python Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) [GCC 4.4.5] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import gevent import gevent.socket gevent.socket.gethostbyname("minobo.das-netzwerkteam.de")
'2001:6f8:900:e5d::2' """ Reproduce (IPv4/IPv6 host): (first request is IPv4, second request times out) =========================== """ mike@fylgja:~$ python Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) [GCC 4.4.5] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import gevent.socket gevent.socket.gethostbyname("vidar.das-netzwerkteam.de")
'178.63.100.242'
gevent.socket.gethostbyname("vidar.das-netzwerkteam.de")
Traceback (most recent call last): File "<stdin>", line 1, in <module>File "/usr/lib/pymodules/python2.6/gevent/socket.py", line 683, in gethostbyname
_ttl, addrs = resolve_ipv4(hostname) File "/usr/lib/pymodules/python2.6/gevent/dns.py", line 59, in resolve_ipv4 raise DNSError(result) gevent.dns.DNSError: [Errno 67] request timed out """ Should be::: """ mike@fylgja:~$ python Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) [GCC 4.4.5] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import gevent import gevent.socket gevent.socket.gethostbyname("vidar.das-netzwerkteam.de")
'2a01:4f8:121:5085:250:56ff:fe15:236e' """With 1.0b1 the above tests work like a charm. With my provided patch applied to 0.13.6 it works, but with some serious time delays.
Mike -- DAS-NETZWERKTEAM mike gabriel, rothenstein 5, 24214 neudorf-bornstein fon: +49 (1520) 1976 148 GnuPG Key ID 0x25771B31 mail: mike.gabr...@das-netzwerkteam.de, http://das-netzwerkteam.de freeBusy: https://mail.das-netzwerkteam.de/freebusy/m.gabriel%40das-netzwerkteam.de.xfb
Nur in python-gevent-0.13.6.patched//gevent: __init__.pyc. diff -ur python-gevent-0.13.6/gevent/socket.py python-gevent-0.13.6.patched//gevent/socket.py --- python-gevent-0.13.6/gevent/socket.py 2011-05-17 16:02:29.000000000 +0200 +++ python-gevent-0.13.6.patched//gevent/socket.py 2012-10-18 16:06:41.000000000 +0200 @@ -680,8 +680,14 @@ return hostname if hostname == _socket.gethostname(): return _socket.gethostbyname(hostname) - _ttl, addrs = resolve_ipv4(hostname) - return inet_ntoa(random.choice(addrs)) + addrs = None + try: + _ttl, addrs = resolve_ipv4(hostname) + except: + _ttl, addrs = resolve_ipv6(hostname) + return inet_ntop(AF_INET6, random.choice(addrs)) + else: + return inet_ntop(AF_INET, random.choice(addrs)) def getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0, evdns_flags=0): """*Some* approximation of :func:`socket.getaddrinfo` implemented using :mod:`gevent.dns`. @@ -750,30 +756,28 @@ for socktype, proto in socktype_proto: result.append((family, socktype, proto, '', sockaddr)) else: - failure = None - job = spawn(wrap_errors(gaierror, resolve_ipv6), host, evdns_flags) + + ipv4_res = None + ipv6_res = None try: - try: - ipv4_res = resolve_ipv4(host, evdns_flags)[1] - except gaierror, failure: - ipv4_res = None - ipv6_res = job.get() - if isinstance(ipv6_res, gaierror): - ipv6_res = None - if failure is not None: - raise - if ipv4_res is not None: - for res in ipv4_res: - sockaddr = (inet_ntop(AF_INET, res), port) - for socktype, proto in socktype_proto: - result.append((AF_INET, socktype, proto, '', sockaddr)) - if ipv6_res is not None: - for res in ipv6_res[1]: - sockaddr = (inet_ntop(AF_INET6, res), port, 0, 0) - for socktype, proto in socktype_proto: - result.append((AF_INET6, socktype, proto, '', sockaddr)) - finally: - job.kill() + ipv4_res = resolve_ipv4(host, evdns_flags)[1] + except: + pass + if not ipv4_res: + ipv4_res = None + ipv6_res= resolve_ipv6(host, evdns_flags)[1] + + if ipv4_res is not None: + for res in ipv4_res: + sockaddr = (inet_ntop(AF_INET, res), port) + for socktype, proto in socktype_proto: + result.append((AF_INET, socktype, proto, '', sockaddr)) + if ipv6_res is not None: + for res in ipv6_res: + sockaddr = (inet_ntop(AF_INET6, res), port, 0, 0) + for socktype, proto in socktype_proto: + result.append((AF_INET6, socktype, proto, '', sockaddr)) + return result # TODO libevent2 has getaddrinfo that is probably better than the hack above; should wrap that.
pgpc7opVYKvGN.pgp
Description: Digitale PGP-Unterschrift