Move all the network constants into the protocol, define also magic.

Closes: #1788.
This commit is contained in:
Lee Miller 2023-01-04 02:05:22 +02:00
parent b99670430f
commit 0c07bb6257
Signed by untrusted user: lee.miller
GPG Key ID: 4F97A5EA88F4AB63
8 changed files with 30 additions and 39 deletions

View File

@ -1033,7 +1033,7 @@ class objectProcessor(threading.Thread):
magic, command, payloadLength, checksum = protocol.Header.unpack( magic, command, payloadLength, checksum = protocol.Header.unpack(
ackData[:protocol.Header.size]) ackData[:protocol.Header.size])
if magic != 0xE9BEB4D9: if magic != protocol.magic:
logger.info('Ackdata magic bytes were wrong. Not sending ackData.') logger.info('Ackdata magic bytes were wrong. Not sending ackData.')
return False return False
payload = ackData[protocol.Header.size:] payload = ackData[protocol.Header.size:]

View File

@ -30,10 +30,6 @@ from network.bmobject import (
from network.dandelion import Dandelion from network.dandelion import Dandelion
from network.proxy import ProxyError from network.proxy import ProxyError
from constants import (
ADDRESS_ALIVE, MAX_MESSAGE_SIZE, MAX_OBJECT_COUNT,
MAX_OBJECT_PAYLOAD_SIZE, MAX_TIME_OFFSET
)
from node import Node, Peer from node import Node, Peer
from objectracker import ObjectTracker, missingObjects from objectracker import ObjectTracker, missingObjects
@ -90,7 +86,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
self.magic, self.command, self.payloadLength, self.checksum = \ self.magic, self.command, self.payloadLength, self.checksum = \
protocol.Header.unpack(self.read_buf[:protocol.Header.size]) protocol.Header.unpack(self.read_buf[:protocol.Header.size])
self.command = self.command.rstrip('\x00') self.command = self.command.rstrip('\x00')
if self.magic != 0xE9BEB4D9: if self.magic != protocol.magic:
# skip 1 byte in order to sync # skip 1 byte in order to sync
self.set_state("bm_header", length=1) self.set_state("bm_header", length=1)
self.bm_proto_reset() self.bm_proto_reset()
@ -99,7 +95,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
self.close_reason = "Bad magic" self.close_reason = "Bad magic"
self.set_state("close") self.set_state("close")
return False return False
if self.payloadLength > MAX_MESSAGE_SIZE: if self.payloadLength > protocol.MAX_MESSAGE_SIZE:
self.invalid = True self.invalid = True
self.set_state( self.set_state(
"bm_command", "bm_command",
@ -351,7 +347,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
""" """
items = self.decode_payload_content("l32s") items = self.decode_payload_content("l32s")
if len(items) > MAX_OBJECT_COUNT: if len(items) > protocol.MAX_OBJECT_COUNT:
logger.error( logger.error(
'Too many items in %sinv message!', 'd' if dandelion else '') 'Too many items in %sinv message!', 'd' if dandelion else '')
raise BMProtoExcessiveDataError() raise BMProtoExcessiveDataError()
@ -387,7 +383,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
self.payload, self.payloadOffset) self.payload, self.payloadOffset)
payload_len = len(self.payload) - self.payloadOffset payload_len = len(self.payload) - self.payloadOffset
if payload_len > MAX_OBJECT_PAYLOAD_SIZE: if payload_len > protocol.MAX_OBJECT_PAYLOAD_SIZE:
logger.info( logger.info(
'The payload length of this object is too large' 'The payload length of this object is too large'
' (%d bytes). Ignoring it.', payload_len) ' (%d bytes). Ignoring it.', payload_len)
@ -460,7 +456,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
decodedIP = protocol.checkIPAddress(ip) decodedIP = protocol.checkIPAddress(ip)
if ( if (
decodedIP and time.time() - seenTime > 0 decodedIP and time.time() - seenTime > 0
and seenTime > time.time() - ADDRESS_ALIVE and seenTime > time.time() - protocol.ADDRESS_ALIVE
and port > 0 and port > 0
): ):
peer = Peer(decodedIP, port) peer = Peer(decodedIP, port)
@ -573,7 +569,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
'Closing connection to old protocol version %s, node: %s', 'Closing connection to old protocol version %s, node: %s',
self.remoteProtocolVersion, self.destination) self.remoteProtocolVersion, self.destination)
return False return False
if self.timeOffset > MAX_TIME_OFFSET: if self.timeOffset > protocol.MAX_TIME_OFFSET:
self.append_write_buf(protocol.assembleErrorMessage( self.append_write_buf(protocol.assembleErrorMessage(
errorText="Your time is too far in the future" errorText="Your time is too far in the future"
" compared to mine. Closing connection.", fatal=2)) " compared to mine. Closing connection.", fatal=2))
@ -583,7 +579,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
self.destination, self.timeOffset) self.destination, self.timeOffset)
BMProto.timeOffsetWrongCount += 1 BMProto.timeOffsetWrongCount += 1
return False return False
elif self.timeOffset < -MAX_TIME_OFFSET: elif self.timeOffset < -protocol.MAX_TIME_OFFSET:
self.append_write_buf(protocol.assembleErrorMessage( self.append_write_buf(protocol.assembleErrorMessage(
errorText="Your time is too far in the past compared to mine." errorText="Your time is too far in the past compared to mine."
" Closing connection.", fatal=2)) " Closing connection.", fatal=2))

View File

@ -1,15 +0,0 @@
"""
Network protocol constants
"""
#: address is online if online less than this many seconds ago
ADDRESS_ALIVE = 10800
#: ~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
MAX_OBJECT_PAYLOAD_SIZE = 2**18
#: protocol specification says max 50000 objects in one inv command
MAX_OBJECT_COUNT = 50000
#: maximum time offset
MAX_TIME_OFFSET = 3600

View File

@ -24,7 +24,6 @@ from tr import _translate
import asyncore_pollchoose as asyncore import asyncore_pollchoose as asyncore
import connectionpool import connectionpool
import knownnodes import knownnodes
from constants import MAX_OBJECT_COUNT
from network.advanceddispatcher import AdvancedDispatcher from network.advanceddispatcher import AdvancedDispatcher
from network.bmproto import BMProto from network.bmproto import BMProto
from network.dandelion import Dandelion from network.dandelion import Dandelion
@ -247,7 +246,7 @@ class TCPConnection(BMProto, TLSDispatcher):
# Remove -1 below when sufficient time has passed for users to # Remove -1 below when sufficient time has passed for users to
# upgrade to versions of PyBitmessage that accept inv with 50,000 # upgrade to versions of PyBitmessage that accept inv with 50,000
# items # items
if objectCount >= MAX_OBJECT_COUNT - 1: if objectCount >= protocol.MAX_OBJECT_COUNT - 1:
sendChunk() sendChunk()
payload = b'' payload = b''
objectCount = 0 objectCount = 0

View File

@ -5,13 +5,15 @@ import logging
import socket import socket
import time import time
# magic imports!
import protocol import protocol
import state import state
from queues import receiveDataQueue
from bmproto import BMProto from bmproto import BMProto
from constants import MAX_TIME_OFFSET
from node import Peer from node import Peer
from objectracker import ObjectTracker from objectracker import ObjectTracker
from queues import receiveDataQueue
logger = logging.getLogger('default') logger = logging.getLogger('default')
@ -81,8 +83,8 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
decodedIP = protocol.checkIPAddress(str(ip)) decodedIP = protocol.checkIPAddress(str(ip))
if stream not in state.streamsInWhichIAmParticipating: if stream not in state.streamsInWhichIAmParticipating:
continue continue
if (seenTime < time.time() - MAX_TIME_OFFSET if (seenTime < time.time() - protocol.MAX_TIME_OFFSET
or seenTime > time.time() + MAX_TIME_OFFSET): or seenTime > time.time() + protocol.MAX_TIME_OFFSET):
continue continue
if decodedIP is False: if decodedIP is False:
# if the address isn't local, interpret it as # if the address isn't local, interpret it as

View File

@ -25,9 +25,20 @@ from helper_sql import sqlExecute
from network.node import Peer from network.node import Peer
from version import softwareVersion from version import softwareVersion
# Network constants
magic = 0xE9BEB4D9
#: protocol specification says max 1000 addresses in one addr command #: protocol specification says max 1000 addresses in one addr command
MAX_ADDR_COUNT = 1000 MAX_ADDR_COUNT = 1000
#: address is online if online less than this many seconds ago
ADDRESS_ALIVE = 10800
#: ~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
MAX_OBJECT_PAYLOAD_SIZE = 2**18
#: protocol specification says max 50000 objects in one inv command
MAX_OBJECT_COUNT = 50000
#: maximum time offset
MAX_TIME_OFFSET = 3600
# Service flags # Service flags
#: This is a normal network node #: This is a normal network node
@ -300,7 +311,7 @@ def CreatePacket(command, payload=b''):
checksum = hashlib.sha512(payload).digest()[0:4] checksum = hashlib.sha512(payload).digest()[0:4]
b = bytearray(Header.size + payload_length) b = bytearray(Header.size + payload_length)
Header.pack_into(b, 0, 0xE9BEB4D9, command, payload_length, checksum) Header.pack_into(b, 0, magic, command, payload_length, checksum)
b[Header.size:] = payload b[Header.size:] = payload
return bytes(b) return bytes(b)

View File

@ -3,8 +3,6 @@
from binascii import unhexlify from binascii import unhexlify
magic = 0xE9BEB4D9
# 500 identical peers: # 500 identical peers:
# 1626611891, 1, 1, 127.0.0.1, 8444 # 1626611891, 1, 1, 127.0.0.1, 8444
sample_addr_data = unhexlify( sample_addr_data = unhexlify(

View File

@ -5,7 +5,7 @@ from struct import pack
from pybitmessage import addresses, protocol from pybitmessage import addresses, protocol
from .samples import magic, sample_addr_data from .samples import sample_addr_data
from .test_protocol import TestSocketInet from .test_protocol import TestSocketInet
@ -45,7 +45,7 @@ class TestSerialize(TestSocketInet):
def test_packet(self): def test_packet(self):
"""Check the packet created by protocol.CreatePacket()""" """Check the packet created by protocol.CreatePacket()"""
head = unhexlify(b'%x' % magic) head = unhexlify(b'%x' % protocol.magic)
self.assertEqual( self.assertEqual(
protocol.CreatePacket(b'ping')[:len(head)], head) protocol.CreatePacket(b'ping')[:len(head)], head)