interface: call socket.connect before sll.wrap_socket, for proxy. (fixes bug #207)
This commit is contained in:
parent
80cd013219
commit
7658b2ade1
|
@ -99,7 +99,7 @@ class NetworkDialog(QDialog):
|
||||||
|
|
||||||
self.server_protocol.connect(self.server_protocol, SIGNAL('currentIndexChanged(int)'), self.change_protocol)
|
self.server_protocol.connect(self.server_protocol, SIGNAL('currentIndexChanged(int)'), self.change_protocol)
|
||||||
|
|
||||||
label = _('Active Servers') if interface.servers else _('Default Servers')
|
label = _('Active Servers') #if interface.servers else _('Default Servers')
|
||||||
self.servers_list_widget = QTreeWidget(parent)
|
self.servers_list_widget = QTreeWidget(parent)
|
||||||
self.servers_list_widget.setHeaderLabels( [ label, _('Limit') ] )
|
self.servers_list_widget.setHeaderLabels( [ label, _('Limit') ] )
|
||||||
self.servers_list_widget.setMaximumHeight(150)
|
self.servers_list_widget.setMaximumHeight(150)
|
||||||
|
|
140
lib/interface.py
140
lib/interface.py
|
@ -32,11 +32,23 @@ proxy_modes = ['socks4', 'socks5', 'http']
|
||||||
class Interface(threading.Thread):
|
class Interface(threading.Thread):
|
||||||
|
|
||||||
|
|
||||||
def init_server(self, host, port, proxy=None, use_ssl=True):
|
def __init__(self, config=None):
|
||||||
self.host = host
|
|
||||||
self.port = port
|
if config is None:
|
||||||
self.proxy = proxy
|
from simple_config import SimpleConfig
|
||||||
self.use_ssl = use_ssl
|
config = SimpleConfig()
|
||||||
|
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
self.daemon = True
|
||||||
|
self.config = config
|
||||||
|
self.connect_event = threading.Event()
|
||||||
|
|
||||||
|
self.subscriptions = {}
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
|
||||||
|
self.rtime = 0
|
||||||
|
self.bytes_received = 0
|
||||||
|
self.is_connected = False
|
||||||
self.poll_interval = 1
|
self.poll_interval = 1
|
||||||
|
|
||||||
#json
|
#json
|
||||||
|
@ -44,6 +56,21 @@ class Interface(threading.Thread):
|
||||||
self.unanswered_requests = {}
|
self.unanswered_requests = {}
|
||||||
self.pending_transactions_for_notifications= []
|
self.pending_transactions_for_notifications= []
|
||||||
|
|
||||||
|
# parse server
|
||||||
|
s = config.get('server')
|
||||||
|
host, port, protocol = s.split(':')
|
||||||
|
port = int(port)
|
||||||
|
if protocol not in 'ghst':
|
||||||
|
raise BaseException('Unknown protocol: %s'%protocol)
|
||||||
|
|
||||||
|
self.host = host
|
||||||
|
self.port = port
|
||||||
|
self.protocol = protocol
|
||||||
|
self.use_ssl = ( protocol in 'sg' )
|
||||||
|
self.proxy = self.parse_proxy_options(config.get('proxy'))
|
||||||
|
self.server = host + ':%d:%s'%(port, protocol)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def queue_json_response(self, c):
|
def queue_json_response(self, c):
|
||||||
|
|
||||||
|
@ -104,7 +131,6 @@ class Interface(threading.Thread):
|
||||||
|
|
||||||
|
|
||||||
def init_http(self, host, port, proxy=None, use_ssl=True):
|
def init_http(self, host, port, proxy=None, use_ssl=True):
|
||||||
self.init_server(host, port, proxy, use_ssl)
|
|
||||||
self.session_id = None
|
self.session_id = None
|
||||||
self.is_connected = True
|
self.is_connected = True
|
||||||
self.connection_msg = ('https' if self.use_ssl else 'http') + '://%s:%d'%( self.host, self.port )
|
self.connection_msg = ('https' if self.use_ssl else 'http') + '://%s:%d'%( self.host, self.port )
|
||||||
|
@ -209,28 +235,26 @@ class Interface(threading.Thread):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def init_tcp(self, host, port, proxy=None, use_ssl=True):
|
def start_tcp(self):
|
||||||
|
|
||||||
if self.use_ssl:
|
if self.use_ssl:
|
||||||
cert_path = os.path.join( self.config.get('path'), 'certs', host)
|
cert_path = os.path.join( self.config.get('path'), 'certs', self.host)
|
||||||
if not os.path.exists(cert_path):
|
if not os.path.exists(cert_path):
|
||||||
dir_path = os.path.join( self.config.get('path'), 'certs')
|
dir_path = os.path.join( self.config.get('path'), 'certs')
|
||||||
if not os.path.exists(dir_path):
|
if not os.path.exists(dir_path):
|
||||||
os.mkdir(dir_path)
|
os.mkdir(dir_path)
|
||||||
try:
|
try:
|
||||||
cert = ssl.get_server_certificate((host, port))
|
cert = ssl.get_server_certificate((self.host, self.port))
|
||||||
except:
|
except:
|
||||||
print_error("failed to connect", host, port)
|
print_error("failed to connect", self.host, self.port)
|
||||||
return
|
return
|
||||||
|
|
||||||
with open(cert_path,"w") as f:
|
with open(cert_path,"w") as f:
|
||||||
f.write(cert)
|
f.write(cert)
|
||||||
|
|
||||||
self.init_server(host, port, proxy, use_ssl)
|
|
||||||
|
|
||||||
global proxy_modes
|
|
||||||
self.connection_msg = "%s:%d"%(self.host, self.port)
|
self.connection_msg = "%s:%d"%(self.host, self.port)
|
||||||
|
|
||||||
|
|
||||||
if self.proxy is None:
|
if self.proxy is None:
|
||||||
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
||||||
else:
|
else:
|
||||||
|
@ -238,6 +262,14 @@ class Interface(threading.Thread):
|
||||||
s = socks.socksocket()
|
s = socks.socksocket()
|
||||||
s.setproxy(proxy_modes.index(self.proxy["mode"]) + 1, self.proxy["host"], int(self.proxy["port"]) )
|
s.setproxy(proxy_modes.index(self.proxy["mode"]) + 1, self.proxy["host"], int(self.proxy["port"]) )
|
||||||
|
|
||||||
|
s.settimeout(2)
|
||||||
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
s.connect(( self.host.encode('ascii'), int(self.port)))
|
||||||
|
except:
|
||||||
|
print_error("failed to connect", self.host, self.port)
|
||||||
|
return
|
||||||
|
|
||||||
if self.use_ssl:
|
if self.use_ssl:
|
||||||
try:
|
try:
|
||||||
|
@ -246,37 +278,28 @@ class Interface(threading.Thread):
|
||||||
cert_reqs=ssl.CERT_REQUIRED,
|
cert_reqs=ssl.CERT_REQUIRED,
|
||||||
ca_certs=cert_path,
|
ca_certs=cert_path,
|
||||||
do_handshake_on_connect=True)
|
do_handshake_on_connect=True)
|
||||||
except:
|
|
||||||
print_error("wrap_socket failed", host)
|
|
||||||
return
|
|
||||||
|
|
||||||
s.settimeout(2)
|
|
||||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
|
||||||
|
|
||||||
try:
|
|
||||||
s.connect(( self.host.encode('ascii'), int(self.port)))
|
|
||||||
except ssl.SSLError, e:
|
except ssl.SSLError, e:
|
||||||
print_error("SSL error:", host, e)
|
print_error("SSL error:", self.host, e)
|
||||||
return
|
return
|
||||||
except:
|
except:
|
||||||
#traceback.print_exc(file=sys.stdout)
|
traceback.print_exc(file=sys.stdout)
|
||||||
print_error("failed to connect", host, port)
|
print_error("wrap_socket failed", self.host)
|
||||||
return
|
return
|
||||||
|
|
||||||
# hostname verification (disabled)
|
# hostname verification (disabled)
|
||||||
if self.use_ssl and False:
|
if self.use_ssl and False:
|
||||||
from backports.ssl_match_hostname import match_hostname, CertificateError
|
from backports.ssl_match_hostname import match_hostname, CertificateError
|
||||||
try:
|
try:
|
||||||
match_hostname(s.getpeercert(), host)
|
match_hostname(s.getpeercert(), self.host)
|
||||||
print_error("hostname matches", host)
|
print_error("hostname matches", self.host)
|
||||||
except CertificateError, ce:
|
except CertificateError, ce:
|
||||||
print_error("hostname does not match", host, s.getpeercert())
|
print_error("hostname does not match", self.host, s.getpeercert())
|
||||||
return
|
return
|
||||||
|
|
||||||
s.settimeout(60)
|
s.settimeout(60)
|
||||||
self.s = s
|
self.s = s
|
||||||
self.is_connected = True
|
self.is_connected = True
|
||||||
print_error("connected to", host, port)
|
print_error("connected to", self.host, self.port)
|
||||||
|
|
||||||
|
|
||||||
def run_tcp(self):
|
def run_tcp(self):
|
||||||
|
@ -355,65 +378,18 @@ class Interface(threading.Thread):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, config=None):
|
|
||||||
#self.server = random.choice(filter_protocol(DEFAULT_SERVERS, 's'))
|
|
||||||
self.proxy = None
|
|
||||||
|
|
||||||
if config is None:
|
|
||||||
from simple_config import SimpleConfig
|
|
||||||
config = SimpleConfig()
|
|
||||||
|
|
||||||
threading.Thread.__init__(self)
|
|
||||||
self.daemon = True
|
|
||||||
self.config = config
|
|
||||||
self.connect_event = threading.Event()
|
|
||||||
|
|
||||||
self.subscriptions = {}
|
|
||||||
self.lock = threading.Lock()
|
|
||||||
|
|
||||||
self.servers = {} # actual list from IRC
|
|
||||||
self.rtime = 0
|
|
||||||
self.bytes_received = 0
|
|
||||||
self.is_connected = False
|
|
||||||
|
|
||||||
# init with None server, in case we are offline
|
|
||||||
self.init_server(None, None)
|
|
||||||
|
|
||||||
|
|
||||||
|
def start_interface(self):
|
||||||
|
|
||||||
|
if self.protocol in 'st':
|
||||||
def init_interface(self):
|
self.start_tcp()
|
||||||
if self.config.get('server'):
|
elif self.protocol in 'gh':
|
||||||
self.init_with_server(self.config)
|
self.start_http()
|
||||||
else:
|
|
||||||
if self.config.get('auto_cycle') is None:
|
|
||||||
self.config.set_key('auto_cycle', True, False)
|
|
||||||
|
|
||||||
if not self.is_connected:
|
|
||||||
self.connect_event.set()
|
|
||||||
return
|
|
||||||
|
|
||||||
self.connect_event.set()
|
self.connect_event.set()
|
||||||
|
|
||||||
|
|
||||||
def init_with_server(self, config):
|
|
||||||
|
|
||||||
s = config.get('server')
|
|
||||||
host, port, protocol = s.split(':')
|
|
||||||
port = int(port)
|
|
||||||
|
|
||||||
self.protocol = protocol
|
|
||||||
proxy = self.parse_proxy_options(config.get('proxy'))
|
|
||||||
self.server = host + ':%d:%s'%(port, protocol)
|
|
||||||
|
|
||||||
#print protocol, host, port
|
|
||||||
if protocol in 'st':
|
|
||||||
self.init_tcp(host, port, proxy, use_ssl=(protocol=='s'))
|
|
||||||
elif protocol in 'gh':
|
|
||||||
self.init_http(host, port, proxy, use_ssl=(protocol=='g'))
|
|
||||||
else:
|
|
||||||
raise BaseException('Unknown protocol: %s'%protocol)
|
|
||||||
|
|
||||||
|
|
||||||
def stop_subscriptions(self):
|
def stop_subscriptions(self):
|
||||||
for callback in self.subscriptions.keys():
|
for callback in self.subscriptions.keys():
|
||||||
|
@ -505,7 +481,7 @@ class Interface(threading.Thread):
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.init_interface()
|
self.start_interface()
|
||||||
if self.is_connected:
|
if self.is_connected:
|
||||||
self.send([('server.version', [ELECTRUM_VERSION, PROTOCOL_VERSION])], self.on_version)
|
self.send([('server.version', [ELECTRUM_VERSION, PROTOCOL_VERSION])], self.on_version)
|
||||||
self.change_status()
|
self.change_status()
|
||||||
|
|
|
@ -53,6 +53,7 @@ class Network(threading.Thread):
|
||||||
self.servers = []
|
self.servers = []
|
||||||
self.banner = ''
|
self.banner = ''
|
||||||
self.interface = None
|
self.interface = None
|
||||||
|
self.proxy = self.config.get('proxy')
|
||||||
self.heights = {}
|
self.heights = {}
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ class Network(threading.Thread):
|
||||||
def start_interface(self, server):
|
def start_interface(self, server):
|
||||||
if server in self.interfaces.keys():
|
if server in self.interfaces.keys():
|
||||||
return
|
return
|
||||||
i = interface.Interface({'server':server, 'path':self.config.path})
|
i = interface.Interface({'server':server, 'path':self.config.path, 'proxy':self.proxy})
|
||||||
self.interfaces[server] = i
|
self.interfaces[server] = i
|
||||||
i.start(self.queue)
|
i.start(self.queue)
|
||||||
|
|
||||||
|
@ -130,6 +131,7 @@ class Network(threading.Thread):
|
||||||
|
|
||||||
i = self.interface
|
i = self.interface
|
||||||
self.default_server = server
|
self.default_server = server
|
||||||
|
self.proxy = proxy
|
||||||
self.start_interface(server)
|
self.start_interface(server)
|
||||||
self.interface = self.interfaces[server]
|
self.interface = self.interfaces[server]
|
||||||
i.stop_subscriptions() # fixme: it should not stop all subscriptions, and send 'unsubscribe'
|
i.stop_subscriptions() # fixme: it should not stop all subscriptions, and send 'unsubscribe'
|
||||||
|
|
Loading…
Reference in New Issue