diff --git a/src/network/addrthread.py b/src/network/addrthread.py index 8b46750f..fea0910e 100644 --- a/src/network/addrthread.py +++ b/src/network/addrthread.py @@ -3,12 +3,13 @@ Announce addresses as they are received from other hosts """ from six.moves import queue - +# magic imports! import state from helper_random import randomshuffle -from network.assemble import assemble_addr +from protocol import assembleAddrMessage +from queues import addrQueue # FIXME: init with queue from network.connectionpool import BMConnectionPool -from queues import addrQueue + from threads import StoppableThread @@ -41,7 +42,7 @@ class AddrThread(StoppableThread): continue filtered.append((stream, peer, seen)) if filtered: - i.append_write_buf(assemble_addr(filtered)) + i.append_write_buf(assembleAddrMessage(filtered)) addrQueue.iterate() for i in range(len(chunk)): diff --git a/src/network/announcethread.py b/src/network/announcethread.py index e34ed963..bbb56dd3 100644 --- a/src/network/announcethread.py +++ b/src/network/announcethread.py @@ -3,10 +3,12 @@ Announce myself (node address) """ import time +# magic imports! import state from bmconfigparser import BMConfigParser -from network.assemble import assemble_addr +from protocol import assembleAddrMessage from network.connectionpool import BMConnectionPool + from node import Peer from threads import StoppableThread @@ -40,4 +42,4 @@ class AnnounceThread(StoppableThread): BMConfigParser().safeGetInt( 'bitmessagesettings', 'port')), time.time()) - connection.append_write_buf(assemble_addr([addr])) + connection.append_write_buf(assembleAddrMessage([addr])) diff --git a/src/network/bmproto.py b/src/network/bmproto.py index 008eadb0..5b073869 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -25,7 +25,7 @@ from network.bmobject import ( BMObjectInvalidError, BMObjectUnwantedStreamError ) from network.constants import ( - ADDRESS_ALIVE, MAX_MESSAGE_SIZE, MAX_OBJECT_COUNT, + ADDRESS_ALIVE, MAX_MESSAGE_SIZE, MAX_OBJECT_PAYLOAD_SIZE, MAX_TIME_OFFSET ) from network.dandelion import Dandelion @@ -350,7 +350,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): """ items = self.decode_payload_content("l32s") - if len(items) > MAX_OBJECT_COUNT: + if len(items) > protocol.MAX_OBJECT_COUNT: logger.error( 'Too many items in %sinv message!', 'd' if dandelion else '') raise BMProtoExcessiveDataError() diff --git a/src/network/constants.py b/src/network/constants.py index f8f4120f..a4a2fcc5 100644 --- a/src/network/constants.py +++ b/src/network/constants.py @@ -5,8 +5,6 @@ Network protocol constants #: address is online if online less than this many seconds ago ADDRESS_ALIVE = 10800 -#: protocol specification says max 1000 addresses in one addr command -MAX_ADDR_COUNT = 1000 #: ~1.6 MB which is the maximum possible size of an inv message. MAX_MESSAGE_SIZE = 1600100 #: 2**18 = 256kB is the maximum size of an object payload diff --git a/src/network/tcp.py b/src/network/tcp.py index ff778378..33f8edbb 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -20,9 +20,7 @@ from bmconfigparser import BMConfigParser from helper_random import randomBytes from inventory import Inventory from network.advanceddispatcher import AdvancedDispatcher -from network.assemble import assemble_addr from network.bmproto import BMProto -from network.constants import MAX_OBJECT_COUNT from network.dandelion import Dandelion from network.objectracker import ObjectTracker from network.socks4a import Socks4aConnection @@ -205,7 +203,7 @@ class TCPConnection(BMProto, TLSDispatcher): for peer, params in addrs[substream]: templist.append((substream, peer, params["lastseen"])) if templist: - self.append_write_buf(assemble_addr(templist)) + self.append_write_buf(protocol.assembleAddrMessage(templist)) def sendBigInv(self): """ @@ -244,7 +242,7 @@ class TCPConnection(BMProto, TLSDispatcher): # Remove -1 below when sufficient time has passed for users to # upgrade to versions of PyBitmessage that accept inv with 50,000 # items - if objectCount >= MAX_OBJECT_COUNT - 1: + if objectCount >= protocol.MAX_OBJECT_COUNT - 1: sendChunk() payload = b'' objectCount = 0 diff --git a/src/protocol.py b/src/protocol.py index 1934d9cc..fc65a580 100644 --- a/src/protocol.py +++ b/src/protocol.py @@ -22,6 +22,7 @@ from bmconfigparser import BMConfigParser from debug import logger from fallback import RIPEMD160Hash from helper_sql import sqlExecute +from network.node import Peer from version import softwareVersion # Service flags @@ -55,6 +56,9 @@ OBJECT_ONIONPEER = 0x746f72 OBJECT_I2P = 0x493250 OBJECT_ADDR = 0x61646472 +#: protocol specification says max 1000 addresses in one addr command +MAX_ADDR_COUNT = 1000 + eightBytesOfRandomDataUsedToDetectConnectionsToSelf = pack( '>Q', random.randrange(1, 18446744073709551615)) @@ -295,6 +299,28 @@ def CreatePacket(command, payload=b''): return bytes(b) +def assembleAddrMessage(peerList): + """Create address command""" + if isinstance(peerList, Peer): + peerList = [peerList] + if not peerList: + return b'' + retval = b'' + for i in range(0, len(peerList), MAX_ADDR_COUNT): + payload = encodeVarint(len(peerList[i:i + MAX_ADDR_COUNT])) + for stream, peer, timestamp in peerList[i:i + MAX_ADDR_COUNT]: + # 64-bit time + payload += pack('>Q', timestamp) + payload += pack('>I', stream) + # service bit flags offered by this node + payload += pack('>q', 1) + payload += encodeHost(peer.host) + # remote port + payload += pack('>H', peer.port) + retval += CreatePacket('addr', payload) + return retval + + def assembleVersionMessage( remoteHost, remotePort, participatingStreams, server=False, nodeid=None ):