Universal bootstrap procedure for any connection type

Dmitri Bogomolov 4 years ago
parent 0a06567071
commit 4825c5a136
Signed by untrusted user: g1itch
GPG Key ID: 720A756F18DEED13

@ -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,7 +160,28 @@ class BMConnectionPool(object):
udpSocket = UDPSocket(host=bind, announcing=True)
self.udpSockets[udpSocket.listening.host] = udpSocket
def loop(self): # pylint: disable=too-many-branches, too-many-statements
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
# This should never happen because socksproxytype setting
# is handled in bitmessagemain before starting the connectionpool
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
spawnConnections = False
@ -184,7 +206,8 @@ class BMConnectionPool(object):
# pylint: disable=too-many-nested-blocks
if spawnConnections:
if not knownnodes.knownNodesActual:
knownnodes.knownNodesActual = True
if not self.bootstrapped:
self.bootstrapped = True
Proxy.proxy = (

@ -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'
self._succeed = True
# pylint: disable=attribute-defined-outside-init
self.close_reason = "Thanks for bootstrapping!"
def handle_close(self):
After closing the connection switch knownnodes.knownNodesActual
back to False if the bootstrapper failed.
if not self._succeed:
knownnodes.knownNodesActual = False
return Bootstrapper
class TCPServer(AdvancedDispatcher):
"""TCP connection server for Bitmessage protocol"""