def handle_read(self): try: (recdata, addr) = self.socket.recvfrom(self._buf_len) except socket.error as e: logger.error("socket error: %s", e) return self.destination = Peer(*addr) encodedAddr = protocol.encodeHost(addr[0]) self.local = bool(protocol.checkIPAddress(encodedAddr, True)) # overwrite the old buffer to avoid mixing data and so that # self.local works correctly self.read_buf[0:] = recdata self.bm_proto_reset() receiveDataQueue.put(self.listening)
def chooseConnection(stream): """Returns an appropriate connection""" haveOnion = BMConfigParser().safeGet("bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS' onionOnly = BMConfigParser().safeGetBoolean("bitmessagesettings", "onionservicesonly") try: retval = portCheckerQueue.get(False) portCheckerQueue.task_done() return retval except Queue.Empty: pass # with a probability of 0.5, connect to a discovered peer if random.choice((False, True)) and not haveOnion: # discovered peers are already filtered by allowed streams return getDiscoveredPeer() for _ in range(50): peer = random.choice(knownnodes.knownNodes[stream].keys()) try: peer_info = knownnodes.knownNodes[stream][peer] if peer_info.get('self'): continue rating = peer_info["rating"] except TypeError: logger.warning('Error in %s', peer) rating = 0 if haveOnion: # do not connect to raw IP addresses # --keep all traffic within Tor overlay if onionOnly and not peer.host.endswith('.onion'): continue # onion addresses have a higher priority when SOCKS if peer.host.endswith('.onion') and rating > 0: rating = 1 # 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): continue if rating > 1: rating = 1 try: if 0.05 / (1.0 - rating) > random.random(): return peer except ZeroDivisionError: return peer raise ValueError
def __init__(self, address=None, sock=None): BMProto.__init__(self, address=address, sock=sock) self.verackReceived = False self.verackSent = False self.streams = [0] self.fullyEstablished = False self.connectedAt = 0 self.skipUntil = 0 if address is None and sock is not None: self.destination = Peer(*sock.getpeername()) self.isOutbound = False 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 logger.debug( 'Outbound proxy connection to %s:%i', self.destination.host, self.destination.port) else: self.destination = address self.isOutbound = True self.create_socket( socket.AF_INET6 if ":" in address.host else socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) TLSDispatcher.__init__(self, sock, server_side=False) self.connect(self.destination) logger.debug( 'Connecting to %s:%i', self.destination.host, self.destination.port) try: self.local = ( protocol.checkIPAddress( protocol.encodeHost(self.destination.host), True) and not protocol.checkSocksIP(self.destination.host) ) except socket.error: # it's probably a hostname pass self.network_group = protocol.network_group(self.destination.host) ObjectTracker.__init__(self) # pylint: disable=non-parent-init-called self.bm_proto_reset() self.set_state("bm_header", expectBytes=protocol.Header.size)
def handle_read(self): try: (recdata, addr) = self.socket.recvfrom(AdvancedDispatcher._buf_len) except socket.error as e: logger.error("socket error: %s", str(e)) return self.destination = state.Peer(addr[0], addr[1]) encodedAddr = protocol.encodeHost(addr[0]) # if protocol.checkIPAddress(encodedAddr, True): # self.local = True # else: # self.local = False # overwrite the old buffer to avoid mixing data and so that self.local works correctly self.read_buf[0:] = recdata self.bm_proto_reset() receiveDataQueue.put(self.listening)
def __init__(self, address=None, sock=None): BMProto.__init__(self, address=address, sock=sock) self.verackReceived = False self.verackSent = False self.streams = [0] self.fullyEstablished = False self.connectedAt = 0 self.skipUntil = 0 if address is None and sock is not None: self.destination = state.Peer(sock.getpeername()[0], sock.getpeername()[1]) self.isOutbound = False 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 logger.debug("Outbound proxy connection to %s:%i", self.destination.host, self.destination.port) else: self.destination = address self.isOutbound = True if ":" in address.host: self.create_socket(socket.AF_INET6, socket.SOCK_STREAM) else: self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) TLSDispatcher.__init__(self, sock, server_side=False) self.connect(self.destination) logger.debug("Connecting to %s:%i", self.destination.host, self.destination.port) encodedAddr = protocol.encodeHost(self.destination.host) if protocol.checkIPAddress( encodedAddr, True) and not protocol.checkSocksIP(self.destination.host): self.local = True else: self.local = False #shared.connectedHostsList[self.destination] = 0 ObjectTracker.__init__(self) UISignalQueue.put(('updateNetworkStatusTab', 'no data')) self.bm_proto_reset() self.set_state("bm_header", expectBytes=protocol.Header.size)
def handle_read(self): try: (recdata, addr) = self.socket.recvfrom(AdvancedDispatcher._buf_len) except socket.error as e: logger.error("socket error: %s", str(e)) return self.destination = state.Peer(addr[0], addr[1]) encodedAddr = protocol.encodeHost(addr[0]) if protocol.checkIPAddress(encodedAddr, True): self.local = True else: self.local = False # overwrite the old buffer to avoid mixing data and so that self.local works correctly self.read_buf[0:] = recdata self.bm_proto_reset() receiveDataQueue.put(self.listening)
def assembleAddr(peerList): if isinstance(peerList, state.Peer): peerList = (peerList) if not peerList: return b'' retval = b'' for i in range(0, len(peerList), BMProto.maxAddrCount): payload = addresses.encodeVarint(len(peerList[i:i + BMProto.maxAddrCount])) for address in peerList[i:i + BMProto.maxAddrCount]: stream, peer, timestamp = address payload += struct.pack( '>Q', timestamp) # 64-bit time payload += struct.pack('>I', stream) payload += struct.pack( '>q', 1) # service bit flags offered by this node payload += protocol.encodeHost(peer.host) payload += struct.pack('>H', peer.port) # remote port retval += protocol.CreatePacket('addr', payload) return retval
def assembleAddr(peerList): if isinstance(peerList, state.Peer): peerList = (peerList) if not peerList: return b'' retval = b'' for i in range(0, len(peerList), BMProto.maxAddrCount): payload = addresses.encodeVarint(len(peerList[i:i + BMProto.maxAddrCount])) for address in peerList[i:i + BMProto.maxAddrCount]: stream, peer, timestamp = address payload += struct.pack( '>Q', timestamp) # 64-bit time payload += struct.pack('>I', stream) payload += struct.pack( '>q', 1) # service bit flags offered by this node payload += protocol.encodeHost(peer.host) payload += struct.pack('>H', peer.port) # remote port retval += protocol.CreatePacket('addr', payload) return retval
def assemble_addr(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 = addresses.encodeVarint(len(peerList[i:i + MAX_ADDR_COUNT])) for stream, peer, timestamp in peerList[i:i + MAX_ADDR_COUNT]: # 64-bit time payload += struct.pack('>Q', timestamp) payload += struct.pack('>I', stream) # service bit flags offered by this node payload += struct.pack('>q', 1) payload += encodeHost(peer.host) # remote port payload += struct.pack('>H', peer.port) retval += CreatePacket('addr', payload) return retval
def chooseConnection(stream): haveOnion = BMConfigParser().safeGet("lmessagesettings", "socksproxytype")[0:5] == 'SOCKS' if state.trustedPeer: return state.trustedPeer try: retval = portCheckerQueue.get(False) portCheckerQueue.task_done() return retval except Queue.Empty: pass # with a probability of 0.5, connect to a discovered peer if helper_random.randomchoice((False, True)) and not haveOnion: # discovered peers are already filtered by allowed streams return getDiscoveredPeer() for _ in range(50): peer = helper_random.randomchoice(knownnodes.knownNodes[stream].keys()) try: rating = knownnodes.knownNodes[stream][peer]["rating"] except TypeError: print "Error in %s" % (peer) rating = 0 if haveOnion: # onion addresses have a higher priority when SOCKS if peer.host.endswith('.onion') and rating > 0: rating = 1 else: encodedAddr = protocol.encodeHost(peer.host) # don't connect to local IPs when using SOCKS if not protocol.checkIPAddress(encodedAddr, False): continue if rating > 1: rating = 1 try: if 0.05 / (1.0 - rating) > random.random(): return peer except ZeroDivisionError: return peer raise ValueError
def __init__(self, address=None, sock=None): BMProto.__init__(self, address=address, sock=sock) self.verackReceived = False self.verackSent = False self.streams = [0] self.fullyEstablished = False self.connectedAt = 0 self.skipUntil = 0 if address is None and sock is not None: self.destination = state.Peer(sock.getpeername()[0], sock.getpeername()[1]) self.isOutbound = False 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 logger.debug("Outbound proxy connection to %s:%i", self.destination.host, self.destination.port) else: self.destination = address self.isOutbound = True if ":" in address.host: self.create_socket(socket.AF_INET6, socket.SOCK_STREAM) else: self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) TLSDispatcher.__init__(self, sock, server_side=False) self.connect(self.destination) logger.debug("Connecting to %s:%i", self.destination.host, self.destination.port) encodedAddr = protocol.encodeHost(self.destination.host) if protocol.checkIPAddress(encodedAddr, True) and not protocol.checkSocksIP(self.destination.host): self.local = True else: self.local = False #shared.connectedHostsList[self.destination] = 0 ObjectTracker.__init__(self) self.bm_proto_reset() self.set_state("bm_header", expectBytes=protocol.Header.size)
def chooseConnection(stream): haveOnion = BMConfigParser().safeGet("bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS' if state.trustedPeer: return state.trustedPeer try: retval = portCheckerQueue.get(False) portCheckerQueue.task_done() return retval except Queue.Empty: pass # with a probability of 0.5, connect to a discovered peer if random.choice((False, True)) and not haveOnion: # discovered peers are already filtered by allowed streams return getDiscoveredPeer() for _ in range(50): peer = random.choice(knownnodes.knownNodes[stream].keys()) try: rating = knownnodes.knownNodes[stream][peer]["rating"] except TypeError: print "Error in %s" % (peer) rating = 0 if haveOnion: # onion addresses have a higher priority when SOCKS if peer.host.endswith('.onion') and rating > 0: rating = 1 else: encodedAddr = protocol.encodeHost(peer.host) # don't connect to local IPs when using SOCKS if not protocol.checkIPAddress(encodedAddr, False): continue if rating > 1: rating = 1 try: if 0.05/(1.0-rating) > random.random(): return peer except ZeroDivisionError: return peer raise ValueError
def run(self): logger.debug('sendDataThread starting. ID: ' + str(id(self)) + '. Number of queues in sendDataQueues: ' + str(len(state.sendDataQueues))) while self.sendBytes(): deststream, command, data = self.sendDataThreadQueue.get() if deststream == 0 or deststream in self.streamNumber: if command == 'shutdown': logger.debug('sendDataThread (associated with ' + str(self.peer) + ') ID: ' + str(id(self)) + ' shutting down now.') break # When you receive an incoming connection, a sendDataThread is # created even though you don't yet know what stream number the # remote peer is interested in. They will tell you in a version # message and if you too are interested in that stream then you # will continue on with the connection and will set the # streamNumber of this send data thread here: elif command == 'setStreamNumber': self.streamNumber = data logger.debug('setting the stream number to %s', ', '.join(str(x) for x in self.streamNumber)) elif command == 'setRemoteProtocolVersion': specifiedRemoteProtocolVersion = data logger.debug( 'setting the remote node\'s protocol version in the sendDataThread (ID: ' + str(id(self)) + ') to ' + str(specifiedRemoteProtocolVersion)) self.remoteProtocolVersion = specifiedRemoteProtocolVersion elif command == 'sendaddr': if self.connectionIsOrWasFullyEstablished: # only send addr messages if we have sent and heard a verack from the remote node numberOfAddressesInAddrMessage = len(data) payload = '' for hostDetails in data: timeLastReceivedMessageFromThisNode, streamNumber, services, host, port = hostDetails payload += pack('>Q', timeLastReceivedMessageFromThisNode ) # now uses 64-bit time payload += pack('>I', streamNumber) payload += pack( '>q', services ) # service bit flags offered by this node payload += protocol.encodeHost(host) payload += pack('>H', port) payload = encodeVarint( numberOfAddressesInAddrMessage) + payload packet = protocol.CreatePacket('addr', payload) if not self.sendBytes(packet): break elif command == 'advertiseobject': self.objectHashHolderInstance.holdHash(data) elif command == 'sendinv': if self.connectionIsOrWasFullyEstablished: # only send inv messages if we have send and heard a verack from the remote node payload = '' for hash in data: payload += hash if payload != '': payload = encodeVarint(len(payload) / 32) + payload packet = protocol.CreatePacket('inv', payload) if not self.sendBytes(packet): break elif command == 'pong': if self.lastTimeISentData < (int(time.time()) - 298): # Send out a pong message to keep the connection alive. logger.debug('Sending pong to ' + str(self.peer) + ' to keep connection alive.') packet = protocol.CreatePacket('pong') if not self.sendBytes(packet): break elif command == 'sendRawData': objectHash = None if type(data) in [list, tuple]: objectHash, data = data if not self.sendBytes(data): break if objectHash: PendingUpload().delete(objectHash) elif command == 'connectionIsOrWasFullyEstablished': self.connectionIsOrWasFullyEstablished = True self.services, self.sock = data elif self.connectionIsOrWasFullyEstablished: logger.error('sendDataThread ID: ' + str(id(self)) + ' ignoring command ' + command + ' because the thread is not in stream ' + str(deststream) + ' but in streams ' + ', '.join(str(x) for x in self.streamNumber)) self.sendDataThreadQueue.task_done() # Flush if the cycle ended with break try: self.sendDataThreadQueue.task_done() except ValueError: pass try: self.sock.shutdown(socket.SHUT_RDWR) self.sock.close() except: pass state.sendDataQueues.remove(self.sendDataThreadQueue) PendingUpload().threadEnd() logger.info('sendDataThread ending. ID: ' + str(id(self)) + '. Number of queues in sendDataQueues: ' + str(len(state.sendDataQueues))) self.objectHashHolderInstance.close()
def run(self): logger.debug('sendDataThread starting. ID: ' + str(id(self)) + '. Number of queues in sendDataQueues: ' + str(len(state.sendDataQueues))) while self.sendBytes(): deststream, command, data = self.sendDataThreadQueue.get() if deststream == 0 or deststream in self.streamNumber: if command == 'shutdown': logger.debug('sendDataThread (associated with ' + str(self.peer) + ') ID: ' + str(id(self)) + ' shutting down now.') break # When you receive an incoming connection, a sendDataThread is # created even though you don't yet know what stream number the # remote peer is interested in. They will tell you in a version # message and if you too are interested in that stream then you # will continue on with the connection and will set the # streamNumber of this send data thread here: elif command == 'setStreamNumber': self.streamNumber = data logger.debug('setting the stream number to %s', ', '.join(str(x) for x in self.streamNumber)) elif command == 'setRemoteProtocolVersion': specifiedRemoteProtocolVersion = data logger.debug('setting the remote node\'s protocol version in the sendDataThread (ID: ' + str(id(self)) + ') to ' + str(specifiedRemoteProtocolVersion)) self.remoteProtocolVersion = specifiedRemoteProtocolVersion elif command == 'advertisepeer': self.objectHashHolderInstance.holdPeer(data) elif command == 'sendaddr': if self.connectionIsOrWasFullyEstablished: # only send addr messages if we have sent and heard a verack from the remote node numberOfAddressesInAddrMessage = len(data) payload = '' for hostDetails in data: timeLastReceivedMessageFromThisNode, streamNumber, services, host, port = hostDetails payload += pack( '>Q', timeLastReceivedMessageFromThisNode) # now uses 64-bit time payload += pack('>I', streamNumber) payload += pack( '>q', services) # service bit flags offered by this node payload += protocol.encodeHost(host) payload += pack('>H', port) payload = encodeVarint(numberOfAddressesInAddrMessage) + payload packet = protocol.CreatePacket('addr', payload) try: self.sendBytes(packet) except: logger.error('sendaddr: self.sock.sendall failed') break elif command == 'advertiseobject': self.objectHashHolderInstance.holdHash(data) elif command == 'sendinv': if self.connectionIsOrWasFullyEstablished: # only send inv messages if we have send and heard a verack from the remote node payload = '' for hash in data: payload += hash if payload != '': payload = encodeVarint(len(payload)/32) + payload packet = protocol.CreatePacket('inv', payload) try: self.sendBytes(packet) except: logger.error('sendinv: self.sock.sendall failed') break elif command == 'pong': if self.lastTimeISentData < (int(time.time()) - 298): # Send out a pong message to keep the connection alive. logger.debug('Sending pong to ' + str(self.peer) + ' to keep connection alive.') packet = protocol.CreatePacket('pong') try: self.sendBytes(packet) except: logger.error('send pong failed') break elif command == 'sendRawData': objectHash = None if type(data) in [list, tuple]: objectHash, data = data try: self.sendBytes(data) PendingUpload().delete(objectHash) except: logger.error('Sending of data to ' + str(self.peer) + ' failed. sendDataThread thread ' + str(self) + ' ending now.', exc_info=True) break elif command == 'connectionIsOrWasFullyEstablished': self.connectionIsOrWasFullyEstablished = True self.services, self.sslSock = data elif self.connectionIsOrWasFullyEstablished: logger.error('sendDataThread ID: ' + str(id(self)) + ' ignoring command ' + command + ' because the thread is not in stream ' + str(deststream) + ' but in streams ' + ', '.join(str(x) for x in self.streamNumber)) self.sendDataThreadQueue.task_done() # Flush if the cycle ended with break try: self.sendDataThreadQueue.task_done() except ValueError: pass try: self.sock.shutdown(socket.SHUT_RDWR) self.sock.close() except: pass state.sendDataQueues.remove(self.sendDataThreadQueue) PendingUpload().threadEnd() logger.info('sendDataThread ending. ID: ' + str(id(self)) + '. Number of queues in sendDataQueues: ' + str(len(state.sendDataQueues))) self.objectHashHolderInstance.close()
def sendaddr(self): def sendChunk(): if numberOfAddressesInAddrMessage == 0: return self.sendDataThreadQueue.put((0, 'sendRawData', \ protocol.CreatePacket('addr', \ encodeVarint(numberOfAddressesInAddrMessage) + payload))) # We are going to share a maximum number of 1000 addrs (per overlapping # stream) with our peer. 500 from overlapping streams, 250 from the # left child stream, and 250 from the right child stream. maxAddrCount = BMConfigParser().safeGetInt("bitmessagesettings", "maxaddrperstreamsend", 500) # protocol defines this as a maximum in one chunk protocolAddrLimit = 1000 # init numberOfAddressesInAddrMessage = 0 payload = '' for stream in self.streamNumber: addrsInMyStream = {} addrsInChildStreamLeft = {} addrsInChildStreamRight = {} with knownnodes.knownNodesLock: if len(knownnodes.knownNodes[stream]) > 0: filtered = { k: v for k, v in knownnodes.knownNodes[stream].items() if v > (int(time.time()) - shared.maximumAgeOfNodesThatIAdvertiseToOthers) } elemCount = len(filtered) if elemCount > maxAddrCount: elemCount = maxAddrCount # only if more recent than 3 hours addrsInMyStream = random.sample(filtered.items(), elemCount) # sent 250 only if the remote isn't interested in it if len(knownnodes.knownNodes[ stream * 2]) > 0 and stream not in self.streamNumber: filtered = { k: v for k, v in knownnodes.knownNodes[stream * 2].items() if v > (int(time.time()) - shared.maximumAgeOfNodesThatIAdvertiseToOthers) } elemCount = len(filtered) if elemCount > maxAddrCount / 2: elemCount = int(maxAddrCount / 2) addrsInChildStreamLeft = random.sample( filtered.items(), elemCount) if len(knownnodes.knownNodes[ (stream * 2) + 1]) > 0 and stream not in self.streamNumber: filtered = { k: v for k, v in knownnodes.knownNodes[stream * 2 + 1].items() if v > (int(time.time()) - shared.maximumAgeOfNodesThatIAdvertiseToOthers) } elemCount = len(filtered) if elemCount > maxAddrCount / 2: elemCount = int(maxAddrCount / 2) addrsInChildStreamRight = random.sample( filtered.items(), elemCount) for (HOST, PORT), timeLastReceivedMessageFromThisNode in addrsInMyStream: numberOfAddressesInAddrMessage += 1 payload += pack( '>Q', timeLastReceivedMessageFromThisNode) # 64-bit time payload += pack('>I', stream) payload += pack('>q', 1) # service bit flags offered by this node payload += protocol.encodeHost(HOST) payload += pack('>H', PORT) # remote port if numberOfAddressesInAddrMessage >= protocolAddrLimit: sendChunk() payload = '' numberOfAddressesInAddrMessage = 0 for ( HOST, PORT ), timeLastReceivedMessageFromThisNode in addrsInChildStreamLeft: numberOfAddressesInAddrMessage += 1 payload += pack( '>Q', timeLastReceivedMessageFromThisNode) # 64-bit time payload += pack('>I', stream * 2) payload += pack('>q', 1) # service bit flags offered by this node payload += protocol.encodeHost(HOST) payload += pack('>H', PORT) # remote port if numberOfAddressesInAddrMessage >= protocolAddrLimit: sendChunk() payload = '' numberOfAddressesInAddrMessage = 0 for ( HOST, PORT ), timeLastReceivedMessageFromThisNode in addrsInChildStreamRight: numberOfAddressesInAddrMessage += 1 payload += pack( '>Q', timeLastReceivedMessageFromThisNode) # 64-bit time payload += pack('>I', (stream * 2) + 1) payload += pack('>q', 1) # service bit flags offered by this node payload += protocol.encodeHost(HOST) payload += pack('>H', PORT) # remote port if numberOfAddressesInAddrMessage >= protocolAddrLimit: sendChunk() payload = '' numberOfAddressesInAddrMessage = 0 # flush sendChunk()
def sendaddr(self): def sendChunk(): if numberOfAddressesInAddrMessage == 0: return self.sendDataThreadQueue.put((0, 'sendRawData', \ protocol.CreatePacket('addr', \ encodeVarint(numberOfAddressesInAddrMessage) + payload))) # We are going to share a maximum number of 1000 addrs (per overlapping # stream) with our peer. 500 from overlapping streams, 250 from the # left child stream, and 250 from the right child stream. maxAddrCount = BMConfigParser().safeGetInt("bitmessagesettings", "maxaddrperstreamsend", 500) # protocol defines this as a maximum in one chunk protocolAddrLimit = 1000 # init numberOfAddressesInAddrMessage = 0 payload = '' for stream in self.streamNumber: addrsInMyStream = {} addrsInChildStreamLeft = {} addrsInChildStreamRight = {} with knownnodes.knownNodesLock: if len(knownnodes.knownNodes[stream]) > 0: filtered = {k: v for k, v in knownnodes.knownNodes[stream].items() if v > (int(time.time()) - shared.maximumAgeOfNodesThatIAdvertiseToOthers)} elemCount = len(filtered) if elemCount > maxAddrCount: elemCount = maxAddrCount # only if more recent than 3 hours addrsInMyStream = random.sample(filtered.items(), elemCount) # sent 250 only if the remote isn't interested in it if len(knownnodes.knownNodes[stream * 2]) > 0 and stream not in self.streamNumber: filtered = {k: v for k, v in knownnodes.knownNodes[stream*2].items() if v > (int(time.time()) - shared.maximumAgeOfNodesThatIAdvertiseToOthers)} elemCount = len(filtered) if elemCount > maxAddrCount / 2: elemCount = int(maxAddrCount / 2) addrsInChildStreamLeft = random.sample(filtered.items(), elemCount) if len(knownnodes.knownNodes[(stream * 2) + 1]) > 0 and stream not in self.streamNumber: filtered = {k: v for k, v in knownnodes.knownNodes[stream*2+1].items() if v > (int(time.time()) - shared.maximumAgeOfNodesThatIAdvertiseToOthers)} elemCount = len(filtered) if elemCount > maxAddrCount / 2: elemCount = int(maxAddrCount / 2) addrsInChildStreamRight = random.sample(filtered.items(), elemCount) for (HOST, PORT), timeLastReceivedMessageFromThisNode in addrsInMyStream: numberOfAddressesInAddrMessage += 1 payload += pack( '>Q', timeLastReceivedMessageFromThisNode) # 64-bit time payload += pack('>I', stream) payload += pack( '>q', 1) # service bit flags offered by this node payload += protocol.encodeHost(HOST) payload += pack('>H', PORT) # remote port if numberOfAddressesInAddrMessage >= protocolAddrLimit: sendChunk() payload = '' numberOfAddressesInAddrMessage = 0 for (HOST, PORT), timeLastReceivedMessageFromThisNode in addrsInChildStreamLeft: numberOfAddressesInAddrMessage += 1 payload += pack( '>Q', timeLastReceivedMessageFromThisNode) # 64-bit time payload += pack('>I', stream * 2) payload += pack( '>q', 1) # service bit flags offered by this node payload += protocol.encodeHost(HOST) payload += pack('>H', PORT) # remote port if numberOfAddressesInAddrMessage >= protocolAddrLimit: sendChunk() payload = '' numberOfAddressesInAddrMessage = 0 for (HOST, PORT), timeLastReceivedMessageFromThisNode in addrsInChildStreamRight: numberOfAddressesInAddrMessage += 1 payload += pack( '>Q', timeLastReceivedMessageFromThisNode) # 64-bit time payload += pack('>I', (stream * 2) + 1) payload += pack( '>q', 1) # service bit flags offered by this node payload += protocol.encodeHost(HOST) payload += pack('>H', PORT) # remote port if numberOfAddressesInAddrMessage >= protocolAddrLimit: sendChunk() payload = '' numberOfAddressesInAddrMessage = 0 # flush sendChunk()