summaryrefslogtreecommitdiff
path: root/amqp/transport.py
diff options
context:
space:
mode:
Diffstat (limited to 'amqp/transport.py')
-rw-r--r--amqp/transport.py70
1 files changed, 19 insertions, 51 deletions
diff --git a/amqp/transport.py b/amqp/transport.py
index b5a0d4b..2761f09 100644
--- a/amqp/transport.py
+++ b/amqp/transport.py
@@ -169,59 +169,27 @@ class _AbstractTransport:
sock.settimeout(prev)
def _connect(self, host, port, timeout):
- e = None
-
- # Below we are trying to avoid additional DNS requests for AAAA if A
- # succeeds. This helps a lot in case when a hostname has an IPv4 entry
- # in /etc/hosts but not IPv6. Without the (arguably somewhat twisted)
- # logic below, getaddrinfo would attempt to resolve the hostname for
- # both IP versions, which would make the resolver talk to configured
- # DNS servers. If those servers are for some reason not available
- # during resolution attempt (either because of system misconfiguration,
- # or network connectivity problem), resolution process locks the
- # _connect call for extended time.
- addr_types = (socket.AF_INET, socket.AF_INET6)
- addr_types_num = len(addr_types)
- for n, family in enumerate(addr_types):
- # first, resolve the address for a single address family
+ entries = socket.getaddrinfo(
+ host, port, socket.AF_UNSPEC, socket.SOCK_STREAM, SOL_TCP,
+ )
+ for i, res in enumerate(entries):
+ af, socktype, proto, canonname, sa = res
try:
- entries = socket.getaddrinfo(
- host, port, family, socket.SOCK_STREAM, SOL_TCP)
- entries_num = len(entries)
- except socket.gaierror:
- # we may have depleted all our options
- if n + 1 >= addr_types_num:
- # if getaddrinfo succeeded before for another address
- # family, reraise the previous socket.error since it's more
- # relevant to users
- raise (e
- if e is not None
- else socket.error(
- "failed to resolve broker hostname"))
- continue # pragma: no cover
-
- # now that we have address(es) for the hostname, connect to broker
- for i, res in enumerate(entries):
- af, socktype, proto, _, sa = res
+ self.sock = socket.socket(af, socktype, proto)
try:
- self.sock = socket.socket(af, socktype, proto)
- try:
- set_cloexec(self.sock, True)
- except NotImplementedError:
- pass
- self.sock.settimeout(timeout)
- self.sock.connect(sa)
- except OSError as ex:
- e = ex
- if self.sock is not None:
- self.sock.close()
- self.sock = None
- # we may have depleted all our options
- if i + 1 >= entries_num and n + 1 >= addr_types_num:
- raise
- else:
- # hurray, we established connection
- return
+ set_cloexec(self.sock, True)
+ except NotImplementedError:
+ pass
+ self.sock.settimeout(timeout)
+ self.sock.connect(sa)
+ except socket.error:
+ if self.sock:
+ self.sock.close()
+ self.sock = None
+ if i + 1 >= len(entries):
+ raise
+ else:
+ break
def _init_socket(self, socket_settings, read_timeout, write_timeout):
self.sock.settimeout(None) # set socket back to blocking mode