self.label_3.setText(QtGui.QApplication.translate("aboutDialog","Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php",None,QtGui.QApplication.UnicodeUTF8))
self.label_4.setText(QtGui.QApplication.translate("aboutDialog","This product includes Python-RSA (http://stuvel.eu/rsa) originally written by Sybren A. Stüvel <sybren@stuvel.eu>. It is licensed under the Apache 2.0 license: http://www.apache.org/licenses/LICENSE-2.0",None,QtGui.QApplication.UnicodeUTF8))
self.label_3.setText(QtGui.QApplication.translate("aboutDialog","<html><head/><body><p>Distributed under the MIT/X11 software license, see the accompanying file license.txt or <a href=\"http://www.opensource.org/licenses/mit-license.php\"><span style=\" text-decoration: underline; color:#0000ff;\">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html>",None,QtGui.QApplication.UnicodeUTF8))
self.label_5.setText(QtGui.QApplication.translate("aboutDialog","This is Beta software.",None,QtGui.QApplication.UnicodeUTF8))
<string>Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>20</x>
<y>280</y>
<width>331</width>
<height>81</height>
</rect>
</property>
<property name="text">
<string>This product includes Python-RSA (http://stuvel.eu/rsa) originally written by Sybren A. Stüvel <sybren@stuvel.eu>. It is licensed under the Apache 2.0 license: http://www.apache.org/licenses/LICENSE-2.0</string>
<string><html><head/><body><p>Distributed under the MIT/X11 software license, see the accompanying file license.txt or <a href="http://www.opensource.org/licenses/mit-license.php"><span style=" text-decoration: underline; color:#0000ff;">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html></string>
if(int(time.time())-timeLastSeen)>172800andlen(knownNodes[self.streamNumber])>1000:# for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the knownNodes data-structure.
delknownNodes[self.streamNumber][HOST]
@ -156,7 +158,9 @@ class outgoingSynSender(QThread):
print'Bitmessage MIGHT be having trouble connecting to the SOCKS server. '+str(err)
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"Problem: Bitmessage can not connect to the SOCKS server. "+str(err))
else:
printLock.acquire()
print'Could NOT connect to',HOST,'during outgoing attempt.',err
if(int(time.time())-timeLastSeen)>172800andlen(knownNodes[self.streamNumber])>1000:# for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the knownNodes data-structure.
delknownNodes[self.streamNumber][HOST]
@ -188,11 +192,11 @@ class singleListener(QThread):
whileTrue:
#We don't want to accept incoming connections if the user is using a SOCKS proxy. If they eventually select proxy 'none' then this will start listening for connections.
#We don't want to accept incoming connections if the user is using a SOCKS proxy. If the user eventually select proxy 'none' then this will start listening for connections.
#Users are finding that if they run more than one node in the same network (thus with the same public IP), they can not connect with the second node. This is because this section of code won't accept the connection from the same IP. This problem will go away when the Bitmessage network grows behond being tiny but in the mean time, I'll comment out this code section.
#Users are finding that if they run more than one node in the same network (thus with the same public IP), they can not connect with the second node. This is because this section of code won't accept the connection from the same IP. This problem will go away when the Bitmessage network grows beyond being tiny but in the mean time I'll comment out this code section.
"""while HOST in connectedHostsList:
print'incoming connection is from a host in connectedHostsList (we are already connected to it). Ignoring it.'
a.close()
@ -226,10 +230,10 @@ class receiveDataThread(QThread):
self.payloadLength=0#This is the protocol payload length thus it doesn't include the 24 byte message header
self.receivedgetbiginv=False#Gets set to true once we receive a getbiginv message from our peer. An abusive peer might request it too much so we use this variable to check whether they have already asked for a big inv message.
self.objectsThatWeHaveYetToGet={}
connectedHostsList[self.HOST]=0
connectedHostsList[self.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 the 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.
ifself.streamNumber==-1:#This was an incoming connection. Send out a version message if we accept the other node's version message.
self.initiatedConnection=False
@ -245,7 +249,7 @@ class receiveDataThread(QThread):
self.data=self.data+self.sock.recv(65536)
exceptsocket.timeout:
printLock.acquire()
print'Timeout occurred waiting for data. Closing thread.'
print'Timeout occurred waiting for data. Closing receiveData thread.'
printLock.release()
break
exceptException,err:
@ -256,7 +260,7 @@ class receiveDataThread(QThread):
ifself.connectionIsOrWasFullyEstablished:#We don't want to decrement the number of connections and show the result if we never incremented it in the first place (which we only do if the connection is fully established- meaning that both nodes accepted each other's version packets.)
print'Inventory (in memory) already has object listed in inv message.'
printLock.release()
delself.objectsThatWeHaveYetToGet[objectHash]
elifisInSqlInventory(objectHash):
printLock.acquire()
print'Inventory (SQL on disk) already has object listed in inv message.'
printLock.release()
delself.objectsThatWeHaveYetToGet[objectHash]
else:
print'processData function making request for object:',objectHash.encode('hex')
#print 'processData function making request for object:', objectHash.encode('hex')
self.sendgetdata(objectHash)
delself.objectsThatWeHaveYetToGet[objectHash]#It is possible that the remote node doesn't respond with the object. In that case, we'll very likely get it from someone else anyway.
break
@ -402,9 +415,11 @@ class receiveDataThread(QThread):
print'broadcasting addr from within connectionFullyEstablished function.'
printLock.release()
self.broadcastaddr([(int(time.time()),self.streamNumber,1,self.HOST,remoteNodeIncomingPort)])#This lets all of our peers know about this new node.
self.sendaddr()#This is one addr message to this one peer.
self.sendaddr()#This is one large addr message to this one peer.
ifconnectionsCount[self.streamNumber]>150:
printLock.acquire()
print'We are connected to too many people. Closing connection.'
printLock.release()
self.sock.close()
return
self.sendBigInv()
@ -427,18 +442,19 @@ class receiveDataThread(QThread):
forrowinqueryreturn:
hash,=row
bigInvList[hash]=0
#print 'bigInvList:', bigInvList
#We also have messages in our inventory in memory (which is a python dictionary). Let's fetch those too.
#Now let us start appending all of these hashes together. They will be sent out in a big inv message to our new peer.
forhash,storedValueinbigInvList.items():
payload+=hash
numberOfObjectsInInvMessage+=1
ifnumberOfObjectsInInvMessage>=50000:#We can only send a max of 50000 items per inv message but we may have more objects to advertise. They must be split up into multiple inv messages.
print'The stream number encoded in this msg ('+streamNumberAsClaimedByMsg+') message does not match the stream number on which it was received. Ignoring it.'
@ -632,7 +646,7 @@ class receiveDataThread(QThread):
sqlReturnQueue.get()
sqlLock.release()
self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),self.data[readPosition:24+self.payloadLength],'Acknowledgement of the message received just now.')
flushInventory()#so that we won't accidentially receive this message twice if the user restarts Bitmessage soon.
flushInventory()#so that we won't accidentially receive this message twice if the user restarts Bitmessage both soon and un-cleanly.
return
else:
printLock.acquire()
@ -806,18 +820,12 @@ class receiveDataThread(QThread):
#print 'The POW is strong enough that this ackdataPayload will be accepted by the Bitmessage network.'
#Currently PyBitmessage only supports sending a message with the acknowledgement in the form of a msg message. But future versions, and other clients, could send any object and this software will relay them. This can be used to relay identifying information, like your public key, through another Bitmessage host in case you believe that your Internet connection is being individually watched. You may pick a random address, hope its owner is online, and send a message with encoding type 0 so that they ignore the message but send your acknowledgement data over the network. If you send and receive many messages, it would also be clever to take someone else's acknowledgement data and use it for your own. Assuming that your message is delivered successfully, both will be acknowledged simultaneously (though if it is not delivered successfully, you will be in a pickle.)
#print 'self.data before:', repr(self.data)
#We'll need to make sure that our client will properly process the ackData; if the packet is malformed, we could clear out self.data and an attacker could use that behavior to determine that we were capable of decoding this message.
#Now let's send the acknowledgement. We'll need to make sure that our client will properly process the ackData; if the packet is malformed, we could clear out self.data and an attacker could use that behavior to determine that we were capable of decoding this message.
ackDataValidThusFar=True
iflen(ackData)<24:
print'The length of ackData is unreasonably short. Not sending ackData.'
ackDataValidThusFar=False
if ackData[0:4]!='\xe9\xbe\xb4\xd9':
elifackData[0:4]!='\xe9\xbe\xb4\xd9':
print'Ackdata magic bytes were wrong. Not sending ackData.'
ackDataValidThusFar=False
ifackDataValidThusFar:
@ -1234,7 +1242,7 @@ class receiveDataThread(QThread):
#print 'queryreturn', queryreturn
ifqueryreturn==[]:
print'pubkey request is for me but the pubkey is not in our database of pubkeys. Making it.'
payload=pack('>I',(int(time.time())))#todo: fuzz this time
payload=pack('>I',(int(time.time())+random.randrange(-300,300)))#the current time plus or minus five minutes
payload+=encodeVarint(2)#Address version number
payload+=encodeVarint(streamNumber)
payload+='\x00\x00\x00\x01'#bitfield of features supported by me (see the wiki).
@ -1326,7 +1334,6 @@ class receiveDataThread(QThread):
print'(For pubkey message) Found proof of work',trialValue,'Nonce:',nonce
payload=pack('>Q',nonce)+payload
@ -1360,6 +1367,9 @@ class receiveDataThread(QThread):
self.broadcastinv(inventoryHash)
else:
#This section hasn't been tested yet. Criteria for success: Alice sends Bob a message. Three days later, Charlie who is completely new to Bitmessage runs the client for the first time then sends a message to Bob and accomplishes this without Bob having to redo the POW for a pubkey message.
print'Hash in getpubkey request is not for any of my keys.'
#..but lets see if we have it stored from when it came in from someone else.