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

try connecting to all possible values returned from getaddrinfo #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 40 additions & 19 deletions puka/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,24 @@ def _connect(self):
self._handle_read = self._handle_conn_read
self._init_buffers()

addrinfo = None
if socket.has_ipv6:
addrinfo = socket.getaddrinfo(
self.host, self.port,
socket.AF_UNSPEC if socket.has_ipv6 else socket.AF_INET,
socket.SOCK_STREAM)

err = None

for addr in addrinfo:
try:
addrinfo = socket.getaddrinfo(
self.host, self.port, socket.AF_INET6, socket.SOCK_STREAM)
except socket.gaierror:
self.sd = connect_to(addr, len(addrinfo) == 1)
err = None
break
except socket.error, err:
pass
if not addrinfo:
addrinfo = socket.getaddrinfo(
self.host, self.port, socket.AF_INET, socket.SOCK_STREAM)

(family, socktype, proto, canonname, sockaddr) = addrinfo[0]
self.sd = socket.socket(family, socktype, proto)
self.sd.setblocking(False)
set_ridiculously_high_buffers(self.sd)
set_close_exec(self.sd)
try:
self.sd.connect(sockaddr)
except socket.error, e:
if e.errno not in (errno.EINPROGRESS, errno.EWOULDBLOCK):
raise

if err is not None:
raise err

return machine.connection_handshake(self)

def on_read(self):
Expand Down Expand Up @@ -435,3 +432,27 @@ def set_close_exec(fd):
fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
except ImportError:
pass

def prepare_socket(sd):
sd.setblocking(False)
set_ridiculously_high_buffers(sd)
set_close_exec(sd)

def connect_to(addr, nonblocking):
(family, socktype, proto, canonname, sockaddr) = addr
sock = socket.socket(family, socktype, proto)
if nonblocking:
prepare_socket(sock)

try:
sock.connect(sockaddr)
except socket.error, e:
if nonblocking and e.errno in (errno.EINPROGRESS, errno.EWOULDBLOCK):
return sock
sock.close()
raise e

if not nonblocking:
prepare_socket(sock)

return sock