commit 5a75ce74d775ec5ea789c546f879c7212027ba06
parent 0682166314464506d07e58ce95da96ba8940a900
Author: ThomasV <thomasv@electrum.org>
Date: Mon, 11 Jun 2018 12:18:37 +0200
Merge pull request #4422 from SomberNight/fix_4421
socket.getaddrinfo on win32: do our own dns resolution outside the lock
Diffstat:
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/lib/network.py b/lib/network.py
@@ -32,8 +32,12 @@ from collections import defaultdict
import threading
import socket
import json
+import sys
+import dns
+import dns.resolver
import socks
+
from . import util
from . import bitcoin
from .bitcoin import *
@@ -413,7 +417,23 @@ class Network(util.DaemonThread):
socket.getaddrinfo = lambda *args: [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0], args[1]))]
else:
socket.socket = socket._socketobject
- socket.getaddrinfo = socket._getaddrinfo
+ if sys.platform == 'win32':
+ # on Windows, socket.getaddrinfo takes a mutex, and might hold it for up to 10 seconds
+ # when dns-resolving. to speed it up drastically, we resolve dns ourselves, outside that lock
+ def fast_getaddrinfo(host, *args, **kwargs):
+ try:
+ if str(host) not in ('localhost', 'localhost.',):
+ answers = dns.resolver.query(host)
+ addr = str(answers[0])
+ else:
+ addr = host
+ except:
+ raise socket.gaierror(11001, 'getaddrinfo failed')
+ else:
+ return socket._getaddrinfo(addr, *args, **kwargs)
+ socket.getaddrinfo = fast_getaddrinfo
+ else:
+ socket.getaddrinfo = socket._getaddrinfo
def start_network(self, protocol, proxy):
assert not self.interface and not self.interfaces