start removing daemontools by moving node announcement to communicatorutils file, deniable block insertion now config option

This commit is contained in:
Kevin Froman 2019-06-12 21:35:30 -05:00
parent 268325c07d
commit 3d93a37d0c
4 changed files with 96 additions and 68 deletions

View File

@ -25,7 +25,7 @@ import onionrexceptions, onionrpeers, onionrevents as events, onionrplugins as p
from communicatorutils import onionrdaemontools, servicecreator, onionrcommunicatortimers
from communicatorutils import downloadblocks, lookupblocks, lookupadders
from communicatorutils import servicecreator, connectnewpeers, uploadblocks
from communicatorutils import daemonqueuehandler
from communicatorutils import daemonqueuehandler, announcenode
import onionrservices, onionr, onionrproofs
OnionrCommunicatorTimers = onionrcommunicatortimers.OnionrCommunicatorTimers
@ -60,6 +60,8 @@ class OnionrCommunicatorDaemon:
self.connectTimes = {}
self.peerProfiles = [] # list of peer's profiles (onionrpeers.PeerProfile instances)
self.newPeers = [] # Peers merged to us. Don't add to db until we know they're reachable
self.announceProgress = {}
self.announceCache = {}
# amount of threads running by name, used to prevent too many
self.threadCounts = {}
@ -121,7 +123,7 @@ class OnionrCommunicatorDaemon:
OnionrCommunicatorTimers(self, self.uploadBlock, 10, requiresPeer=True, maxThreads=1)
# Timer to process the daemon command queue
OnionrCommunicatorTimers(self, self.daemonCommands, 6, maxThreads=1)
OnionrCommunicatorTimers(self, self.daemonCommands, 6, maxThreads=3)
# Timer that kills Onionr if the API server crashes
OnionrCommunicatorTimers(self, self.detectAPICrash, 30, maxThreads=1)
@ -136,7 +138,9 @@ class OnionrCommunicatorDaemon:
self.services = None
# This timer creates deniable blocks, in an attempt to further obfuscate block insertion metadata
if config.get('general.insert_deniable_blocks', True):
deniableBlockTimer = OnionrCommunicatorTimers(self, self.daemonTools.insertDeniableBlock, 180, requiresPeer=True, maxThreads=1)
deniableBlockTimer.count = (deniableBlockTimer.frequency - 175)
# Timer to check for connectivity, through Tor to various high-profile onion services
netCheckTimer = OnionrCommunicatorTimers(self, self.daemonTools.netCheck, 600)
@ -144,7 +148,7 @@ class OnionrCommunicatorDaemon:
# Announce the public API server transport address to other nodes if security level allows
if config.get('general.security_level', 1) == 0:
# Default to high security level incase config breaks
announceTimer = OnionrCommunicatorTimers(self, self.daemonTools.announceNode, 3600, requiresPeer=True, maxThreads=1)
announceTimer = OnionrCommunicatorTimers(self, announcenode.announce_node, 3600, myArgs=[self], requiresPeer=True, maxThreads=1)
announceTimer.count = (announceTimer.frequency - 120)
else:
logger.debug('Will not announce node.')
@ -158,7 +162,6 @@ class OnionrCommunicatorDaemon:
# Adjust initial timer triggers
peerPoolTimer.count = (peerPoolTimer.frequency - 1)
cleanupTimer.count = (cleanupTimer.frequency - 60)
deniableBlockTimer.count = (deniableBlockTimer.frequency - 175)
blockCleanupTimer.count = (blockCleanupTimer.frequency - 5)
# Main daemon loop, mainly for calling timers, don't do any complex operations here to avoid locking
@ -358,7 +361,7 @@ class OnionrCommunicatorDaemon:
def announce(self, peer):
'''Announce to peers our address'''
if self.daemonTools.announceNode() == False:
if announcenode.announce_node(self) == False:
logger.warn('Could not introduce node.')
def detectAPICrash(self):

View File

@ -4,6 +4,8 @@ The files in this submodule handle various subtasks and utilities for the onionr
## Files:
announcenode.py: Uses a communicator instance to announce our transport address to connected nodes
connectnewpeers.py: takes a communicator instance and has it connect to as many peers as needed, and/or to a new specified peer.
daemonqueuehandler.py: checks for new commands in the daemon queue and processes them accordingly.

View File

@ -0,0 +1,84 @@
'''
Onionr - Private P2P Communication
Use a communicator instance to announce our transport address to connected nodes
'''
'''
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
import base64
import onionrproofs, logger
from etc import onionrvalues
def announce_node(daemon):
'''Announce our node to our peers'''
ov = onionrvalues.OnionrValues()
retData = False
announceFail = False
# Do not let announceCache get too large
if len(daemon.announceCache) >= 10000:
daemon.announceCache.popitem()
if daemon._core.config.get('general.security_level', 0) == 0:
# Announce to random online peers
for i in daemon.onlinePeers:
if not i in daemon.announceCache and not i in daemon.announceProgress:
peer = i
break
else:
peer = daemon.pickOnlinePeer()
for x in range(1):
if x == 1 and daemon._core.config.get('i2p.host'):
ourID = daemon._core.config.get('i2p.own_addr').strip()
else:
ourID = daemon._core.hsAddress.strip()
url = 'http://' + peer + '/announce'
data = {'node': ourID}
combinedNodes = ourID + peer
if ourID != 1:
#TODO: Extend existingRand for i2p
existingRand = daemon._core._utils.bytesToStr(daemon._core.getAddressInfo(peer, 'powValue'))
# Reset existingRand if it no longer meets the minimum POW
if type(existingRand) is type(None) or not existingRand.endswith('0' * ov.announce_pow):
existingRand = ''
if peer in daemon.announceCache:
data['random'] = self.announceCache[peer]
elif len(existingRand) > 0:
data['random'] = existingRand
else:
daemon.announceProgress[peer] = True
proof = onionrproofs.DataPOW(combinedNodes, forceDifficulty=ov.announce_pow)
del daemon.announceProgress[peer]
try:
data['random'] = base64.b64encode(proof.waitForResult()[1])
except TypeError:
# Happens when we failed to produce a proof
logger.error("Failed to produce a pow for announcing to " + peer)
announceFail = True
else:
daemon.announceCache[peer] = data['random']
if not announceFail:
logger.info('Announcing node to ' + url)
if daemon._core._utils.doPostRequest(url, data) == 'Success':
logger.info('Successfully introduced node to ' + peer)
retData = True
daemon._core.setAddressInfo(peer, 'introduced', 1)
daemon._core.setAddressInfo(peer, 'powValue', data['random'])
daemon.decrementThreadCount('announceNode')
return retData

View File

@ -1,7 +1,7 @@
'''
Onionr - Private P2P Communication
Contains the CommunicatorUtils class which contains useful functions for the communicator daemon
Contains the DaemonTools class
'''
'''
This program is free software: you can redistribute it and/or modify
@ -37,67 +37,6 @@ class DaemonTools:
self.announceProgress = {}
self.announceCache = {}
def announceNode(self):
'''Announce our node to our peers'''
retData = False
announceFail = False
# Do not let announceCache get too large
if len(self.announceCache) >= 10000:
self.announceCache.popitem()
if self.daemon._core.config.get('general.security_level', 0) == 0:
# Announce to random online peers
for i in self.daemon.onlinePeers:
if not i in self.announceCache and not i in self.announceProgress:
peer = i
break
else:
peer = self.daemon.pickOnlinePeer()
for x in range(1):
if x == 1 and self.daemon._core.config.get('i2p.host'):
ourID = self.daemon._core.config.get('i2p.own_addr').strip()
else:
ourID = self.daemon._core.hsAddress.strip()
url = 'http://' + peer + '/announce'
data = {'node': ourID}
combinedNodes = ourID + peer
if ourID != 1:
#TODO: Extend existingRand for i2p
existingRand = self.daemon._core._utils.bytesToStr(self.daemon._core.getAddressInfo(peer, 'powValue'))
# Reset existingRand if it no longer meets the minimum POW
if type(existingRand) is type(None) or not existingRand.endswith('0' * ov.announce_pow):
existingRand = ''
if peer in self.announceCache:
data['random'] = self.announceCache[peer]
elif len(existingRand) > 0:
data['random'] = existingRand
else:
self.announceProgress[peer] = True
proof = onionrproofs.DataPOW(combinedNodes, forceDifficulty=ov.announce_pow)
del self.announceProgress[peer]
try:
data['random'] = base64.b64encode(proof.waitForResult()[1])
except TypeError:
# Happens when we failed to produce a proof
logger.error("Failed to produce a pow for announcing to " + peer)
announceFail = True
else:
self.announceCache[peer] = data['random']
if not announceFail:
logger.info('Announcing node to ' + url)
if self.daemon._core._utils.doPostRequest(url, data) == 'Success':
logger.info('Successfully introduced node to ' + peer)
retData = True
self.daemon._core.setAddressInfo(peer, 'introduced', 1)
self.daemon._core.setAddressInfo(peer, 'powValue', data['random'])
self.daemon.decrementThreadCount('announceNode')
return retData
def netCheck(self):
'''Check if we are connected to the internet or not when we can't connect to any peers'''
if len(self.daemon.onlinePeers) == 0: