Notify in UI if time offset wrong

- if your time is off by more than an hour, you won't be able to
  establish a connection to the network. This patch adds a UI
  notification so that the user can understand why he can't connect.
This commit is contained in:
Peter Šurda 2016-10-23 10:12:49 +02:00
parent c335ef7d10
commit 40090a9a12
Signed by untrusted user: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
2 changed files with 20 additions and 1 deletions

View File

@ -1,6 +1,7 @@
doTimingAttackMitigation = False doTimingAttackMitigation = False
import base64 import base64
import datetime
import errno import errno
import math import math
import time import time
@ -26,6 +27,7 @@ from class_objectHashHolder import objectHashHolder
from helper_generic import addDataPadding, isHostInPrivateIPRange from helper_generic import addDataPadding, isHostInPrivateIPRange
from helper_sql import sqlQuery from helper_sql import sqlQuery
from debug import logger from debug import logger
import tr
# This thread is created either by the synSenderThread(for outgoing # This thread is created either by the synSenderThread(for outgoing
# connections) or the singleListenerThread(for incoming connections). # connections) or the singleListenerThread(for incoming connections).
@ -105,10 +107,14 @@ class receiveDataThread(threading.Thread):
select.select([self.sslSock], [], []) select.select([self.sslSock], [], [])
continue continue
logger.error('sock.recv error. Closing receiveData thread (' + str(self.peer) + ', Thread ID: ' + str(id(self)) + ').' + str(err.errno) + "/" + str(err)) logger.error('sock.recv error. Closing receiveData thread (' + str(self.peer) + ', Thread ID: ' + str(id(self)) + ').' + str(err.errno) + "/" + str(err))
if self.initiatedConnection and not self.connectionIsOrWasFullyEstablished:
shared.timeOffsetWrongCount += 1
break break
# print 'Received', repr(self.data) # print 'Received', repr(self.data)
if len(self.data) == dataLen: # If self.sock.recv returned no data: if len(self.data) == dataLen: # If self.sock.recv returned no data:
logger.debug('Connection to ' + str(self.peer) + ' closed. Closing receiveData thread. (ID: ' + str(id(self)) + ')') logger.debug('Connection to ' + str(self.peer) + ' closed. Closing receiveData thread. (ID: ' + str(id(self)) + ')')
if self.initiatedConnection and not self.connectionIsOrWasFullyEstablished:
shared.timeOffsetWrongCount += 1
break break
else: else:
self.processData() self.processData()
@ -130,6 +136,7 @@ class receiveDataThread(threading.Thread):
except: except:
pass pass
shared.UISignalQueue.put(('updateNetworkStatusTab', 'no data')) shared.UISignalQueue.put(('updateNetworkStatusTab', 'no data'))
self.checkTimeOffsetNotification()
logger.debug('receiveDataThread ending. ID ' + str(id(self)) + '. The size of the shared.connectedHostsList is now ' + str(len(shared.connectedHostsList))) logger.debug('receiveDataThread ending. ID ' + str(id(self)) + '. The size of the shared.connectedHostsList is now ' + str(len(shared.connectedHostsList)))
def antiIntersectionDelay(self, initial = False): def antiIntersectionDelay(self, initial = False):
@ -146,6 +153,10 @@ class receiveDataThread(threading.Thread):
logger.debug("Sleeping due to missing object for %.2fs", delay) logger.debug("Sleeping due to missing object for %.2fs", delay)
time.sleep(delay) time.sleep(delay)
def checkTimeOffsetNotification(self):
if shared.timeOffsetWrongCount >= 4 and not self.connectionIsOrWasFullyEstablished:
shared.UISignalQueue.put(('updateStatusBar', tr._translate("MainWindow", "The time on your computer, %1, may be wrong. Please verify your settings.").arg(datetime.datetime.now().strftime("%H:%M:%S"))))
def processData(self): def processData(self):
if len(self.data) < shared.Header.size: # if so little of the data has arrived that we can't even read the checksum then wait for more data. if len(self.data) < shared.Header.size: # if so little of the data has arrived that we can't even read the checksum then wait for more data.
return return
@ -265,6 +276,7 @@ class receiveDataThread(threading.Thread):
# there is no reason to run this function a second time # there is no reason to run this function a second time
return return
self.connectionIsOrWasFullyEstablished = True self.connectionIsOrWasFullyEstablished = True
shared.timeOffsetWrongCount = 0
self.sslSock = self.sock self.sslSock = self.sock
if ((self.services & shared.NODE_SSL == shared.NODE_SSL) and if ((self.services & shared.NODE_SSL == shared.NODE_SSL) and
@ -699,15 +711,21 @@ class receiveDataThread(threading.Thread):
if timeOffset > 3600: 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."))) 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)) logger.info("%s's time is too far in the future (%s seconds). Closing connection to it." % (self.peer, timeOffset))
shared.timeOffsetWrongCount += 1
time.sleep(2) time.sleep(2)
self.sendDataThreadQueue.put((0, 'shutdown','no data')) self.sendDataThreadQueue.put((0, 'shutdown','no data'))
return return
if timeOffset < -3600: elif 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."))) 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)) logger.info("%s's time is too far in the past (timeOffset %s seconds). Closing connection to it." % (self.peer, timeOffset))
shared.timeOffsetWrongCount += 1
time.sleep(2) time.sleep(2)
self.sendDataThreadQueue.put((0, 'shutdown','no data')) self.sendDataThreadQueue.put((0, 'shutdown','no data'))
return return
else:
shared.timeOffsetWrongCount = 0
self.checkTimeOffsetNotification()
self.myExternalIP = socket.inet_ntoa(data[40:44]) self.myExternalIP = socket.inet_ntoa(data[40:44])
# print 'myExternalIP', self.myExternalIP # print 'myExternalIP', self.myExternalIP
self.remoteNodeIncomingPort, = unpack('>H', data[70:72]) self.remoteNodeIncomingPort, = unpack('>H', data[70:72])

View File

@ -94,6 +94,7 @@ needToWriteKnownNodesToDisk = False # If True, the singleCleaner will write it t
maximumLengthOfTimeToBotherResendingMessages = 0 maximumLengthOfTimeToBotherResendingMessages = 0
objectProcessorQueue = ObjectProcessorQueue() # receiveDataThreads dump objects they hear on the network into this queue to be processed. objectProcessorQueue = ObjectProcessorQueue() # receiveDataThreads dump objects they hear on the network into this queue to be processed.
streamsInWhichIAmParticipating = {} streamsInWhichIAmParticipating = {}
timeOffsetWrongCount = 0
# sanity check, prevent doing ridiculous PoW # sanity check, prevent doing ridiculous PoW
# 20 million PoWs equals approximately 2 days on dev's dual R9 290 # 20 million PoWs equals approximately 2 days on dev's dual R9 290