Skip to content

Commit 6db693d

Browse files
committed
Use asyncio to avoid blocking sock.getaddrinfo
when DNS resolution fails.
1 parent 3eb690b commit 6db693d

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ The table below shows which release corresponds to each branch, and what date th
7474

7575
## 5.0.0 (`dev`)
7676

77+
- [#2541][2541] Fix blocking `tube.remote()` when DNS resolution fail.
7778
- [#2519][2519] Drop Python 2.7 support / Require Python 3.10
7879
- [#2507][2507] Add `+LINUX` and `+WINDOWS` doctest options and start proper testing on Windows
7980
- [#2522][2522] Support starting a kitty debugging window with the 'kitten' command
@@ -84,6 +85,7 @@ The table below shows which release corresponds to each branch, and what date th
8485
- [#2530][2530] Do NOT error when passing directory arguments in `checksec` commandline tool.
8586
- [#2529][2529] Add LoongArch64 support
8687

88+
[2541]: https://github.com/Gallopsled/pwntools/pull/2541
8789
[2519]: https://github.com/Gallopsled/pwntools/pull/2519
8890
[2507]: https://github.com/Gallopsled/pwntools/pull/2507
8991
[2522]: https://github.com/Gallopsled/pwntools/pull/2522

pwnlib/tubes/remote.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import absolute_import
22
from __future__ import division
33

4+
import asyncio
45
import socket
56
import socks
67

@@ -109,8 +110,17 @@ def _connect(self, fam, typ):
109110
sock = None
110111
timeout = self.timeout
111112

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+
112118
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 before we have the needs.
122+
results = asyncio.run(resolve_hostname(self.rhost, self.rport, fam, typ, 0, socket.AI_PASSIVE))
123+
for res in results:
114124
self.family, self.type, self.proto, _canonname, sockaddr = res
115125

116126
if self.type not in [socket.SOCK_STREAM, socket.SOCK_DGRAM]:

0 commit comments

Comments
 (0)