From 63a83458abcbb4893b903784b2bb3c57817bea04 Mon Sep 17 00:00:00 2001
From: Tydus <Tydus@Tydus.org>
Date: Fri, 15 Sep 2017 15:03:57 +0900
Subject: [PATCH] Support IPv6 literal for daemon connection in gtkui
If a daemon is listening to "::" (i.e. invoked by deluged -u "::") or
a specific IPv6 address, the client could connect to it with IPv6
address literal (e.g. "2001:db8::1234", but not domain names).
The domain name is not supported since twisted could not yet handle
concurrent connection attempts for dual-stack domain names.
Therefore, currently, we need to manually handle the concurrent
attempts in deluge.ui.client. This will be a non-trivial modification
for all the clients.
---
deluge/ui/gtkui/connectionmanager.py | 4 ++--
deluge/ui/hostlist.py | 14 +++++++++-----
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/deluge/ui/gtkui/connectionmanager.py b/deluge/ui/gtkui/connectionmanager.py
index ba791ee..ab7fec1 100644
a
|
b
|
|
11 | 11 | |
12 | 12 | import logging |
13 | 13 | import os |
14 | | from socket import gaierror, gethostbyname |
| 14 | from socket import gaierror, getaddrinfo |
15 | 15 | |
16 | 16 | import gtk |
17 | 17 | from twisted.internet import defer, reactor |
… |
… |
def _update_widget_buttons(self):
|
218 | 218 | # Get selected host info. |
219 | 219 | __, host, port, __, __, status, __ = model[row] |
220 | 220 | try: |
221 | | gethostbyname(host) |
| 221 | getaddrinfo(host, port) |
222 | 222 | except gaierror as ex: |
223 | 223 | log.error('Error resolving host %s to ip: %s', row[HOSTLIST_COL_HOST], ex.args[1]) |
224 | 224 | self.builder.get_object('button_connect').set_sensitive(False) |
diff --git a/deluge/ui/hostlist.py b/deluge/ui/hostlist.py
index fa61555..ddc86c1 100644
a
|
b
|
|
13 | 13 | import os |
14 | 14 | import time |
15 | 15 | from hashlib import sha1 |
16 | | from socket import gaierror, gethostbyname |
| 16 | from socket import gaierror, getaddrinfo, AF_INET, AF_INET6 |
17 | 17 | |
18 | 18 | from twisted.internet import defer |
19 | 19 | |
… |
… |
def validate_host_info(hostname, port):
|
48 | 48 | """ |
49 | 49 | |
50 | 50 | try: |
51 | | gethostbyname(hostname) |
| 51 | getaddrinfo(hostname, port) |
52 | 52 | except gaierror as ex: |
53 | 53 | raise ValueError('Host %s: %s', hostname, ex.args[1]) |
54 | 54 | |
… |
… |
def on_connect_failed(reason, host_id):
|
197 | 197 | log.warning('Problem getting host_id info from hostlist') |
198 | 198 | return status_offline |
199 | 199 | |
| 200 | # Try to resolve to IPv4 first, for backward compatibility |
200 | 201 | try: |
201 | | ip = gethostbyname(host) |
| 202 | ip = getaddrinfo(host, port, AF_INET)[0][4][0] |
202 | 203 | except gaierror as ex: |
203 | | log.error('Error resolving host %s to ip: %s', host, ex.args[1]) |
204 | | return status_offline |
| 204 | try: |
| 205 | ip = getaddrinfo(host, port, AF_INET6)[0][4][0] |
| 206 | except gaierror as ex: |
| 207 | log.error('Error resolving host %s to ip: %s', host, ex.args[1]) |
| 208 | return status_offline |
205 | 209 | |
206 | 210 | host_conn_info = (ip, port, 'localclient' if not user and host in LOCALHOST else user) |
207 | 211 | if client.connected() and host_conn_info == client.connection_info(): |