diff --git a/src/knownnodes.py b/src/knownnodes.py index f4e00b90..6d4629a2 100644 --- a/src/knownnodes.py +++ b/src/knownnodes.py @@ -11,7 +11,6 @@ import time import state from bmconfigparser import BMConfigParser from debug import logger -from helper_bootstrap import dns knownNodesLock = threading.Lock() knownNodes = {stream: {} for stream in range(1, 4)} @@ -123,6 +122,8 @@ def readKnownNodes(): logger.debug( 'Failed to read nodes from knownnodes.dat', exc_info=True) createDefaultKnownNodes() + if BMConfigParser().get('bitmessagesettings', 'socksproxytype') == 'SOCKS5': + createDefaultKnownNodes(onion=True) config = BMConfigParser() @@ -177,6 +178,13 @@ def trimKnownNodes(recAddrStream=1): del knownNodes[recAddrStream][oldest] +def dns(): + """Add DNS names to knownnodes""" + for port in [8080, 8444]: + addKnownNode( + 1, state.Peer('bootstrap%s.bitmessage.org' % port, port)) + + def cleanupKnownNodes(): """ Cleanup knownnodes: remove old nodes and nodes with low rating diff --git a/src/network/connectionchooser.py b/src/network/connectionchooser.py index e116ec53..4b1565a2 100644 --- a/src/network/connectionchooser.py +++ b/src/network/connectionchooser.py @@ -46,7 +46,8 @@ def chooseConnection(stream): # onion addresses have a higher priority when SOCKS if peer.host.endswith('.onion') and rating > 0: rating = 1 - else: + # TODO: need better check + elif not peer.host.startswith('bootstrap'): encodedAddr = protocol.encodeHost(peer.host) # don't connect to local IPs when using SOCKS if not protocol.checkIPAddress(encodedAddr, False): diff --git a/src/network/connectionpool.py b/src/network/connectionpool.py index 461c2b77..05358c28 100644 --- a/src/network/connectionpool.py +++ b/src/network/connectionpool.py @@ -8,7 +8,6 @@ import socket import time import asyncore_pollchoose as asyncore -import helper_bootstrap import helper_random import knownnodes import protocol @@ -185,7 +184,7 @@ class BMConnectionPool(object): # pylint: disable=too-many-nested-blocks if spawnConnections: if not knownnodes.knownNodesActual: - helper_bootstrap.dns() + knownnodes.dns() if not self.bootstrapped: self.bootstrapped = True Proxy.proxy = ( diff --git a/src/network/socks5.py b/src/network/socks5.py index 86616f30..e0cb7202 100644 --- a/src/network/socks5.py +++ b/src/network/socks5.py @@ -8,6 +8,7 @@ src/network/socks5.py import socket import struct +import state from proxy import GeneralProxyError, Proxy, ProxyError @@ -160,9 +161,6 @@ class Socks5(Proxy): class Socks5Connection(Socks5): """Child socks5 class used for making outbound connections.""" - def __init__(self, address): - Socks5.__init__(self, address=address) - def state_auth_done(self): """Request connection to be made""" # Now we can request the actual connection @@ -172,9 +170,9 @@ class Socks5Connection(Socks5): try: self.ipaddr = socket.inet_aton(self.destination[0]) self.append_write_buf(chr(0x01).encode() + self.ipaddr) - except socket.error: + except socket.error: # may be IPv6! # Well it's not an IP number, so it's probably a DNS name. - if Proxy._remote_dns: # pylint: disable=protected-access + if self._remote_dns: # Resolve remotely self.ipaddr = None self.append_write_buf(chr(0x03).encode() + chr( @@ -202,7 +200,7 @@ class Socks5Resolver(Socks5): def __init__(self, host): self.host = host self.port = 8444 - Socks5.__init__(self, address=(self.host, self.port)) + Socks5.__init__(self, address=state.Peer(self.host, self.port)) def state_auth_done(self): """Perform resolving""" diff --git a/src/network/tcp.py b/src/network/tcp.py index 5ebd6a21..9b92cb52 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -73,11 +73,14 @@ class TCPConnection(BMProto, TLSDispatcher): logger.debug( 'Connecting to %s:%i', self.destination.host, self.destination.port) - encodedAddr = protocol.encodeHost(self.destination.host) - self.local = all([ - protocol.checkIPAddress(encodedAddr, True), - not protocol.checkSocksIP(self.destination.host) - ]) + try: + self.local = ( + protocol.checkIPAddress( + protocol.encodeHost(self.destination.host), True) and + not protocol.checkSocksIP(self.destination.host) + ) + except socket.error: + pass # it's probably a hostname ObjectTracker.__init__(self) # pylint: disable=non-parent-init-called self.bm_proto_reset() self.set_state("bm_header", expectBytes=protocol.Header.size) diff --git a/src/protocol.py b/src/protocol.py index ab81e5e5..1031b950 100644 --- a/src/protocol.py +++ b/src/protocol.py @@ -264,7 +264,10 @@ def assembleVersionMessage(remoteHost, remotePort, participatingStreams, server= else: # use first 16 bytes if host data is longer # for example in case of onion v3 service - payload += encodeHost(remoteHost)[:16] + try: + payload += encodeHost(remoteHost)[:16] + except socket.error: + payload += encodeHost('127.0.0.1') payload += pack('>H', remotePort) # remote IPv6 and port # bitflags of the services I offer.