Merge pull request #639 from bpeel/wip/trusted-peer
Add a 'trustedpeer' option to keys.dat
This commit is contained in:
commit
38d7db24ad
|
@ -22,26 +22,37 @@ class outgoingSynSender(threading.Thread):
|
|||
self.streamNumber = streamNumber
|
||||
self.selfInitiatedConnections = selfInitiatedConnections
|
||||
|
||||
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
|
||||
shared.knownNodesLock.acquire()
|
||||
if shared.trustedPeer:
|
||||
peer = shared.trustedPeer
|
||||
shared.knownNodes[self.streamNumber][peer] = time.time()
|
||||
else:
|
||||
peer, = random.sample(shared.knownNodes[self.streamNumber], 1)
|
||||
shared.knownNodesLock.release()
|
||||
|
||||
return peer
|
||||
|
||||
def run(self):
|
||||
while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'):
|
||||
time.sleep(2)
|
||||
while shared.safeConfigGetBoolean('bitmessagesettings', 'sendoutgoingconnections'):
|
||||
while len(self.selfInitiatedConnections[self.streamNumber]) >= 8: # maximum number of outgoing connections = 8
|
||||
maximumConnections = 1 if shared.trustedPeer else 8 # maximum number of outgoing connections = 8
|
||||
while len(self.selfInitiatedConnections[self.streamNumber]) >= maximumConnections:
|
||||
time.sleep(10)
|
||||
if shared.shutdown:
|
||||
break
|
||||
random.seed()
|
||||
shared.knownNodesLock.acquire()
|
||||
peer, = random.sample(shared.knownNodes[self.streamNumber], 1)
|
||||
shared.knownNodesLock.release()
|
||||
peer = self._getPeer()
|
||||
shared.alreadyAttemptedConnectionsListLock.acquire()
|
||||
while peer in shared.alreadyAttemptedConnectionsList or peer.host in shared.connectedHostsList:
|
||||
shared.alreadyAttemptedConnectionsListLock.release()
|
||||
# print 'choosing new sample'
|
||||
random.seed()
|
||||
shared.knownNodesLock.acquire()
|
||||
peer, = random.sample(shared.knownNodes[self.streamNumber], 1)
|
||||
shared.knownNodesLock.release()
|
||||
peer = self._getPeer()
|
||||
time.sleep(1)
|
||||
# Clear out the shared.alreadyAttemptedConnectionsList every half
|
||||
# hour so that this program will again attempt a connection
|
||||
|
|
|
@ -319,6 +319,14 @@ class receiveDataThread(threading.Thread):
|
|||
print 'Sending huge inv message with', numberOfObjects, 'objects to just this one peer'
|
||||
self.sendDataThreadQueue.put((0, 'sendRawData', headerData + payload))
|
||||
|
||||
def _sleepForTimingAttackMitigation(self, sleepTime):
|
||||
# We don't need to do the timing attack mitigation if we are
|
||||
# only connected to the trusted peer because we can trust the
|
||||
# peer not to attack
|
||||
if sleepTime > 0 and doTimingAttackMitigation and shared.trustedPeer == None:
|
||||
with shared.printLock:
|
||||
print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.'
|
||||
time.sleep(sleepTime)
|
||||
|
||||
# We have received a broadcast message
|
||||
def recbroadcast(self, data):
|
||||
|
@ -347,10 +355,7 @@ class receiveDataThread(threading.Thread):
|
|||
|
||||
sleepTime = lengthOfTimeWeShouldUseToProcessThisMessage - \
|
||||
(time.time() - self.messageProcessingStartTime)
|
||||
if sleepTime > 0 and doTimingAttackMitigation:
|
||||
with shared.printLock:
|
||||
print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.'
|
||||
time.sleep(sleepTime)
|
||||
self._sleepForTimingAttackMitigation(sleepTime)
|
||||
|
||||
# We have received a msg message.
|
||||
def recmsg(self, data):
|
||||
|
@ -379,10 +384,7 @@ class receiveDataThread(threading.Thread):
|
|||
|
||||
sleepTime = lengthOfTimeWeShouldUseToProcessThisMessage - \
|
||||
(time.time() - self.messageProcessingStartTime)
|
||||
if sleepTime > 0 and doTimingAttackMitigation:
|
||||
with shared.printLock:
|
||||
print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.'
|
||||
time.sleep(sleepTime)
|
||||
self._sleepForTimingAttackMitigation(sleepTime)
|
||||
|
||||
# We have received a pubkey
|
||||
def recpubkey(self, data):
|
||||
|
@ -393,11 +395,7 @@ class receiveDataThread(threading.Thread):
|
|||
lengthOfTimeWeShouldUseToProcessThisMessage = .1
|
||||
sleepTime = lengthOfTimeWeShouldUseToProcessThisMessage - \
|
||||
(time.time() - self.pubkeyProcessingStartTime)
|
||||
if sleepTime > 0 and doTimingAttackMitigation:
|
||||
with shared.printLock:
|
||||
print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.'
|
||||
time.sleep(sleepTime)
|
||||
|
||||
self._sleepForTimingAttackMitigation(sleepTime)
|
||||
|
||||
# We have received an inv message
|
||||
def recinv(self, data):
|
||||
|
|
|
@ -39,6 +39,11 @@ class singleListener(threading.Thread):
|
|||
return sock
|
||||
|
||||
def run(self):
|
||||
# If there is a trusted peer then we don't want to accept
|
||||
# incoming connections so we'll just abandon the thread
|
||||
if shared.trustedPeer:
|
||||
return
|
||||
|
||||
while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'):
|
||||
time.sleep(1)
|
||||
helper_bootstrap.dns()
|
||||
|
|
|
@ -12,6 +12,17 @@ from namecoin import ensureNamecoinOptions
|
|||
|
||||
storeConfigFilesInSameDirectoryAsProgramByDefault = False # The user may de-select Portable Mode in the settings if they want the config files to stay in the application data folder.
|
||||
|
||||
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 loadConfig():
|
||||
if shared.appdata:
|
||||
shared.config.read(shared.appdata + 'keys.dat')
|
||||
|
@ -123,6 +134,8 @@ def loadConfig():
|
|||
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
||||
shared.config.write(configfile)
|
||||
|
||||
_loadTrustedPeer()
|
||||
|
||||
def isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections():
|
||||
try:
|
||||
VER_THIS=StrictVersion(platform.version())
|
||||
|
|
|
@ -92,6 +92,18 @@ namecoinDefaultRpcPort = "8336"
|
|||
# binary distributions vs source distributions.
|
||||
frozen = getattr(sys,'frozen', None)
|
||||
|
||||
# If the trustedpeer option is specified in keys.dat then this will
|
||||
# contain a Peer which will be connected to instead of using the
|
||||
# addresses advertised by other peers. The client will only connect to
|
||||
# this peer and the timing attack mitigation will be disabled in order
|
||||
# to download data faster. The expected use case is where the user has
|
||||
# a fast connection to a trusted server where they run a BitMessage
|
||||
# daemon permanently. If they then run a second instance of the client
|
||||
# on a local machine periodically when they want to check for messages
|
||||
# it will sync with the network a lot faster without compromising
|
||||
# security.
|
||||
trustedPeer = None
|
||||
|
||||
def isInSqlInventory(hash):
|
||||
queryreturn = sqlQuery('''select hash from inventory where hash=?''', hash)
|
||||
return queryreturn != []
|
||||
|
|
Reference in New Issue
Block a user