Universal bootstrap procedure for any connection type

This commit is contained in:
Dmitri Bogomolov 2019-07-20 11:41:49 +03:00
parent 0a06567071
commit 4825c5a136
Signed by untrusted user: g1itch
GPG Key ID: 720A756F18DEED13
2 changed files with 59 additions and 3 deletions

View File

@ -18,7 +18,8 @@ from debug import logger
from proxy import Proxy
from singleton import Singleton
from tcp import (
TCPServer, Socks5BMConnection, Socks4aBMConnection, TCPConnection)
bootstrap, Socks4aBMConnection, Socks5BMConnection,
TCPConnection, TCPServer)
from udp import UDPSocket
@ -159,6 +160,27 @@ class BMConnectionPool(object):
udpSocket = UDPSocket(host=bind, announcing=True)
self.udpSockets[udpSocket.listening.host] = udpSocket
def startBootstrappers(self):
"""Run the process of resolving bootstrap hostnames"""
proxy_type = BMConfigParser().safeGet(
'bitmessagesettings', 'socksproxytype')
# A plugins may be added here
if not proxy_type or proxy_type == 'none':
connection_base = TCPConnection
elif proxy_type == 'SOCKS5':
connection_base = Socks5BMConnection
elif proxy_type == 'SOCKS4a':
connection_base = Socks4aBMConnection # FIXME: I cannot test
else:
# This should never happen because socksproxytype setting
# is handled in bitmessagemain before starting the connectionpool
return
bootstrapper = bootstrap(connection_base)
port = helper_random.randomchoice([8080, 8444])
hostname = 'bootstrap%s.bitmessage.org' % port
self.addConnection(bootstrapper(hostname, port))
def loop(self): # pylint: disable=too-many-branches,too-many-statements
"""Main Connectionpool's loop"""
# defaults to empty loop if outbound connections are maxed
@ -184,7 +206,8 @@ class BMConnectionPool(object):
# pylint: disable=too-many-nested-blocks
if spawnConnections:
if not knownnodes.knownNodesActual:
knownnodes.dns()
self.startBootstrappers()
knownnodes.knownNodesActual = True
if not self.bootstrapped:
self.bootstrapped = True
Proxy.proxy = (

View File

@ -325,6 +325,39 @@ class Socks4aBMConnection(Socks4aConnection, TCPConnection):
return True
def bootstrap(connection_class):
"""Make bootstrapper class for connection type (connection_class)"""
class Bootstrapper(connection_class):
"""Base class for bootstrappers"""
_connection_base = connection_class
def __init__(self, host, port):
self._connection_base.__init__(self, state.Peer(host, port))
self.close_reason = self._succeed = False
def bm_command_addr(self):
"""
Got addr message - the bootstrap succeed.
Let BMProto process the addr message and switch state to 'close'
"""
BMProto.bm_command_addr(self)
self._succeed = True
# pylint: disable=attribute-defined-outside-init
self.close_reason = "Thanks for bootstrapping!"
self.set_state("close")
def handle_close(self):
"""
After closing the connection switch knownnodes.knownNodesActual
back to False if the bootstrapper failed.
"""
self._connection_base.handle_close(self)
if not self._succeed:
knownnodes.knownNodesActual = False
return Bootstrapper
class TCPServer(AdvancedDispatcher):
"""TCP connection server for Bitmessage protocol"""