summaryrefslogtreecommitdiffstats
path: root/deluge/ui/hostlist.py
diff options
context:
space:
mode:
Diffstat (limited to 'deluge/ui/hostlist.py')
-rw-r--r--deluge/ui/hostlist.py69
1 files changed, 40 insertions, 29 deletions
diff --git a/deluge/ui/hostlist.py b/deluge/ui/hostlist.py
index b4bb538fb..0fc3eabd8 100644
--- a/deluge/ui/hostlist.py
+++ b/deluge/ui/hostlist.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) Calum Lind 2017 <calumlind+deluge@gmail.com>
#
@@ -7,12 +6,10 @@
# See LICENSE for more details.
#
-from __future__ import unicode_literals
-
import logging
import os
import uuid
-from socket import gaierror, gethostbyname
+from socket import gaierror, getaddrinfo
from twisted.internet import defer
@@ -25,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():
@@ -47,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])
@@ -87,7 +84,15 @@ def migrate_config_2_to_3(config):
return config
-class HostList(object):
+def mask_hosts_password(hosts):
+ """Replace passwords in hosts list with *'s for log output"""
+ if not hosts:
+ return hosts
+
+ return [list(host)[:-1] + ['*' * 10] for host in hosts]
+
+
+class HostList:
"""This class contains methods for adding, removing and looking up hosts in hostlist.conf."""
def __init__(self):
@@ -97,6 +102,7 @@ class HostList(object):
default_hostlist(),
config_dir=get_config_dir(),
file_version=3,
+ log_mask_funcs={'hosts': mask_hosts_password},
)
self.config.run_converter((1, 2), 3, migrate_config_2_to_3)
self.config.save()
@@ -210,30 +216,35 @@ class HostList(object):
return defer.succeed(status_offline)
try:
- ip = gethostbyname(host)
- except gaierror as ex:
- log.error('Error resolving host %s to ip: %s', host, ex.args[1])
+ 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.