def run(self):
        with shared.printLock:
            print 'sendDataThread starting. ID:', str(
                id(self)) + '. Number of queues in sendDataQueues:', len(
                    shared.sendDataQueues)
        while True:
            deststream, command, data = self.sendDataThreadQueue.get()

            if deststream == self.streamNumber or deststream == 0:
                if command == 'shutdown':
                    with shared.printLock:
                        print 'sendDataThread (associated with', self.peer, ') ID:', 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
                    with shared.printLock:
                        print 'setting the stream number in the sendData thread (ID:', id(
                            self), ') to', self.streamNumber
                elif command == 'setRemoteProtocolVersion':
                    specifiedRemoteProtocolVersion = data
                    with shared.printLock:
                        print 'setting the remote node\'s protocol version in the sendDataThread (ID:', id(
                            self), ') to', 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 += shared.encodeHost(host)
                            payload += pack('>H', port)

                        payload = encodeVarint(
                            numberOfAddressesInAddrMessage) + payload
                        packet = shared.CreatePacket('addr', payload)
                        try:
                            self.sendBytes(packet)
                        except:
                            with shared.printLock:
                                print '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:
                            if hash not in self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware:
                                payload += hash
                        if payload != '':
                            payload = encodeVarint(len(payload) / 32) + payload
                            packet = shared.CreatePacket('inv', payload)
                            try:
                                self.sendBytes(packet)
                            except:
                                with shared.printLock:
                                    print 'sendinv: self.sock.sendall failed'
                                break
                elif command == 'pong':
                    self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware.clear(
                    )  # To save memory, let us clear this data structure from time to time. As its function is to help us keep from sending inv messages to peers which sent us the same inv message mere seconds earlier, it will be fine to clear this data structure from time to time.
                    if self.lastTimeISentData < (int(time.time()) - 298):
                        # Send out a pong message to keep the connection alive.
                        with shared.printLock:
                            print 'Sending pong to', self.peer, 'to keep connection alive.'
                        packet = shared.CreatePacket('pong')
                        try:
                            self.sendBytes(packet)
                        except:
                            with shared.printLock:
                                print 'send pong failed'
                            break
                elif command == 'sendRawData':
                    try:
                        self.sendBytes(data)
                    except:
                        with shared.printLock:
                            print 'Sending of data to', self.peer, 'failed. sendDataThread thread', self, 'ending now.'
                        break
                elif command == 'connectionIsOrWasFullyEstablished':
                    self.connectionIsOrWasFullyEstablished = True
                    self.services, self.sslSock = data
            else:
                with shared.printLock:
                    print 'sendDataThread ID:', id(
                        self
                    ), 'ignoring command', command, 'because the thread is not in stream', deststream

        try:
            self.sock.shutdown(socket.SHUT_RDWR)
            self.sock.close()
        except:
            pass
        shared.sendDataQueues.remove(self.sendDataThreadQueue)
        with shared.printLock:
            print 'sendDataThread ending. ID:', str(
                id(self)) + '. Number of queues in sendDataQueues:', len(
                    shared.sendDataQueues)
        self.objectHashHolderInstance.close()
    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.
        shared.knownNodesLock.acquire()
        if len(shared.knownNodes[self.streamNumber]) > 0:
            for i in range(500):
                peer, = random.sample(shared.knownNodes[self.streamNumber], 1)
                if isHostInPrivateIPRange(peer.host):
                    continue
                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]
        shared.knownNodesLock.release()
        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 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.
        shared.knownNodesLock.acquire()
        if len(shared.knownNodes[self.streamNumber]) > 0:
            for i in range(500):
                peer, = random.sample(shared.knownNodes[self.streamNumber], 1)
                if isHostInPrivateIPRange(peer.host):
                    continue
                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]
        shared.knownNodesLock.release()
        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 run(self):
        while True:
            deststream, command, data = self.sendDataThreadQueue.get()

            if deststream == self.streamNumber or deststream == 0:
                if command == 'shutdown':
                    if data == self.peer or data == 'all':
                        with shared.printLock:
                            print 'sendDataThread (associated with', self.peer, ') ID:', 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
                    with shared.printLock:
                        print 'setting the stream number in the sendData thread (ID:', id(self), ') to', self.streamNumber 
                elif command == 'setRemoteProtocolVersion':
                    specifiedRemoteProtocolVersion = data
                    with shared.printLock:
                        print 'setting the remote node\'s protocol version in the sendDataThread (ID:', id(self), ') to', specifiedRemoteProtocolVersion
                    self.remoteProtocolVersion = specifiedRemoteProtocolVersion
                elif command == 'advertisepeer':
                    self.objectHashHolderInstance.holdPeer(data)
                elif command == 'sendaddr':
                    if not self.connectionIsOrWasFullyEstablished:
                        # not sending addr because we haven't sent and heard a verack from the remote node yet
                        return
                    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 += shared.encodeHost(host)
                        payload += pack('>H', port)

                    payload = encodeVarint(numberOfAddressesInAddrMessage) + payload
                    datatosend = '\xE9\xBE\xB4\xD9addr\x00\x00\x00\x00\x00\x00\x00\x00'
                    datatosend = datatosend + pack('>L', len(payload))  # payload length
                    datatosend = datatosend + hashlib.sha512(payload).digest()[0:4]
                    datatosend = datatosend + payload

                    try:
                        self.sock.sendall(datatosend)
                        self.lastTimeISentData = int(time.time())
                    except:
                        print 'sendaddr: self.sock.sendall failed'
                        break
                elif command == 'advertiseobject':
                    self.objectHashHolderInstance.holdHash(data)
                elif command == 'sendinv':
                    if not self.connectionIsOrWasFullyEstablished:
                        # not sending inv because we haven't sent and heard a verack from the remote node yet
                        return
                    payload = ''
                    for hash in data:
                        if hash not in self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware:
                            payload += hash
                    if payload != '':
                        payload = encodeVarint(len(payload)/32) + payload
                        headerData = '\xe9\xbe\xb4\xd9'  # magic bits, slighly different from Bitcoin's magic bits.
                        headerData += 'inv\x00\x00\x00\x00\x00\x00\x00\x00\x00'
                        headerData += pack('>L', len(payload))
                        headerData += hashlib.sha512(payload).digest()[:4]
                        try:
                            self.sock.sendall(headerData + payload)
                            self.lastTimeISentData = int(time.time())
                        except:
                            print 'sendinv: self.sock.sendall failed'
                            break
                elif command == 'pong':
                    self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware.clear() # To save memory, let us clear this data structure from time to time. As its function is to help us keep from sending inv messages to peers which sent us the same inv message mere seconds earlier, it will be fine to clear this data structure from time to time.
                    if self.lastTimeISentData < (int(time.time()) - 298):
                        # Send out a pong message to keep the connection alive.
                        with shared.printLock:
                            print 'Sending pong to', self.peer, 'to keep connection alive.'

                        try:
                            self.sock.sendall(
                                '\xE9\xBE\xB4\xD9\x70\x6F\x6E\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\x83\xe1\x35')
                            self.lastTimeISentData = int(time.time())
                        except:
                            print 'send pong failed'
                            break
                elif command == 'sendRawData':
                    try:
                        self.sock.sendall(data)
                        self.lastTimeISentData = int(time.time())
                    except:
                        print 'Sending of data to', self.peer, 'failed. sendDataThread thread', self, 'ending now.' 
                        break
                elif command == 'connectionIsOrWasFullyEstablished':
                    self.connectionIsOrWasFullyEstablished = True
            else:
                with shared.printLock:
                    print 'sendDataThread ID:', id(self), 'ignoring command', command, 'because the thread is not in stream', deststream

        try:
            self.sock.shutdown(socket.SHUT_RDWR)
            self.sock.close()
        except:
            pass
        shared.sendDataQueues.remove(self.sendDataThreadQueue)
        with shared.printLock:
            print 'Number of queues remaining in sendDataQueues:', len(shared.sendDataQueues)
        self.objectHashHolderInstance.close()
    def run(self):
        with shared.printLock:
            print 'sendDataThread starting. ID:', str(id(self))+'. Number of queues in sendDataQueues:', len(shared.sendDataQueues)
        while True:
            deststream, command, data = self.sendDataThreadQueue.get()

            if deststream == self.streamNumber or deststream == 0:
                if command == 'shutdown':
                    with shared.printLock:
                        print 'sendDataThread (associated with', self.peer, ') ID:', 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
                    with shared.printLock:
                        print 'setting the stream number in the sendData thread (ID:', id(self), ') to', self.streamNumber 
                elif command == 'setRemoteProtocolVersion':
                    specifiedRemoteProtocolVersion = data
                    with shared.printLock:
                        print 'setting the remote node\'s protocol version in the sendDataThread (ID:', id(self), ') to', 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 += shared.encodeHost(host)
                            payload += pack('>H', port)
    
                        payload = encodeVarint(numberOfAddressesInAddrMessage) + payload
                        packet = shared.CreatePacket('addr', payload)
                        try:
                            self.sendBytes(packet)
                        except:
                            with shared.printLock:
                                print '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:
                            if hash not in self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware:
                                payload += hash
                        if payload != '':
                            payload = encodeVarint(len(payload)/32) + payload
                            packet = shared.CreatePacket('inv', payload)
                            try:
                                self.sendBytes(packet)
                            except:
                                with shared.printLock:
                                    print 'sendinv: self.sock.sendall failed'
                                break
                elif command == 'pong':
                    self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware.clear() # To save memory, let us clear this data structure from time to time. As its function is to help us keep from sending inv messages to peers which sent us the same inv message mere seconds earlier, it will be fine to clear this data structure from time to time.
                    if self.lastTimeISentData < (int(time.time()) - 298):
                        # Send out a pong message to keep the connection alive.
                        with shared.printLock:
                            print 'Sending pong to', self.peer, 'to keep connection alive.'
                        packet = shared.CreatePacket('pong')
                        try:
                            self.sendBytes(packet)
                        except:
                            with shared.printLock:
                                print 'send pong failed'
                            break
                elif command == 'sendRawData':
                    try:
                        self.sendBytes(data)
                    except:
                        with shared.printLock:
                            print 'Sending of data to', self.peer, 'failed. sendDataThread thread', self, 'ending now.' 
                        break
                elif command == 'connectionIsOrWasFullyEstablished':
                    self.connectionIsOrWasFullyEstablished = True
                    self.services, self.sslSock = data
            else:
                with shared.printLock:
                    print 'sendDataThread ID:', id(self), 'ignoring command', command, 'because the thread is not in stream', deststream

        try:
            self.sock.shutdown(socket.SHUT_RDWR)
            self.sock.close()
        except:
            pass
        shared.sendDataQueues.remove(self.sendDataThreadQueue)
        with shared.printLock:
            print 'sendDataThread ending. ID:', str(id(self))+'. Number of queues in sendDataQueues:', len(shared.sendDataQueues)
        self.objectHashHolderInstance.close()
Example #6
0
    def run(self):
        while True:
            deststream, command, data = self.sendDataThreadQueue.get()

            if deststream == self.streamNumber or deststream == 0:
                if command == 'shutdown':
                    if data == self.peer or data == 'all':
                        with shared.printLock:
                            print 'sendDataThread (associated with', self.peer, ') ID:', 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
                    with shared.printLock:
                        print 'setting the stream number in the sendData thread (ID:', id(
                            self), ') to', self.streamNumber
                elif command == 'setRemoteProtocolVersion':
                    specifiedRemoteProtocolVersion = data
                    with shared.printLock:
                        print 'setting the remote node\'s protocol version in the sendDataThread (ID:', id(
                            self), ') to', specifiedRemoteProtocolVersion
                    self.remoteProtocolVersion = specifiedRemoteProtocolVersion
                elif command == 'advertisepeer':
                    self.objectHashHolderInstance.holdPeer(data)
                elif command == 'sendaddr':
                    if not self.connectionIsOrWasFullyEstablished:
                        # not sending addr because we haven't sent and heard a verack from the remote node yet
                        return
                    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 += shared.encodeHost(host)
                        payload += pack('>H', port)

                    payload = encodeVarint(
                        numberOfAddressesInAddrMessage) + payload
                    datatosend = '\xE9\xBE\xB4\xD9addr\x00\x00\x00\x00\x00\x00\x00\x00'
                    datatosend = datatosend + pack(
                        '>L', len(payload))  # payload length
                    datatosend = datatosend + hashlib.sha512(
                        payload).digest()[0:4]
                    datatosend = datatosend + payload

                    try:
                        self.sock.sendall(datatosend)
                        self.lastTimeISentData = int(time.time())
                    except:
                        print 'sendaddr: self.sock.sendall failed'
                        break
                elif command == 'advertiseobject':
                    self.objectHashHolderInstance.holdHash(data)
                elif command == 'sendinv':
                    if not self.connectionIsOrWasFullyEstablished:
                        # not sending inv because we haven't sent and heard a verack from the remote node yet
                        return
                    payload = ''
                    for hash in data:
                        if hash not in self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware:
                            payload += hash
                    if payload != '':
                        payload = encodeVarint(len(payload) / 32) + payload
                        headerData = '\xe9\xbe\xb4\xd9'  # magic bits, slighly different from Bitcoin's magic bits.
                        headerData += 'inv\x00\x00\x00\x00\x00\x00\x00\x00\x00'
                        headerData += pack('>L', len(payload))
                        headerData += hashlib.sha512(payload).digest()[:4]
                        try:
                            self.sock.sendall(headerData + payload)
                            self.lastTimeISentData = int(time.time())
                        except:
                            print 'sendinv: self.sock.sendall failed'
                            break
                elif command == 'pong':
                    self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware.clear(
                    )  # To save memory, let us clear this data structure from time to time. As its function is to help us keep from sending inv messages to peers which sent us the same inv message mere seconds earlier, it will be fine to clear this data structure from time to time.
                    if self.lastTimeISentData < (int(time.time()) - 298):
                        # Send out a pong message to keep the connection alive.
                        with shared.printLock:
                            print 'Sending pong to', self.peer, 'to keep connection alive.'

                        try:
                            self.sock.sendall(
                                '\xE9\xBE\xB4\xD9\x70\x6F\x6E\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\x83\xe1\x35'
                            )
                            self.lastTimeISentData = int(time.time())
                        except:
                            print 'send pong failed'
                            break
                elif command == 'sendRawData':
                    try:
                        self.sock.sendall(data)
                        self.lastTimeISentData = int(time.time())
                    except:
                        print 'Sending of data to', self.peer, 'failed. sendDataThread thread', self, 'ending now.'
                        break
                elif command == 'connectionIsOrWasFullyEstablished':
                    self.connectionIsOrWasFullyEstablished = True
            else:
                with shared.printLock:
                    print 'sendDataThread ID:', id(
                        self
                    ), 'ignoring command', command, 'because the thread is not in stream', deststream

        try:
            self.sock.shutdown(socket.SHUT_RDWR)
            self.sock.close()
        except:
            pass
        shared.sendDataQueues.remove(self.sendDataThreadQueue)
        with shared.printLock:
            print 'Number of queues remaining in sendDataQueues:', len(
                shared.sendDataQueues)
        self.objectHashHolderInstance.close()
    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 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.
        shared.knownNodesLock.acquire()
        if len(shared.knownNodes[self.streamNumber]) > 0:
            for i in range(500):
                peer, = random.sample(shared.knownNodes[self.streamNumber], 1)
                if helper_generic.isHostInPrivateIPRange(peer.host):
                    continue
                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 helper_generic.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 helper_generic.isHostInPrivateIPRange(peer.host):
                    continue
                addrsInChildStreamRight[peer] = shared.knownNodes[
                    (self.streamNumber * 2) + 1][peer]
        shared.knownNodesLock.release()
        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
        datatosend = '\xE9\xBE\xB4\xD9addr\x00\x00\x00\x00\x00\x00\x00\x00'
        datatosend = datatosend + pack('>L', len(payload))  # payload length
        datatosend = datatosend + hashlib.sha512(payload).digest()[0:4]
        datatosend = datatosend + payload
        self.sendDataThreadQueue.put((0, 'sendRawData', datatosend))