From 2016983d3544e827c0cb0192464185ff83f1f7bb Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Fri, 31 May 2013 17:21:10 +0200 Subject: [PATCH] Add supybot.utils.net.getAddressFromHostname() and improve Socket driver to try successively all IP addresses. --- src/drivers/Socket.py | 8 ++++++-- src/utils/net.py | 8 ++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/drivers/Socket.py b/src/drivers/Socket.py index 1e13cb545..0f69c673b 100644 --- a/src/drivers/Socket.py +++ b/src/drivers/Socket.py @@ -72,6 +72,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): drivers.IrcDriver.__init__(self, irc) drivers.ServersMixin.__init__(self, irc) self.conn = None + self._attempt = -1 self.servers = () self.eagains = 0 self.inbuffer = b'' @@ -239,6 +240,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): self.reconnect(reset=False, **kwargs) def reconnect(self, reset=True): + self._attempt += 1 self.nextReconnectTime = None if self.connected: drivers.log.reconnect(self.irc.network) @@ -256,6 +258,8 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): else: drivers.log.debug('Not resetting %s.', self.irc) server = self._getNextServer() + address = utils.net.getAddressFromHostname(server[0], + attempt=self._attempt) drivers.log.connect(self.currentServer) try: socks_proxy = getattr(conf.supybot.networks, self.irc.network) \ @@ -267,7 +271,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): log.error('Cannot use socks proxy (SocksiPy not installed), ' 'using direct connection instead.') socks_proxy = '' - self.conn = utils.net.getSocket(server[0], socks_proxy) + self.conn = utils.net.getSocket(address, socks_proxy) vhost = conf.supybot.protocols.irc.vhost() self.conn.bind((vhost, 0)) except socket.error, e: @@ -281,7 +285,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): if getattr(conf.supybot.networks, self.irc.network).ssl(): assert globals().has_key('ssl') self.conn = ssl.wrap_socket(self.conn) - self.conn.connect(server) + self.conn.connect((address, server[1])) def setTimeout(): self.conn.settimeout(conf.supybot.drivers.poll()) conf.supybot.drivers.poll.addCallback(setTimeout) diff --git a/src/utils/net.py b/src/utils/net.py index 9a14b5cb6..f8361fe23 100644 --- a/src/utils/net.py +++ b/src/utils/net.py @@ -80,6 +80,14 @@ class EmailRe: return count >= 1 emailRe = EmailRe() +def getAddressFromHostname(host, attempt=0): + addrinfo = socket.getaddrinfo(host, None) + addresses = [] + for (family, socktype, proto, canonname, sockaddr) in addrinfo: + if sockaddr[0] not in addresses: + addresses.append(sockaddr[0]) + return addresses[attempt % len(addresses)] + def getSocket(host, socks_proxy=None): """Returns a socket of the correct AF_INET type (v4 or v6) in order to communicate with host.