|
1 | 1 | from __future__ import absolute_import
|
2 | 2 | from __future__ import division
|
3 | 3 |
|
| 4 | +import asyncio |
4 | 5 | import socket
|
5 | 6 | import socks
|
6 | 7 |
|
@@ -109,8 +110,17 @@ def _connect(self, fam, typ):
|
109 | 110 | sock = None
|
110 | 111 | timeout = self.timeout
|
111 | 112 |
|
| 113 | + async def resolve_hostname(host, port, fam=0, typ=0, proto=0, flags=0): |
| 114 | + loop = asyncio.get_event_loop() |
| 115 | + result = await loop.getaddrinfo(host, port, family=fam, type=typ, proto=proto, flags=flags) |
| 116 | + return result |
| 117 | + |
112 | 118 | with self.waitfor('Opening connection to %s on port %s' % (self.rhost, self.rport)) as h:
|
113 |
| - for res in socket.getaddrinfo(self.rhost, self.rport, fam, typ, 0, socket.AI_PASSIVE): |
| 119 | + # Using asyncio to avoid blocking when DNS resolution fail. It's probably better |
| 120 | + # to use async all the ways to `sock.connect`. However, let's keep the changes |
| 121 | + # small until we have the needs. |
| 122 | + hostnames = asyncio.run(resolve_hostname(self.rhost, self.rport, fam, typ, 0, socket.AI_PASSIVE)) |
| 123 | + for res in hostnames: |
114 | 124 | self.family, self.type, self.proto, _canonname, sockaddr = res
|
115 | 125 |
|
116 | 126 | if self.type not in [socket.SOCK_STREAM, socket.SOCK_DGRAM]:
|
|
0 commit comments