From 3941b39136206a50c90fb1cad4d320bb5d70c676 Mon Sep 17 00:00:00 2001 From: Peter Surda Date: Mon, 10 Jul 2017 07:10:05 +0200 Subject: [PATCH] Randomise node id - in order to detect if it's connected to to itself, PyBitmessage now uses a per-connection id rather than a global one --- src/network/connectionpool.py | 9 +++++++++ src/network/tcp.py | 12 +++++++++--- src/protocol.py | 7 +++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/network/connectionpool.py b/src/network/connectionpool.py index ba5481da..be7b8ceb 100644 --- a/src/network/connectionpool.py +++ b/src/network/connectionpool.py @@ -65,6 +65,15 @@ class BMConnectionPool(object): return self.udpSockets[addr] raise KeyError + def isAlreadyConnected(self, nodeid): + for i in self.inboundConnections.values() + self.outboundConnections.values(): + try: + if nodeid == i.nodeid: + return True + except AttributeError: + pass + return False + def addConnection(self, connection): if isinstance(connection, network.udp.UDPSocket): return diff --git a/src/network/tcp.py b/src/network/tcp.py index 75ddea1c..01b19817 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -11,6 +11,7 @@ import traceback from addresses import calculateInventoryHash from debug import logger +from helper_random import randomBytes from inventory import Inventory import knownnodes from network.advanceddispatcher import AdvancedDispatcher @@ -47,6 +48,7 @@ class TCPConnection(BMProto, TLSDispatcher): TLSDispatcher.__init__(self, sock, server_side=True) self.connectedAt = time.time() logger.debug("Received connection from %s:%i", self.destination.host, self.destination.port) + self.nodeid = randomBytes(8) elif address is not None and sock is not None: TLSDispatcher.__init__(self, sock, server_side=False) self.isOutbound = True @@ -187,7 +189,9 @@ class TCPConnection(BMProto, TLSDispatcher): if e.errno in asyncore._DISCONNECTED: logger.debug("%s:%i: Connection failed: %s" % (self.destination.host, self.destination.port, str(e))) return - self.append_write_buf(protocol.assembleVersionMessage(self.destination.host, self.destination.port, network.connectionpool.BMConnectionPool().streams, False)) + self.nodeid = randomBytes(8) + self.append_write_buf(protocol.assembleVersionMessage(self.destination.host, self.destination.port, \ + network.connectionpool.BMConnectionPool().streams, False, nodeid=self.nodeid)) #print "%s:%i: Sending version" % (self.destination.host, self.destination.port) self.connectedAt = time.time() receiveDataQueue.put(self.destination) @@ -220,8 +224,9 @@ class Socks5BMConnection(Socks5Connection, TCPConnection): def state_proxy_handshake_done(self): Socks5Connection.state_proxy_handshake_done(self) + self.nodeid = randomBytes(8) self.append_write_buf(protocol.assembleVersionMessage(self.destination.host, self.destination.port, \ - network.connectionpool.BMConnectionPool().streams, False)) + network.connectionpool.BMConnectionPool().streams, False, nodeid=self.nodeid)) self.set_state("bm_header", expectBytes=protocol.Header.size) return True @@ -234,8 +239,9 @@ class Socks4aBMConnection(Socks4aConnection, TCPConnection): def state_proxy_handshake_done(self): Socks4aConnection.state_proxy_handshake_done(self) + self.nodeid = randomBytes(8) self.append_write_buf(protocol.assembleVersionMessage(self.destination.host, self.destination.port, \ - network.connectionpool.BMConnectionPool().streams, False)) + network.connectionpool.BMConnectionPool().streams, False, nodeid=self.nodeid)) self.set_state("bm_header", expectBytes=protocol.Header.size) return True diff --git a/src/protocol.py b/src/protocol.py index d7bd5b8c..c2a58de8 100644 --- a/src/protocol.py +++ b/src/protocol.py @@ -186,7 +186,7 @@ def CreatePacket(command, payload=''): b[Header.size:] = payload return bytes(b) -def assembleVersionMessage(remoteHost, remotePort, participatingStreams, server = False): +def assembleVersionMessage(remoteHost, remotePort, participatingStreams, server = False, nodeid = None): payload = '' payload += pack('>L', 3) # protocol version. payload += pack('>q', NODE_NETWORK|(NODE_SSL if haveSSL(server) else 0)) # bitflags of the services I offer. @@ -217,7 +217,10 @@ def assembleVersionMessage(remoteHost, remotePort, participatingStreams, server payload += pack('>H', BMConfigParser().getint('bitmessagesettings', 'port')) random.seed() - payload += eightBytesOfRandomDataUsedToDetectConnectionsToSelf + if nodeid is not None: + payload += nodeid[0:8] + else: + payload += eightBytesOfRandomDataUsedToDetectConnectionsToSelf userAgent = '/PyBitmessage:' + softwareVersion + '/' payload += encodeVarint(len(userAgent)) payload += userAgent