WIP: Handle all peers nonces, not only own #5

Draft
lee.miller wants to merge 4 commits from lee.miller/MiNode:network-nonce into v0.3
3 changed files with 27 additions and 4 deletions

View File

@ -4,6 +4,7 @@ import base64
import errno import errno
import logging import logging
import math import math
import os
import random import random
import select import select
import socket import socket
@ -80,7 +81,8 @@ class ConnectionBase(threading.Thread):
if self.network == 'ip': if self.network == 'ip':
self.send_queue.put(message.Version(self.host, self.port)) self.send_queue.put(message.Version(self.host, self.port))
else: else:
self.send_queue.put(message.Version('127.0.0.1', 7656)) self.send_queue.put(message.Version(
'127.0.0.1', 7656, nonce=self._get_nonce()))
while True: while True:
if ( if (
self.on_connection_fully_established_scheduled self.on_connection_fully_established_scheduled
@ -149,6 +151,14 @@ class ConnectionBase(threading.Thread):
break break
time.sleep(0.2) time.sleep(0.2)
def _get_nonce(self):
nonce = shared.nonce_pool.get(('127.0.0.1', 8448))
if nonce is None:
nonce = os.urandom(8)
shared.nonce_pool[('127.0.0.1', 8448)] = nonce
return nonce
def _connect(self): def _connect(self):
peer_str = '{0.host_print}:{0.port}'.format(self) peer_str = '{0.host_print}:{0.port}'.format(self)
logging.debug('Connecting to %s', peer_str) logging.debug('Connecting to %s', peer_str)
@ -377,16 +387,23 @@ class ConnectionBase(threading.Thread):
if shared.stream not in version.streams: if shared.stream not in version.streams:
raise ValueError('message not for stream %i' % shared.stream) raise ValueError('message not for stream %i' % shared.stream)
logging.debug('%s:%s -> %s', self.host_print, self.port, version) logging.debug('%s:%s -> %s', self.host_print, self.port, version)
nonce_print = base64.b16encode(version.nonce).decode()
if ( if (
version.protocol_version != shared.protocol_version version.protocol_version != shared.protocol_version
or version.nonce == shared.nonce or version.nonce == shared.nonce
or version.nonce in shared.nonce_pool.values()
): ):
logging.warning(
'Disconnecting v%s node %s with nonce %s',
version.protocol_version, self.host_print, nonce_print)
shared.unchecked_node_pool.discard((self.host, self.port))
self.status = 'disconnecting' self.status = 'disconnecting'
self.send_queue.put(None) self.send_queue.put(None)
else: else:
shared.nonce_pool[(self.host, self.port)] = version.nonce
logging.info( logging.info(
'%s:%s claims to be %s', '%s:%s claims to be %s (%s)',
self.host_print, self.port, version.user_agent) self.host_print, self.port, version.user_agent, nonce_print)
self.send_queue.put(message.Message(b'verack', b'')) self.send_queue.put(message.Message(b'verack', b''))
self.verack_sent = True self.verack_sent = True
self.remote_version = version self.remote_version = version
@ -405,7 +422,8 @@ class ConnectionBase(threading.Thread):
if self.network == 'ip': if self.network == 'ip':
self.send_queue.put(message.Version(self.host, self.port)) self.send_queue.put(message.Version(self.host, self.port))
else: else:
self.send_queue.put(message.Version('127.0.0.1', 7656)) self.send_queue.put(message.Version(
'127.0.0.1', 7656, nonce=self._get_nonce()))
def _process_msg_addr(self, m): def _process_msg_addr(self, m):
addr = message.Addr.from_message(m) addr = message.Addr.from_message(m)

View File

@ -76,6 +76,10 @@ class Manager(threading.Thread):
if not c.is_alive() or c.status == 'disconnected': if not c.is_alive() or c.status == 'disconnected':
with shared.connections_lock: with shared.connections_lock:
shared.connections.remove(c) shared.connections.remove(c)
try:
del shared.nonce_pool[(c.host, c.port)]
except KeyError:
pass
else: else:
hosts.add(structure.NetAddrNoPrefix.network_group(c.host)) hosts.add(structure.NetAddrNoPrefix.network_group(c.host))
if not c.server: if not c.server:

View File

@ -54,6 +54,7 @@ core_nodes = set()
node_pool = set() node_pool = set()
unchecked_node_pool = set() unchecked_node_pool = set()
nonce_pool = {}
i2p_core_nodes = set() i2p_core_nodes = set()
i2p_node_pool = set() i2p_node_pool = set()