def knownNodes(): try: # We shouldn't have to use the shared.knownNodesLock because this had # better be the only thread accessing knownNodes right now. pickleFile = open(shared.appdata + 'knownnodes.dat', 'rb') loadedKnownNodes = pickle.load(pickleFile) pickleFile.close() # The old format of storing knownNodes was as a 'host: (port, time)' # mapping. The new format is as 'Peer: time' pairs. If we loaded # data in the old format, transform it to the new style. for stream, nodes in loadedKnownNodes.items(): shared.knownNodes[stream] = {} for node_tuple in nodes.items(): try: host, (port, lastseen) = node_tuple peer = shared.Peer(host, port) except: peer, lastseen = node_tuple shared.knownNodes[stream][peer] = lastseen except: shared.knownNodes = defaultKnownNodes.createDefaultKnownNodes(shared.appdata) # your own onion address, if setup if shared.config.has_option('bitmessagesettings', 'onionhostname') and ".onion" in shared.config.get('bitmessagesettings', 'onionhostname'): shared.knownNodes[1][shared.Peer(shared.config.get('bitmessagesettings', 'onionhostname'), shared.config.getint('bitmessagesettings', 'onionport'))] = int(time.time()) if shared.config.getint('bitmessagesettings', 'settingsversion') > 10: logger.error('Bitmessage cannot read future versions of the keys file (keys.dat). Run the newer version of Bitmessage.') raise SystemExit
def dns(): # DNS bootstrap. This could be programmed to use the SOCKS proxy to do the # DNS lookup some day but for now we will just rely on the entries in # defaultKnownNodes.py. Hopefully either they are up to date or the user # has run Bitmessage recently without SOCKS turned on and received good # bootstrap nodes using that method. with shared.printLock: if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none': try: for item in socket.getaddrinfo('bootstrap8080.bitmessage.org', 80): print 'Adding', item[4][ 0], 'to knownNodes based on DNS boostrap method' shared.knownNodes[1][shared.Peer(item[4][0], 8080)] = int(time.time()) except: print 'bootstrap8080.bitmessage.org DNS bootstrapping failed.' try: for item in socket.getaddrinfo('bootstrap8444.bitmessage.org', 80): print 'Adding', item[4][ 0], 'to knownNodes based on DNS boostrap method' shared.knownNodes[1][shared.Peer(item[4][0], 8444)] = int(time.time()) except: print 'bootstrap8444.bitmessage.org DNS bootstrapping failed.' else: print 'DNS bootstrap skipped because SOCKS is used.'
def dns(): # DNS bootstrap. This could be programmed to use the SOCKS proxy to do the # DNS lookup some day but for now we will just rely on the entries in # defaultKnownNodes.py. Hopefully either they are up to date or the user # has run Bitmessage recently without SOCKS turned on and received good # bootstrap nodes using that method. if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none': try: for item in socket.getaddrinfo('bootstrap8080.bitmessage.org', 80): logger.info('Adding ' + item[4][0] + ' to knownNodes based on DNS bootstrap method') shared.knownNodes[1][shared.Peer(item[4][0], 8080)] = int(time.time()) except: logger.error('bootstrap8080.bitmessage.org DNS bootstrapping failed.') try: for item in socket.getaddrinfo('bootstrap8444.bitmessage.org', 80): logger.info ('Adding ' + item[4][0] + ' to knownNodes based on DNS bootstrap method') shared.knownNodes[1][shared.Peer(item[4][0], 8444)] = int(time.time()) except: logger.error('bootstrap8444.bitmessage.org DNS bootstrapping failed.') elif shared.config.get('bitmessagesettings', 'socksproxytype') == 'SOCKS5': shared.knownNodes[1][shared.Peer('quzwelsuziwqgpt2.onion', 8444)] = int(time.time()) logger.debug("Adding quzwelsuziwqgpt2.onion:8444 to knownNodes.") for port in [8080, 8444]: logger.debug("Resolving %i through SOCKS...", port) address_family = socket.AF_INET sock = socks.socksocket(address_family, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.settimeout(20) proxytype = socks.PROXY_TYPE_SOCKS5 sockshostname = shared.config.get( 'bitmessagesettings', 'sockshostname') socksport = shared.config.getint( 'bitmessagesettings', 'socksport') rdns = True # Do domain name lookups through the proxy; though this setting doesn't really matter since we won't be doing any domain name lookups anyway. if shared.config.getboolean('bitmessagesettings', 'socksauthentication'): socksusername = shared.config.get( 'bitmessagesettings', 'socksusername') sockspassword = shared.config.get( 'bitmessagesettings', 'sockspassword') sock.setproxy( proxytype, sockshostname, socksport, rdns, socksusername, sockspassword) else: sock.setproxy( proxytype, sockshostname, socksport, rdns) try: ip = sock.resolve("bootstrap" + str(port) + ".bitmessage.org") sock.shutdown(socket.SHUT_RDWR) sock.close() except: logger.error("SOCKS DNS resolving failed", exc_info=True) if ip is not None: logger.info ('Adding ' + ip + ' to knownNodes based on SOCKS DNS bootstrap method') shared.knownNodes[1][shared.Peer(ip, port)] = time.time() else: logger.info('DNS bootstrap skipped because the proxy type does not support DNS resolution.')
def createDefaultKnownNodes(appdata): ############## Stream 1 ################ stream1 = {} #stream1[shared.Peer('2604:2000:1380:9f:82e:148b:2746:d0c7', 8080)] = int(time.time()) stream1[shared.Peer('5.45.99.75', 8444)] = int(time.time()) stream1[shared.Peer('75.167.159.54', 8444)] = int(time.time()) stream1[shared.Peer('95.165.168.168', 8444)] = int(time.time()) stream1[shared.Peer('85.180.139.241', 8444)] = int(time.time()) stream1[shared.Peer('158.222.211.81', 8080)] = int(time.time()) stream1[shared.Peer('178.62.12.187', 8448)] = int(time.time()) stream1[shared.Peer('24.188.198.204', 8111)] = int(time.time()) stream1[shared.Peer('109.147.204.113', 1195)] = int(time.time()) stream1[shared.Peer('178.11.46.221', 8444)] = int(time.time()) ############# Stream 2 ################# stream2 = {} # None yet ############# Stream 3 ################# stream3 = {} # None yet allKnownNodes = {} allKnownNodes[1] = stream1 allKnownNodes[2] = stream2 allKnownNodes[3] = stream3 with open(appdata + 'knownnodes.dat', 'wb') as output: # Pickle dictionary using protocol 0. pickle.dump(allKnownNodes, output) return allKnownNodes
def createDefaultKnownNodes(appdata): ############## Stream 1 ################ stream1 = {} stream1[shared.Peer('85.171.174.131', 8444)] = int(time.time()) stream1[shared.Peer('23.28.68.159', 8444)] = int(time.time()) stream1[shared.Peer('66.108.210.240', 8444)] = int(time.time()) stream1[shared.Peer('204.236.246.212', 8444)] = int(time.time()) stream1[shared.Peer('78.81.56.239', 8444)] = int(time.time()) stream1[shared.Peer('122.60.235.157', 8444)] = int(time.time()) stream1[shared.Peer('204.236.246.212', 8444)] = int(time.time()) stream1[shared.Peer('24.98.219.109', 8444)] = int(time.time()) ############# Stream 2 ################# stream2 = {} # None yet ############# Stream 3 ################# stream3 = {} # None yet allKnownNodes = {} allKnownNodes[1] = stream1 allKnownNodes[2] = stream2 allKnownNodes[3] = stream3 #print stream1 #print allKnownNodes with open(appdata + 'knownnodes.dat', 'wb') as output: # Pickle dictionary using protocol 0. pickle.dump(allKnownNodes, output) return allKnownNodes
def setup( self, sock, HOST, port, streamNumber, someObjectsOfWhichThisRemoteNodeIsAlreadyAware, selfInitiatedConnections, sendDataThreadQueue, objectHashHolderInstance): self.sock = sock self.peer = shared.Peer(HOST, port) self.name = "receiveData-" + self.peer.host.replace(":", ".") # ":" log parser field separator self.streamNumber = streamNumber self.objectsThatWeHaveYetToGetFromThisPeer = {} self.selfInitiatedConnections = selfInitiatedConnections self.sendDataThreadQueue = sendDataThreadQueue # used to send commands and data to the sendDataThread shared.connectedHostsList[ self.peer.host] = 0 # The very fact that this receiveData thread exists shows that we are connected to the remote host. Let's add it to this list so that an outgoingSynSender thread doesn't try to connect to it. self.connectionIsOrWasFullyEstablished = False # set to true after the remote node and I accept each other's version messages. This is needed to allow the user interface to accurately reflect the current number of connections. self.services = 0 if self.streamNumber == -1: # This was an incoming connection. Send out a version message if we accept the other node's version message. self.initiatedConnection = False else: self.initiatedConnection = True self.selfInitiatedConnections[streamNumber][self] = 0 self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware = someObjectsOfWhichThisRemoteNodeIsAlreadyAware self.objectHashHolderInstance = objectHashHolderInstance self.startTime = time.time()
def setup( self, sock, HOST, port, streamNumber, someObjectsOfWhichThisRemoteNodeIsAlreadyAware, selfInitiatedConnections, sendDataThreadQueue): self.sock = sock self.peer = shared.Peer(HOST, port) self.streamNumber = streamNumber self.payloadLength = 0 # This is the protocol payload length thus it doesn't include the 24 byte message header self.objectsThatWeHaveYetToGetFromThisPeer = {} self.selfInitiatedConnections = selfInitiatedConnections self.sendDataThreadQueue = sendDataThreadQueue # used to send commands and data to the sendDataThread shared.connectedHostsList[ self.peer.host] = 0 # The very fact that this receiveData thread exists shows that we are connected to the remote host. Let's add it to this list so that an outgoingSynSender thread doesn't try to connect to it. self.connectionIsOrWasFullyEstablished = False # set to true after the remote node and I accept each other's version messages. This is needed to allow the user interface to accurately reflect the current number of connections. if self.streamNumber == -1: # This was an incoming connection. Send out a version message if we accept the other node's version message. self.initiatedConnection = False else: self.initiatedConnection = True self.selfInitiatedConnections[streamNumber][self] = 0 self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware = someObjectsOfWhichThisRemoteNodeIsAlreadyAware
def knownNodes(): try: # We shouldn't have to use the shared.knownNodesLock because this had # better be the only thread accessing knownNodes right now. pickleFile = open(shared.appdata + 'knownnodes.dat', 'rb') loadedKnownNodes = pickle.load(pickleFile) pickleFile.close() # The old format of storing knownNodes was as a 'host: (port, time)' # mapping. The new format is as 'Peer: time' pairs. If we loaded # data in the old format, transform it to the new style. for stream, nodes in loadedKnownNodes.items(): shared.knownNodes[stream] = {} for node_tuple in nodes.items(): try: host, (port, time) = node_tuple peer = shared.Peer(host, port) except: peer, time = node_tuple shared.knownNodes[stream][peer] = time except: shared.knownNodes = defaultKnownNodes.createDefaultKnownNodes( shared.appdata) if shared.config.getint('bitmessagesettings', 'settingsversion') > 8: print 'Bitmessage cannot read future versions of the keys file (keys.dat). Run the newer version of Bitmessage.' raise SystemExit
def recaddr(self, data): numberOfAddressesIncluded, lengthOfNumberOfAddresses = decodeVarint( data[:10]) if numberOfAddressesIncluded > 1000 or numberOfAddressesIncluded == 0: return if len(data) != lengthOfNumberOfAddresses + (38 * numberOfAddressesIncluded): return for i in xrange(0, numberOfAddressesIncluded): fullHost = data[20 + lengthOfNumberOfAddresses + (38 * i):36 + lengthOfNumberOfAddresses + (38 * i)] recaddrStream, = unpack('>I', data[8 + lengthOfNumberOfAddresses + ( 38 * i):12 + lengthOfNumberOfAddresses + (38 * i)]) if recaddrStream == 0: continue if recaddrStream != self.streamNumber and recaddrStream != (self.streamNumber * 2) and recaddrStream != ((self.streamNumber * 2) + 1): # if the embedded stream number is not in my stream or either of my child streams then ignore it. Someone might be trying funny business. continue recaddrServices, = unpack('>Q', data[12 + lengthOfNumberOfAddresses + ( 38 * i):20 + lengthOfNumberOfAddresses + (38 * i)]) recaddrPort, = unpack('>H', data[36 + lengthOfNumberOfAddresses + ( 38 * i):38 + lengthOfNumberOfAddresses + (38 * i)]) if fullHost[0:12] == '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': ipv4Host = fullHost[12:] hostStandardFormat = socket.inet_ntop(socket.AF_INET, ipv4Host) if not self._checkIPv4Address(ipv4Host, hostStandardFormat): continue else: hostStandardFormat = socket.inet_ntop(socket.AF_INET6, fullHost) if hostStandardFormat == "": # This can happen on Windows systems which are not 64-bit compatible # so let us drop the IPv6 address. continue if not self._checkIPv6Address(fullHost, hostStandardFormat): continue timeSomeoneElseReceivedMessageFromThisNode, = unpack('>Q', data[lengthOfNumberOfAddresses + ( 38 * i):8 + lengthOfNumberOfAddresses + (38 * i)]) # This is the 'time' value in the received addr message. 64-bit. if recaddrStream not in shared.knownNodes: # knownNodes is a dictionary of dictionaries with one outer dictionary for each stream. If the outer stream dictionary doesn't exist yet then we must make it. with shared.knownNodesLock: shared.knownNodes[recaddrStream] = {} peerFromAddrMessage = shared.Peer(hostStandardFormat, recaddrPort) if peerFromAddrMessage not in shared.knownNodes[recaddrStream]: if len(shared.knownNodes[recaddrStream]) < 20000 and timeSomeoneElseReceivedMessageFromThisNode > (int(time.time()) - 10800) and timeSomeoneElseReceivedMessageFromThisNode < (int(time.time()) + 10800): # If we have more than 20000 nodes in our list already then just forget about adding more. Also, make sure that the time that someone else received a message from this node is within three hours from now. with shared.knownNodesLock: shared.knownNodes[recaddrStream][peerFromAddrMessage] = timeSomeoneElseReceivedMessageFromThisNode shared.needToWriteKnownNodesToDisk = True hostDetails = ( timeSomeoneElseReceivedMessageFromThisNode, recaddrStream, recaddrServices, hostStandardFormat, recaddrPort) shared.broadcastToSendDataQueues(( self.streamNumber, 'advertisepeer', hostDetails)) else: timeLastReceivedMessageFromThisNode = shared.knownNodes[recaddrStream][ peerFromAddrMessage] if (timeLastReceivedMessageFromThisNode < timeSomeoneElseReceivedMessageFromThisNode) and (timeSomeoneElseReceivedMessageFromThisNode < int(time.time())+900): # 900 seconds for wiggle-room in case other nodes' clocks aren't quite right. with shared.knownNodesLock: shared.knownNodes[recaddrStream][peerFromAddrMessage] = timeSomeoneElseReceivedMessageFromThisNode
def recversion(self, data): if len(data) < 83: # This version message is unreasonably short. Forget it. return elif not self.verackSent: self.remoteProtocolVersion, = unpack('>L', data[:4]) if self.remoteProtocolVersion <= 1: shared.broadcastToSendDataQueues((0, 'shutdown', self.peer)) with shared.printLock: print 'Closing connection to old protocol version 1 node: ', self.peer return # print 'remoteProtocolVersion', self.remoteProtocolVersion self.myExternalIP = socket.inet_ntoa(data[40:44]) # print 'myExternalIP', self.myExternalIP self.remoteNodeIncomingPort, = unpack('>H', data[70:72]) # print 'remoteNodeIncomingPort', self.remoteNodeIncomingPort useragentLength, lengthOfUseragentVarint = decodeVarint( data[80:84]) readPosition = 80 + lengthOfUseragentVarint useragent = data[readPosition:readPosition + useragentLength] readPosition += useragentLength numberOfStreamsInVersionMessage, lengthOfNumberOfStreamsInVersionMessage = decodeVarint( data[readPosition:]) readPosition += lengthOfNumberOfStreamsInVersionMessage self.streamNumber, lengthOfRemoteStreamNumber = decodeVarint( data[readPosition:]) with shared.printLock: print 'Remote node useragent:', useragent, ' stream number:', self.streamNumber if self.streamNumber != 1: shared.broadcastToSendDataQueues((0, 'shutdown', self.peer)) with shared.printLock: print 'Closed connection to', self.peer, 'because they are interested in stream', self.streamNumber, '.' return shared.connectedHostsList[ self.peer.host] = 1 # We use this data structure to not only keep track of what hosts we are connected to so that we don't try to connect to them again, but also to list the connections count on the Network Status tab. # If this was an incoming connection, then the sendData thread # doesn't know the stream. We have to set it. if not self.initiatedConnection: shared.broadcastToSendDataQueues(( 0, 'setStreamNumber', (self.peer, self.streamNumber))) if data[72:80] == shared.eightBytesOfRandomDataUsedToDetectConnectionsToSelf: shared.broadcastToSendDataQueues((0, 'shutdown', self.peer)) with shared.printLock: print 'Closing connection to myself: ', self.peer return self.sendDataThreadQueue.put((0, 'setRemoteProtocolVersion', self.remoteProtocolVersion)) shared.knownNodesLock.acquire() shared.knownNodes[self.streamNumber][shared.Peer(self.peer.host, self.remoteNodeIncomingPort)] = int(time.time()) shared.needToWriteKnownNodesToDisk = True shared.knownNodesLock.release() self.sendverack() if self.initiatedConnection == False: self.sendversion()
def recaddr(self, data): numberOfAddressesIncluded, lengthOfNumberOfAddresses = decodeVarint( data[:10]) if shared.verbose >= 1: logger.debug('addr message contains ' + str(numberOfAddressesIncluded) + ' IP addresses.') if numberOfAddressesIncluded > 1000 or numberOfAddressesIncluded == 0: return if len(data) != lengthOfNumberOfAddresses + (38 * numberOfAddressesIncluded): logger.debug('addr message does not contain the correct amount of data. Ignoring.') return for i in range(0, numberOfAddressesIncluded): fullHost = data[20 + lengthOfNumberOfAddresses + (38 * i):36 + lengthOfNumberOfAddresses + (38 * i)] recaddrStream, = unpack('>I', data[8 + lengthOfNumberOfAddresses + ( 38 * i):12 + lengthOfNumberOfAddresses + (38 * i)]) if recaddrStream == 0: continue if recaddrStream != self.streamNumber and recaddrStream != (self.streamNumber * 2) and recaddrStream != ((self.streamNumber * 2) + 1): # if the embedded stream number is not in my stream or either of my child streams then ignore it. Someone might be trying funny business. continue recaddrServices, = unpack('>Q', data[12 + lengthOfNumberOfAddresses + ( 38 * i):20 + lengthOfNumberOfAddresses + (38 * i)]) recaddrPort, = unpack('>H', data[36 + lengthOfNumberOfAddresses + ( 38 * i):38 + lengthOfNumberOfAddresses + (38 * i)]) hostStandardFormat = self._checkIPAddress(fullHost) if hostStandardFormat is False: continue if recaddrPort == 0: continue timeSomeoneElseReceivedMessageFromThisNode, = unpack('>Q', data[lengthOfNumberOfAddresses + ( 38 * i):8 + lengthOfNumberOfAddresses + (38 * i)]) # This is the 'time' value in the received addr message. 64-bit. if recaddrStream not in shared.knownNodes: # knownNodes is a dictionary of dictionaries with one outer dictionary for each stream. If the outer stream dictionary doesn't exist yet then we must make it. with shared.knownNodesLock: shared.knownNodes[recaddrStream] = {} peerFromAddrMessage = shared.Peer(hostStandardFormat, recaddrPort) if peerFromAddrMessage not in shared.knownNodes[recaddrStream]: if len(shared.knownNodes[recaddrStream]) < 20000 and timeSomeoneElseReceivedMessageFromThisNode > (int(time.time()) - 10800) and timeSomeoneElseReceivedMessageFromThisNode < (int(time.time()) + 10800): # If we have more than 20000 nodes in our list already then just forget about adding more. Also, make sure that the time that someone else received a message from this node is within three hours from now. with shared.knownNodesLock: shared.knownNodes[recaddrStream][peerFromAddrMessage] = timeSomeoneElseReceivedMessageFromThisNode logger.debug('added new node ' + str(peerFromAddrMessage) + ' to knownNodes in stream ' + str(recaddrStream)) shared.needToWriteKnownNodesToDisk = True hostDetails = ( timeSomeoneElseReceivedMessageFromThisNode, recaddrStream, recaddrServices, hostStandardFormat, recaddrPort) shared.broadcastToSendDataQueues(( self.streamNumber, 'advertisepeer', hostDetails)) else: timeLastReceivedMessageFromThisNode = shared.knownNodes[recaddrStream][ peerFromAddrMessage] if (timeLastReceivedMessageFromThisNode < timeSomeoneElseReceivedMessageFromThisNode) and (timeSomeoneElseReceivedMessageFromThisNode < int(time.time())+900): # 900 seconds for wiggle-room in case other nodes' clocks aren't quite right. with shared.knownNodesLock: shared.knownNodes[recaddrStream][peerFromAddrMessage] = timeSomeoneElseReceivedMessageFromThisNode logger.debug('knownNodes currently has ' + str(len(shared.knownNodes[self.streamNumber])) + ' nodes for this stream.')
def _loadTrustedPeer(): try: trustedPeer = shared.config.get('bitmessagesettings', 'trustedpeer') except ConfigParser.Error: # This probably means the trusted peer wasn't specified so we # can just leave it as None return host, port = trustedPeer.split(':') shared.trustedPeer = shared.Peer(host, int(port))
def setup(self, sock, HOST, PORT, streamNumber, someObjectsOfWhichThisRemoteNodeIsAlreadyAware): self.sock = sock self.peer = shared.Peer(HOST, PORT) self.streamNumber = streamNumber self.remoteProtocolVersion = - \ 1 # This must be set using setRemoteProtocolVersion command which is sent through the self.sendDataThreadQueue queue. self.lastTimeISentData = int( time.time() ) # If this value increases beyond five minutes ago, we'll send a pong message to keep the connection alive. self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware = someObjectsOfWhichThisRemoteNodeIsAlreadyAware
def createDefaultKnownNodes(appdata): ############## Stream 1 ################ stream1 = {} #stream1[shared.Peer('2604:2000:1380:9f:82e:148b:2746:d0c7', 8080)] = int(time.time()) stream1[shared.Peer('23.239.9.147', 8444)] = int(time.time()) stream1[shared.Peer('98.218.125.214', 8444)] = int(time.time()) stream1[shared.Peer('192.121.170.162', 8444)] = int(time.time()) stream1[shared.Peer('108.61.72.12', 28444)] = int(time.time()) stream1[shared.Peer('158.222.211.81', 8080)] = int(time.time()) stream1[shared.Peer('79.163.240.110', 8446)] = int(time.time()) stream1[shared.Peer('178.62.154.250', 8444)] = int(time.time()) stream1[shared.Peer('178.62.155.6', 8444)] = int(time.time()) stream1[shared.Peer('178.62.155.8', 8444)] = int(time.time()) stream1[shared.Peer('68.42.42.120', 8444)] = int(time.time()) ############# Stream 2 ################# stream2 = {} # None yet ############# Stream 3 ################# stream3 = {} # None yet allKnownNodes = {} allKnownNodes[1] = stream1 allKnownNodes[2] = stream2 allKnownNodes[3] = stream3 #print stream1 #print allKnownNodes with open(appdata + 'knownnodes.dat', 'wb') as output: # Pickle dictionary using protocol 0. pickle.dump(allKnownNodes, output) return allKnownNodes
def createDefaultKnownNodes(appdata): ############## Stream 1 ################ stream1 = {} stream1[shared.Peer('176.31.246.114', 8444)] = int(time.time()) stream1[shared.Peer('109.229.197.133', 8444)] = int(time.time()) stream1[shared.Peer('174.3.101.111', 8444)] = int(time.time()) stream1[shared.Peer('90.188.238.79', 7829)] = int(time.time()) stream1[shared.Peer('184.75.69.2', 8444)] = int(time.time()) stream1[shared.Peer('60.225.209.243', 8444)] = int(time.time()) stream1[shared.Peer('5.145.140.218', 8444)] = int(time.time()) stream1[shared.Peer('5.19.255.216', 8444)] = int(time.time()) stream1[shared.Peer('193.159.162.189', 8444)] = int(time.time()) stream1[shared.Peer('86.26.15.171', 8444)] = int(time.time()) ############# Stream 2 ################# stream2 = {} # None yet ############# Stream 3 ################# stream3 = {} # None yet allKnownNodes = {} allKnownNodes[1] = stream1 allKnownNodes[2] = stream2 allKnownNodes[3] = stream3 #print stream1 #print allKnownNodes with open(appdata + 'knownnodes.dat', 'wb') as output: # Pickle dictionary using protocol 0. pickle.dump(allKnownNodes, output) return allKnownNodes
def createDefaultKnownNodes(appdata): ############## Stream 1 ################ stream1 = {} #stream1[shared.Peer('2604:2000:1380:9f:82e:148b:2746:d0c7', 8080)] = int(time.time()) stream1[shared.Peer('68.33.0.104', 8444)] = int(time.time()) stream1[shared.Peer('97.77.34.35', 8444)] = int(time.time()) stream1[shared.Peer('71.232.195.131', 8444)] = int(time.time()) stream1[shared.Peer('192.241.231.39', 8444)] = int(time.time()) stream1[shared.Peer('75.66.0.116', 8444)] = int(time.time()) stream1[shared.Peer('182.169.23.102', 8444)] = int(time.time()) stream1[shared.Peer('75.95.134.9', 8444)] = int(time.time()) stream1[shared.Peer('46.236.100.108', 48444)] = int(time.time()) stream1[shared.Peer('66.108.53.42', 8080)] = int(time.time()) ############# Stream 2 ################# stream2 = {} # None yet ############# Stream 3 ################# stream3 = {} # None yet allKnownNodes = {} allKnownNodes[1] = stream1 allKnownNodes[2] = stream2 allKnownNodes[3] = stream3 #print stream1 #print allKnownNodes with open(appdata + 'knownnodes.dat', 'wb') as output: # Pickle dictionary using protocol 0. pickle.dump(allKnownNodes, output) return allKnownNodes
def _getPeer(self): # If the user has specified a trusted peer then we'll only # ever connect to that. Otherwise we'll pick a random one from # the known nodes if shared.trustedPeer: shared.knownNodesLock.acquire() peer = shared.trustedPeer shared.knownNodes[self.streamNumber][peer] = time.time() shared.knownNodesLock.release() else: while not shared.shutdown: shared.knownNodesLock.acquire() try: peer, = random.sample(shared.knownNodes[self.streamNumber], 1) except ValueError: # no known nodes shared.knownNodesLock.release() time.sleep(1) continue priority = ( 183600 - (time.time() - shared.knownNodes[self.streamNumber][peer]) ) / 183600 # 2 days and 3 hours shared.knownNodesLock.release() if shared.config.get('bitmessagesettings', 'socksproxytype') != 'none': if peer.host.find(".onion") == -1: priority /= 10 # hidden services have 10x priority over plain net elif peer.host.find( ".onion") != -1: # onion address and so proxy continue if priority <= 0.001: # everyone has at least this much priority priority = 0.001 if (random.random() <= priority): break time.sleep(0.01) # prevent CPU hogging if something is broken try: return peer except NameError: return shared.Peer('127.0.0.1', 8444)
def setup(self, sock, HOST, PORT, streamNumber, someObjectsOfWhichThisRemoteNodeIsAlreadyAware): self.sock = sock self.peer = shared.Peer(HOST, PORT) self.name = "sendData-" + self.peer.host.replace( ":", ".") # log parser field separator self.streamNumber = streamNumber self.services = 0 self.initiatedConnection = False self.remoteProtocolVersion = - \ 1 # This must be set using setRemoteProtocolVersion command which is sent through the self.sendDataThreadQueue queue. self.lastTimeISentData = int( time.time() ) # If this value increases beyond five minutes ago, we'll send a pong message to keep the connection alive. self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware = someObjectsOfWhichThisRemoteNodeIsAlreadyAware if self.streamNumber == -1: # This was an incoming connection. self.initiatedConnection = False else: self.initiatedConnection = True logger.debug('The streamNumber of this sendDataThread (ID: ' + str(id(self)) + ') at setup() is' + str(self.streamNumber))
def knownNodes(): try: # We shouldn't have to use the shared.knownNodesLock because this had # better be the only thread accessing knownNodes right now. pickleFile = open(shared.appdata + 'knownnodes.dat', 'rb') loadedKnownNodes = pickle.load(pickleFile) pickleFile.close() # The old format of storing knownNodes was as a 'host: (port, time)' # mapping. The new format is as 'Peer: time' pairs. If we loaded # data in the old format, transform it to the new style. for stream, nodes in loadedKnownNodes.items(): shared.knownNodes[stream] = {} for node_tuple in nodes.items(): try: host, (port, time) = node_tuple peer = shared.Peer(host, port) except: peer, time = node_tuple shared.knownNodes[stream][peer] = time except: shared.knownNodes = defaultKnownNodes.createDefaultKnownNodes( shared.appdata)
def sendaddr(self): addrsInMyStream = {} addrsInChildStreamLeft = {} addrsInChildStreamRight = {} # print 'knownNodes', shared.knownNodes # We are going to share a maximum number of 1000 addrs with our peer. # 500 from this stream, 250 from the left child stream, and 250 from # the right child stream. with shared.knownNodesLock: if len(shared.knownNodes[self.streamNumber]) > 0: ownPosition = random.randint(0, 499) sentOwn = False for i in range(500): # if current connection is over a proxy, sent our own onion address at a random position if ownPosition == i and ".onion" in shared.config.get("bitmessagesettings", "onionhostname") and \ hasattr(self.sock, "getproxytype") and self.sock.getproxytype() != "none" and not sentOwn: peer = shared.Peer(shared.config.get("bitmessagesettings", "onionhostname"), shared.config.getint("bitmessagesettings", "onionport")) else: # still may contain own onion address, but we don't change it peer, = random.sample(shared.knownNodes[self.streamNumber], 1) if isHostInPrivateIPRange(peer.host): continue if peer.host == shared.config.get("bitmessagesettings", "onionhostname") and peer.port == shared.config.getint("bitmessagesettings", "onionport") : sentOwn = True addrsInMyStream[peer] = shared.knownNodes[ self.streamNumber][peer] if len(shared.knownNodes[self.streamNumber * 2]) > 0: for i in range(250): peer, = random.sample(shared.knownNodes[ self.streamNumber * 2], 1) if isHostInPrivateIPRange(peer.host): continue addrsInChildStreamLeft[peer] = shared.knownNodes[ self.streamNumber * 2][peer] if len(shared.knownNodes[(self.streamNumber * 2) + 1]) > 0: for i in range(250): peer, = random.sample(shared.knownNodes[ (self.streamNumber * 2) + 1], 1) if isHostInPrivateIPRange(peer.host): continue addrsInChildStreamRight[peer] = shared.knownNodes[ (self.streamNumber * 2) + 1][peer] numberOfAddressesInAddrMessage = 0 payload = '' # print 'addrsInMyStream.items()', addrsInMyStream.items() for (HOST, PORT), value in addrsInMyStream.items(): timeLastReceivedMessageFromThisNode = value if timeLastReceivedMessageFromThisNode > (int(time.time()) - shared.maximumAgeOfNodesThatIAdvertiseToOthers): # If it is younger than 3 hours old.. numberOfAddressesInAddrMessage += 1 payload += pack( '>Q', timeLastReceivedMessageFromThisNode) # 64-bit time payload += pack('>I', self.streamNumber) payload += pack( '>q', 1) # service bit flags offered by this node payload += shared.encodeHost(HOST) payload += pack('>H', PORT) # remote port for (HOST, PORT), value in addrsInChildStreamLeft.items(): timeLastReceivedMessageFromThisNode = value if timeLastReceivedMessageFromThisNode > (int(time.time()) - shared.maximumAgeOfNodesThatIAdvertiseToOthers): # If it is younger than 3 hours old.. numberOfAddressesInAddrMessage += 1 payload += pack( '>Q', timeLastReceivedMessageFromThisNode) # 64-bit time payload += pack('>I', self.streamNumber * 2) payload += pack( '>q', 1) # service bit flags offered by this node payload += shared.encodeHost(HOST) payload += pack('>H', PORT) # remote port for (HOST, PORT), value in addrsInChildStreamRight.items(): timeLastReceivedMessageFromThisNode = value if timeLastReceivedMessageFromThisNode > (int(time.time()) - shared.maximumAgeOfNodesThatIAdvertiseToOthers): # If it is younger than 3 hours old.. numberOfAddressesInAddrMessage += 1 payload += pack( '>Q', timeLastReceivedMessageFromThisNode) # 64-bit time payload += pack('>I', (self.streamNumber * 2) + 1) payload += pack( '>q', 1) # service bit flags offered by this node payload += shared.encodeHost(HOST) payload += pack('>H', PORT) # remote port payload = encodeVarint(numberOfAddressesInAddrMessage) + payload self.sendDataThreadQueue.put((0, 'sendRawData', shared.CreatePacket('addr', payload)))
def recversion(self, data): if len(data) < 83: # This version message is unreasonably short. Forget it. return if self.verackSent: """ We must have already processed the remote node's version message. There might be a time in the future when we Do want to process a new version message, like if the remote node wants to update the streams in which they are interested. But for now we'll ignore this version message """ return self.remoteProtocolVersion, = unpack('>L', data[:4]) self.services, = unpack('>q', data[4:12]) if self.remoteProtocolVersion < 3: self.sendDataThreadQueue.put((0, 'shutdown','no data')) logger.debug ('Closing connection to old protocol version ' + str(self.remoteProtocolVersion) + ' node: ' + str(self.peer)) return timestamp, = unpack('>Q', data[12:20]) timeOffset = timestamp - int(time.time()) if timeOffset > 3600: self.sendDataThreadQueue.put((0, 'sendRawData', shared.assembleErrorMessage(fatal=2, errorText="Your time is too far in the future compared to mine. Closing connection."))) logger.info("%s's time is too far in the future (%s seconds). Closing connection to it." % (self.peer, timeOffset)) time.sleep(2) self.sendDataThreadQueue.put((0, 'shutdown','no data')) return if timeOffset < -3600: self.sendDataThreadQueue.put((0, 'sendRawData', shared.assembleErrorMessage(fatal=2, errorText="Your time is too far in the past compared to mine. Closing connection."))) logger.info("%s's time is too far in the past (timeOffset %s seconds). Closing connection to it." % (self.peer, timeOffset)) time.sleep(2) self.sendDataThreadQueue.put((0, 'shutdown','no data')) return self.myExternalIP = socket.inet_ntoa(data[40:44]) # print 'myExternalIP', self.myExternalIP self.remoteNodeIncomingPort, = unpack('>H', data[70:72]) # print 'remoteNodeIncomingPort', self.remoteNodeIncomingPort useragentLength, lengthOfUseragentVarint = decodeVarint( data[80:84]) readPosition = 80 + lengthOfUseragentVarint useragent = data[readPosition:readPosition + useragentLength] # version check try: userAgentName, userAgentVersion = useragent[1:-1].split(":", 2) except: userAgentName = useragent userAgentVersion = "0.0.0" if userAgentName == "PyBitmessage": myVersion = [int(n) for n in shared.softwareVersion.split(".")] try: remoteVersion = [int(n) for n in userAgentVersion.split(".")] except: remoteVersion = 0 # remote is newer, but do not cross between stable and unstable try: if cmp(remoteVersion, myVersion) > 0 and \ (myVersion[1] % 2 == remoteVersion[1] % 2): shared.UISignalQueue.put(('newVersionAvailable', remoteVersion)) except: pass readPosition += useragentLength numberOfStreamsInVersionMessage, lengthOfNumberOfStreamsInVersionMessage = decodeVarint( data[readPosition:]) readPosition += lengthOfNumberOfStreamsInVersionMessage self.streamNumber, lengthOfRemoteStreamNumber = decodeVarint( data[readPosition:]) logger.debug('Remote node useragent: ' + useragent + ' stream number:' + str(self.streamNumber) + ' time offset: ' + str(timeOffset) + ' seconds.') if self.streamNumber != 1: self.sendDataThreadQueue.put((0, 'shutdown','no data')) logger.debug ('Closed connection to ' + str(self.peer) + ' because they are interested in stream ' + str(self.streamNumber) + '.') return shared.connectedHostsList[ self.peer.host] = 1 # We use this data structure to not only keep track of what hosts we are connected to so that we don't try to connect to them again, but also to list the connections count on the Network Status tab. # If this was an incoming connection, then the sendDataThread # doesn't know the stream. We have to set it. if not self.initiatedConnection: self.sendDataThreadQueue.put((0, 'setStreamNumber', self.streamNumber)) if data[72:80] == shared.eightBytesOfRandomDataUsedToDetectConnectionsToSelf: self.sendDataThreadQueue.put((0, 'shutdown','no data')) logger.debug('Closing connection to myself: ' + str(self.peer)) return # The other peer's protocol version is of interest to the sendDataThread but we learn of it # in this version message. Let us inform the sendDataThread. self.sendDataThreadQueue.put((0, 'setRemoteProtocolVersion', self.remoteProtocolVersion)) if not isHostInPrivateIPRange(self.peer.host): with shared.knownNodesLock: shared.knownNodes[self.streamNumber][shared.Peer(self.peer.host, self.remoteNodeIncomingPort)] = int(time.time()) if not self.initiatedConnection: shared.knownNodes[self.streamNumber][shared.Peer(self.peer.host, self.remoteNodeIncomingPort)] -= 162000 # penalise inbound, 2 days minus 3 hours shared.needToWriteKnownNodesToDisk = True self.sendverack() if self.initiatedConnection == False: self.sendversion()
def recaddr(self, data): #listOfAddressDetailsToBroadcastToPeers = [] numberOfAddressesIncluded = 0 numberOfAddressesIncluded, lengthOfNumberOfAddresses = decodeVarint( data[:10]) if shared.verbose >= 1: with shared.printLock: print 'addr message contains', numberOfAddressesIncluded, 'IP addresses.' if numberOfAddressesIncluded > 1000 or numberOfAddressesIncluded == 0: return if len(data) != lengthOfNumberOfAddresses + (38 * numberOfAddressesIncluded): print 'addr message does not contain the correct amount of data. Ignoring.' return for i in range(0, numberOfAddressesIncluded): try: if data[20 + lengthOfNumberOfAddresses + (38 * i):32 + lengthOfNumberOfAddresses + (38 * i)] != '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': with shared.printLock: print 'Skipping IPv6 address.', repr(data[20 + lengthOfNumberOfAddresses + (38 * i):32 + lengthOfNumberOfAddresses + (38 * i)]) continue except Exception as err: with shared.printLock: sys.stderr.write( 'ERROR TRYING TO UNPACK recaddr (to test for an IPv6 address). Message: %s\n' % str(err)) break # giving up on unpacking any more. We should still be connected however. try: recaddrStream, = unpack('>I', data[8 + lengthOfNumberOfAddresses + ( 38 * i):12 + lengthOfNumberOfAddresses + (38 * i)]) except Exception as err: with shared.printLock: sys.stderr.write( 'ERROR TRYING TO UNPACK recaddr (recaddrStream). Message: %s\n' % str(err)) break # giving up on unpacking any more. We should still be connected however. if recaddrStream == 0: continue if recaddrStream != self.streamNumber and recaddrStream != (self.streamNumber * 2) and recaddrStream != ((self.streamNumber * 2) + 1): # if the embedded stream number is not in my stream or either of my child streams then ignore it. Someone might be trying funny business. continue try: recaddrServices, = unpack('>Q', data[12 + lengthOfNumberOfAddresses + ( 38 * i):20 + lengthOfNumberOfAddresses + (38 * i)]) except Exception as err: with shared.printLock: sys.stderr.write( 'ERROR TRYING TO UNPACK recaddr (recaddrServices). Message: %s\n' % str(err)) break # giving up on unpacking any more. We should still be connected however. try: recaddrPort, = unpack('>H', data[36 + lengthOfNumberOfAddresses + ( 38 * i):38 + lengthOfNumberOfAddresses + (38 * i)]) except Exception as err: with shared.printLock: sys.stderr.write( 'ERROR TRYING TO UNPACK recaddr (recaddrPort). Message: %s\n' % str(err)) break # giving up on unpacking any more. We should still be connected however. # print 'Within recaddr(): IP', recaddrIP, ', Port', # recaddrPort, ', i', i hostFromAddrMessage = socket.inet_ntoa(data[ 32 + lengthOfNumberOfAddresses + (38 * i):36 + lengthOfNumberOfAddresses + (38 * i)]) # print 'hostFromAddrMessage', hostFromAddrMessage if data[32 + lengthOfNumberOfAddresses + (38 * i)] == '\x7F': print 'Ignoring IP address in loopback range:', hostFromAddrMessage continue if data[32 + lengthOfNumberOfAddresses + (38 * i)] == '\x0A': print 'Ignoring IP address in private range:', hostFromAddrMessage continue if data[32 + lengthOfNumberOfAddresses + (38 * i):34 + lengthOfNumberOfAddresses + (38 * i)] == '\xC0A8': print 'Ignoring IP address in private range:', hostFromAddrMessage continue timeSomeoneElseReceivedMessageFromThisNode, = unpack('>Q', data[lengthOfNumberOfAddresses + ( 38 * i):8 + lengthOfNumberOfAddresses + (38 * i)]) # This is the 'time' value in the received addr message. 64-bit. if recaddrStream not in shared.knownNodes: # knownNodes is a dictionary of dictionaries with one outer dictionary for each stream. If the outer stream dictionary doesn't exist yet then we must make it. shared.knownNodesLock.acquire() shared.knownNodes[recaddrStream] = {} shared.knownNodesLock.release() peerFromAddrMessage = shared.Peer(hostFromAddrMessage, recaddrPort) if peerFromAddrMessage not in shared.knownNodes[recaddrStream]: if len(shared.knownNodes[recaddrStream]) < 20000 and timeSomeoneElseReceivedMessageFromThisNode > (int(time.time()) - 10800) and timeSomeoneElseReceivedMessageFromThisNode < (int(time.time()) + 10800): # If we have more than 20000 nodes in our list already then just forget about adding more. Also, make sure that the time that someone else received a message from this node is within three hours from now. shared.knownNodesLock.acquire() shared.knownNodes[recaddrStream][peerFromAddrMessage] = ( timeSomeoneElseReceivedMessageFromThisNode) shared.knownNodesLock.release() with shared.printLock: print 'added new node', peerFromAddrMessage, 'to knownNodes in stream', recaddrStream shared.needToWriteKnownNodesToDisk = True hostDetails = ( timeSomeoneElseReceivedMessageFromThisNode, recaddrStream, recaddrServices, hostFromAddrMessage, recaddrPort) #listOfAddressDetailsToBroadcastToPeers.append(hostDetails) shared.broadcastToSendDataQueues(( self.streamNumber, 'advertisepeer', hostDetails)) else: timeLastReceivedMessageFromThisNode = shared.knownNodes[recaddrStream][ peerFromAddrMessage] # PORT in this case is either the port we used to connect to the remote node, or the port that was specified by someone else in a past addr message. if (timeLastReceivedMessageFromThisNode < timeSomeoneElseReceivedMessageFromThisNode) and (timeSomeoneElseReceivedMessageFromThisNode < int(time.time())): shared.knownNodesLock.acquire() shared.knownNodes[recaddrStream][peerFromAddrMessage] = timeSomeoneElseReceivedMessageFromThisNode shared.knownNodesLock.release() #if listOfAddressDetailsToBroadcastToPeers != []: # self.broadcastaddr(listOfAddressDetailsToBroadcastToPeers) with shared.printLock: print 'knownNodes currently has', len(shared.knownNodes[self.streamNumber]), 'nodes for this stream.'
def recversion(self, data): if len(data) < 83: # This version message is unreasonably short. Forget it. return if self.verackSent: """ We must have already processed the remote node's version message. There might be a time in the future when we Do want to process a new version message, like if the remote node wants to update the streams in which they are interested. But for now we'll ignore this version message """ return self.remoteProtocolVersion, = unpack('>L', data[:4]) if self.remoteProtocolVersion < 3: self.sendDataThreadQueue.put((0, 'shutdown','no data')) with shared.printLock: print 'Closing connection to old protocol version', self.remoteProtocolVersion, 'node: ', self.peer return timestamp, = unpack('>Q', data[12:20]) timeOffset = timestamp - int(time.time()) if timeOffset > 3600: self.sendDataThreadQueue.put((0, 'sendRawData', shared.assembleErrorMessage(fatal=2, errorText="Your time is too far in the future compared to mine. Closing connection."))) logger.info("%s's time is too far in the future (%s seconds). Closing connection to it." % (self.peer, timeOffset)) time.sleep(2) self.sendDataThreadQueue.put((0, 'shutdown','no data')) return if timeOffset < -3600: self.sendDataThreadQueue.put((0, 'sendRawData', shared.assembleErrorMessage(fatal=2, errorText="Your time is too far in the past compared to mine. Closing connection."))) logger.info("%s's time is too far in the past (timeOffset %s seconds). Closing connection to it." % (self.peer, timeOffset)) time.sleep(2) self.sendDataThreadQueue.put((0, 'shutdown','no data')) return self.myExternalIP = socket.inet_ntoa(data[40:44]) # print 'myExternalIP', self.myExternalIP self.remoteNodeIncomingPort, = unpack('>H', data[70:72]) # print 'remoteNodeIncomingPort', self.remoteNodeIncomingPort useragentLength, lengthOfUseragentVarint = decodeVarint( data[80:84]) readPosition = 80 + lengthOfUseragentVarint useragent = data[readPosition:readPosition + useragentLength] readPosition += useragentLength numberOfStreamsInVersionMessage, lengthOfNumberOfStreamsInVersionMessage = decodeVarint( data[readPosition:]) readPosition += lengthOfNumberOfStreamsInVersionMessage self.streamNumber, lengthOfRemoteStreamNumber = decodeVarint( data[readPosition:]) with shared.printLock: print 'Remote node useragent:', useragent, ' stream number:', self.streamNumber, ' time offset:', timeOffset, 'seconds.' if self.streamNumber != 1: self.sendDataThreadQueue.put((0, 'shutdown','no data')) with shared.printLock: print 'Closed connection to', self.peer, 'because they are interested in stream', self.streamNumber, '.' return shared.connectedHostsList[ self.peer.host] = 1 # We use this data structure to not only keep track of what hosts we are connected to so that we don't try to connect to them again, but also to list the connections count on the Network Status tab. # If this was an incoming connection, then the sendDataThread # doesn't know the stream. We have to set it. if not self.initiatedConnection: self.sendDataThreadQueue.put((0, 'setStreamNumber', self.streamNumber)) if data[72:80] == shared.eightBytesOfRandomDataUsedToDetectConnectionsToSelf: self.sendDataThreadQueue.put((0, 'shutdown','no data')) with shared.printLock: print 'Closing connection to myself: ', self.peer return # The other peer's protocol version is of interest to the sendDataThread but we learn of it # in this version message. Let us inform the sendDataThread. self.sendDataThreadQueue.put((0, 'setRemoteProtocolVersion', self.remoteProtocolVersion)) shared.knownNodesLock.acquire() shared.knownNodes[self.streamNumber][shared.Peer(self.peer.host, self.remoteNodeIncomingPort)] = int(time.time()) shared.needToWriteKnownNodesToDisk = True shared.knownNodesLock.release() self.sendverack() if self.initiatedConnection == False: self.sendversion()
def createDefaultKnownNodes(appdata): ############## Stream 1 ################ stream1 = {} stream1[shared.Peer('98.233.84.134', 8444)] = int(time.time()) stream1[shared.Peer('76.24.18.44', 8444)] = int(time.time()) stream1[shared.Peer('176.31.246.114', 8444)] = int(time.time()) stream1[shared.Peer('66.108.210.240', 8080)] = int(time.time()) stream1[shared.Peer('76.22.240.163', 8445)] = int(time.time()) stream1[shared.Peer('46.21.99.29', 20982)] = int(time.time()) stream1[shared.Peer('109.227.72.36', 8444)] = int(time.time()) stream1[shared.Peer('176.31.246.114', 8444)] = int(time.time()) stream1[shared.Peer('188.110.3.133', 8444)] = int(time.time()) stream1[shared.Peer('174.0.45.163', 8444)] = int(time.time()) stream1[shared.Peer('134.2.182.92', 8444)] = int(time.time()) stream1[shared.Peer('24.143.60.183', 8444)] = int(time.time()) ############# Stream 2 ################# stream2 = {} # None yet ############# Stream 3 ################# stream3 = {} # None yet allKnownNodes = {} allKnownNodes[1] = stream1 allKnownNodes[2] = stream2 allKnownNodes[3] = stream3 #print stream1 #print allKnownNodes with open(appdata + 'knownnodes.dat', 'wb') as output: # Pickle dictionary using protocol 0. pickle.dump(allKnownNodes, output) return allKnownNodes