inv flooding attack mitigation
This commit is contained in:
parent
204f1fe52c
commit
3ee9b4ea6e
|
@ -303,6 +303,10 @@ class receiveDataThread(threading.Thread):
|
||||||
shared.printLock.acquire()
|
shared.printLock.acquire()
|
||||||
print 'Could not delete', self.HOST, 'from shared.connectedHostsList.', err
|
print 'Could not delete', self.HOST, 'from shared.connectedHostsList.', err
|
||||||
shared.printLock.release()
|
shared.printLock.release()
|
||||||
|
try:
|
||||||
|
del numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer[self.HOST]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
shared.UISignalQueue.put(('updateNetworkStatusTab','no data'))
|
shared.UISignalQueue.put(('updateNetworkStatusTab','no data'))
|
||||||
shared.printLock.acquire()
|
shared.printLock.acquire()
|
||||||
print 'The size of the connectedHostsList is now:', len(shared.connectedHostsList)
|
print 'The size of the connectedHostsList is now:', len(shared.connectedHostsList)
|
||||||
|
@ -386,15 +390,24 @@ class receiveDataThread(threading.Thread):
|
||||||
shared.printLock.acquire()
|
shared.printLock.acquire()
|
||||||
print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave)
|
print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave)
|
||||||
shared.printLock.release()
|
shared.printLock.release()
|
||||||
|
try:
|
||||||
|
del numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer[self.HOST]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
break
|
break
|
||||||
if len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) == 0:
|
if len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) == 0:
|
||||||
shared.printLock.acquire()
|
shared.printLock.acquire()
|
||||||
print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave)
|
print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave)
|
||||||
shared.printLock.release()
|
shared.printLock.release()
|
||||||
|
try:
|
||||||
|
del numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer[self.HOST]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
if len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) > 0:
|
if len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) > 0:
|
||||||
shared.printLock.acquire()
|
shared.printLock.acquire()
|
||||||
print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave)
|
print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave)
|
||||||
shared.printLock.release()
|
shared.printLock.release()
|
||||||
|
numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer[self.HOST] = len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave)
|
||||||
if len(self.ackDataThatWeHaveYetToSend) > 0:
|
if len(self.ackDataThatWeHaveYetToSend) > 0:
|
||||||
self.data = self.ackDataThatWeHaveYetToSend.pop()
|
self.data = self.ackDataThatWeHaveYetToSend.pop()
|
||||||
self.processData()
|
self.processData()
|
||||||
|
@ -1489,11 +1502,26 @@ class receiveDataThread(threading.Thread):
|
||||||
|
|
||||||
#We have received an inv message
|
#We have received an inv message
|
||||||
def recinv(self,data):
|
def recinv(self,data):
|
||||||
|
totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave = 0
|
||||||
|
print 'number of keys(hosts) in numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer:', len(numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer)
|
||||||
|
for key, value in numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer.items():
|
||||||
|
totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave += value
|
||||||
|
print 'totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave = ', totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave
|
||||||
|
"""if totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave > 200000:
|
||||||
|
shared.printLock.acquire()
|
||||||
|
print 'We already have', totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave, 'items yet to retrieve from peers. Ignoring this inv message.'
|
||||||
|
shared.printLock.release()
|
||||||
|
return"""
|
||||||
numberOfItemsInInv, lengthOfVarint = decodeVarint(data[:10])
|
numberOfItemsInInv, lengthOfVarint = decodeVarint(data[:10])
|
||||||
if len(data) < lengthOfVarint + (numberOfItemsInInv * 32):
|
if len(data) < lengthOfVarint + (numberOfItemsInInv * 32):
|
||||||
print 'inv message doesn\'t contain enough data. Ignoring.'
|
print 'inv message doesn\'t contain enough data. Ignoring.'
|
||||||
return
|
return
|
||||||
if numberOfItemsInInv == 1: #we'll just request this data from the person who advertised the object.
|
if numberOfItemsInInv == 1: #we'll just request this data from the person who advertised the object.
|
||||||
|
if totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave > 200000 and len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) > 1000:
|
||||||
|
shared.printLock.acquire()
|
||||||
|
print 'We already have', totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave, 'items yet to retrieve from peers and over 1000 from this node in particular. Ignoring this inv message.'
|
||||||
|
shared.printLock.release()
|
||||||
|
return
|
||||||
self.objectsOfWhichThisRemoteNodeIsAlreadyAware[data[lengthOfVarint:32+lengthOfVarint]] = 0
|
self.objectsOfWhichThisRemoteNodeIsAlreadyAware[data[lengthOfVarint:32+lengthOfVarint]] = 0
|
||||||
if data[lengthOfVarint:32+lengthOfVarint] in shared.inventory:
|
if data[lengthOfVarint:32+lengthOfVarint] in shared.inventory:
|
||||||
shared.printLock.acquire()
|
shared.printLock.acquire()
|
||||||
|
@ -1507,8 +1535,14 @@ class receiveDataThread(threading.Thread):
|
||||||
print 'inv message lists', numberOfItemsInInv, 'objects.'
|
print 'inv message lists', numberOfItemsInInv, 'objects.'
|
||||||
for i in range(numberOfItemsInInv): #upon finishing dealing with an incoming message, the receiveDataThread will request a random object from the peer. This way if we get multiple inv messages from multiple peers which list mostly the same objects, we will make getdata requests for different random objects from the various peers.
|
for i in range(numberOfItemsInInv): #upon finishing dealing with an incoming message, the receiveDataThread will request a random object from the peer. This way if we get multiple inv messages from multiple peers which list mostly the same objects, we will make getdata requests for different random objects from the various peers.
|
||||||
if len(data[lengthOfVarint+(32*i):32+lengthOfVarint+(32*i)]) == 32: #The length of an inventory hash should be 32. If it isn't 32 then the remote node is either badly programmed or behaving nefariously.
|
if len(data[lengthOfVarint+(32*i):32+lengthOfVarint+(32*i)]) == 32: #The length of an inventory hash should be 32. If it isn't 32 then the remote node is either badly programmed or behaving nefariously.
|
||||||
|
if totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave > 200000 and len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) > 1000:
|
||||||
|
shared.printLock.acquire()
|
||||||
|
print 'We already have', totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave, 'items yet to retrieve from peers and over',len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave),'from this node in particular. Ignoring the rest of this inv message.'
|
||||||
|
shared.printLock.release()
|
||||||
|
break
|
||||||
self.objectsOfWhichThisRemoteNodeIsAlreadyAware[data[lengthOfVarint+(32*i):32+lengthOfVarint+(32*i)]] = 0
|
self.objectsOfWhichThisRemoteNodeIsAlreadyAware[data[lengthOfVarint+(32*i):32+lengthOfVarint+(32*i)]] = 0
|
||||||
self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave[data[lengthOfVarint+(32*i):32+lengthOfVarint+(32*i)]] = 0
|
self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave[data[lengthOfVarint+(32*i):32+lengthOfVarint+(32*i)]] = 0
|
||||||
|
numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer[self.HOST] = len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave)
|
||||||
|
|
||||||
|
|
||||||
#Send a getdata message to our peer to request the object with the given hash
|
#Send a getdata message to our peer to request the object with the given hash
|
||||||
|
@ -2535,6 +2569,12 @@ class singleCleaner(threading.Thread):
|
||||||
shared.sqlSubmitQueue.put(t)
|
shared.sqlSubmitQueue.put(t)
|
||||||
queryreturn = shared.sqlReturnQueue.get()
|
queryreturn = shared.sqlReturnQueue.get()
|
||||||
for row in queryreturn:
|
for row in queryreturn:
|
||||||
|
if len(row) < 5:
|
||||||
|
shared.printLock.acquire()
|
||||||
|
sys.stderr.write('Something went wrong in the singleCleaner thread: a query did not return the requested fields. '+repr(row))
|
||||||
|
time.sleep(3)
|
||||||
|
shared.printLock.release()
|
||||||
|
break
|
||||||
toaddress, toripe, fromaddress, subject, message, ackdata, lastactiontime, status, pubkeyretrynumber, msgretrynumber = row
|
toaddress, toripe, fromaddress, subject, message, ackdata, lastactiontime, status, pubkeyretrynumber, msgretrynumber = row
|
||||||
if status == 'findingpubkey':
|
if status == 'findingpubkey':
|
||||||
if int(time.time()) - lastactiontime > (maximumAgeOfAnObjectThatIAmWillingToAccept * (2 ** (pubkeyretrynumber))):
|
if int(time.time()) - lastactiontime > (maximumAgeOfAnObjectThatIAmWillingToAccept * (2 ** (pubkeyretrynumber))):
|
||||||
|
@ -3880,6 +3920,7 @@ neededPubkeys = {}
|
||||||
successfullyDecryptMessageTimings = [] #A list of the amounts of time it took to successfully decrypt msg messages
|
successfullyDecryptMessageTimings = [] #A list of the amounts of time it took to successfully decrypt msg messages
|
||||||
apiAddressGeneratorReturnQueue = Queue.Queue() #The address generator thread uses this queue to get information back to the API thread.
|
apiAddressGeneratorReturnQueue = Queue.Queue() #The address generator thread uses this queue to get information back to the API thread.
|
||||||
alreadyAttemptedConnectionsListResetTime = int(time.time()) #used to clear out the alreadyAttemptedConnectionsList periodically so that we will retry connecting to hosts to which we have already tried to connect.
|
alreadyAttemptedConnectionsListResetTime = int(time.time()) #used to clear out the alreadyAttemptedConnectionsList periodically so that we will retry connecting to hosts to which we have already tried to connect.
|
||||||
|
numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer = {}
|
||||||
|
|
||||||
if useVeryEasyProofOfWorkForTesting:
|
if useVeryEasyProofOfWorkForTesting:
|
||||||
shared.networkDefaultProofOfWorkNonceTrialsPerByte = int(shared.networkDefaultProofOfWorkNonceTrialsPerByte / 16)
|
shared.networkDefaultProofOfWorkNonceTrialsPerByte = int(shared.networkDefaultProofOfWorkNonceTrialsPerByte / 16)
|
||||||
|
|
Reference in New Issue
Block a user