summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortbkizle <tbkizle@gmail.com>2022-02-15 15:14:18 -0500
committerCalum Lind <calumlind+deluge@gmail.com>2022-02-18 23:05:12 +0000
commitc89a366dfb86863df290a64dddda6001475ffda8 (patch)
treea27f79f25b9e5447cdb3d905075e228c061c0ddd
parent5f8acabb81f265bd2c8a45db093b58e529833f01 (diff)
downloaddeluge-c89a366dfb86863df290a64dddda6001475ffda8.tar.gz
deluge-c89a366dfb86863df290a64dddda6001475ffda8.tar.bz2
deluge-c89a366dfb86863df290a64dddda6001475ffda8.zip
[Hostlist] Support IPv6 in host lists
socket.gethostbyname does not support IPv6 name resolution, and getaddrinfo() should be used instead for IPv4/v6 dual stack support. Closes: https://github.com/deluge-torrent/deluge/pull/376
-rw-r--r--deluge/ui/gtk3/connectionmanager.py4
-rw-r--r--deluge/ui/hostlist.py53
2 files changed, 31 insertions, 26 deletions
diff --git a/deluge/ui/gtk3/connectionmanager.py b/deluge/ui/gtk3/connectionmanager.py
index 0834ae7e4..b53dd8e04 100644
--- a/deluge/ui/gtk3/connectionmanager.py
+++ b/deluge/ui/gtk3/connectionmanager.py
@@ -8,7 +8,7 @@
import logging
import os
-from socket import gaierror, gethostbyname
+from socket import gaierror, getaddrinfo
from urllib.parse import urlparse
from gi.repository import Gtk
@@ -222,7 +222,7 @@ class ConnectionManager(component.Component):
__, host, port, __, __, status, __, __ = model[row]
try:
- gethostbyname(host)
+ getaddrinfo(host, None)
except gaierror as ex:
log.error(
'Error resolving host %s to ip: %s', row[HOSTLIST_COL_HOST], ex.args[1]
diff --git a/deluge/ui/hostlist.py b/deluge/ui/hostlist.py
index cb5a13447..0fc3eabd8 100644
--- a/deluge/ui/hostlist.py
+++ b/deluge/ui/hostlist.py
@@ -9,7 +9,7 @@
import logging
import os
import uuid
-from socket import gaierror, gethostbyname
+from socket import gaierror, getaddrinfo
from twisted.internet import defer
@@ -22,7 +22,7 @@ log = logging.getLogger(__name__)
DEFAULT_HOST = '127.0.0.1'
DEFAULT_PORT = 58846
-LOCALHOST = ('127.0.0.1', 'localhost')
+LOCALHOST = ('127.0.0.1', 'localhost', '::1')
def default_hostlist():
@@ -44,7 +44,7 @@ def validate_host_info(hostname, port):
"""
try:
- gethostbyname(hostname)
+ getaddrinfo(hostname, None)
except gaierror as ex:
raise ValueError('Host %s: %s', hostname, ex.args[1])
@@ -216,30 +216,35 @@ class HostList:
return defer.succeed(status_offline)
try:
- ip = gethostbyname(host)
- except gaierror as ex:
+ ips = list({addrinfo[4][0] for addrinfo in getaddrinfo(host, None)})
+ except (gaierror, IndexError) as ex:
log.warning('Unable to resolve host %s to IP: %s', host, ex.args[1])
return defer.succeed(status_offline)
- host_conn_info = (
- ip,
- port,
- 'localclient' if not user and host in LOCALHOST else user,
- )
- if client.connected() and host_conn_info == client.connection_info():
- # Currently connected to host_id daemon.
- def on_info(info, host_id):
- log.debug('Client connected, query info: %s', info)
- return host_id, 'Connected', info
-
- return client.daemon.info().addCallback(on_info, host_id)
- else:
- # Attempt to connect to daemon with host_id details.
- c = Client()
- d = c.connect(host, port, skip_authentication=True)
- d.addCallback(on_connect, c, host_id)
- d.addErrback(on_connect_failed, host_id)
- return d
+ host_conn_list = [
+ (
+ host_ip,
+ port,
+ 'localclient' if not user and host_ip in LOCALHOST else user,
+ )
+ for host_ip in ips
+ ]
+
+ for host_conn_info in host_conn_list:
+ if client.connected() and host_conn_info == client.connection_info():
+ # Currently connected to host_id daemon.
+ def on_info(info, host_id):
+ log.debug('Client connected, query info: %s', info)
+ return host_id, 'Connected', info
+
+ return client.daemon.info().addCallback(on_info, host_id)
+ else:
+ # Attempt to connect to daemon with host_id details.
+ c = Client()
+ d = c.connect(host, port, skip_authentication=True)
+ d.addCallback(on_connect, c, host_id)
+ d.addErrback(on_connect_failed, host_id)
+ return d
def update_host(self, host_id, hostname, port, username, password):
"""Update the supplied host id with new connection details.