improved block syncing

master
Kevin Froman 2018-01-27 19:53:24 -06:00
parent f3c1587d51
commit 897f18bbc2
No known key found for this signature in database
GPG Key ID: 0D414D0FE405B63B
5 changed files with 52 additions and 16 deletions

View File

@ -86,6 +86,7 @@ class API:
resp.headers['Content-Type'] = 'text/plain'
resp.headers["Content-Security-Policy"] = "default-src 'none'"
resp.headers['X-Frame-Options'] = 'deny'
resp.headers['X-Content-Type-Options'] = "nosniff"
return resp
@app.route('/client/')
@ -105,10 +106,6 @@ class API:
resp = Response('Goodbye')
elif action == 'stats':
resp = Response('me_irl')
elif action == 'init':
# generate PGP key
self._core.generateMainPGP()
pass
else:
resp = Response('(O_o) Dude what? (invalid command)')
endTime = math.floor(time.time())

View File

@ -94,6 +94,11 @@ class OnionrCommunicate:
if currentDB != False:
if lastDB != currentDB:
blocks += self.performGet('getBlockHashes', i)
if currentDB != lastDB:
if self._utils.validateHash(currentDB):
self._core.setPeerInfo(i, "blockDBHash", currentDB)
else:
logger.warn("Peer " + i + " returned malformed hash")
blockList = blocks.split('\n')
for i in blockList:
if not self._utils.validateHash(i):
@ -109,15 +114,16 @@ class OnionrCommunicate:
if not peer.endswith('.onion') and not peer.endswith('.onion/'):
raise PeerError('Currently only Tor .onion peers are supported. You must manually specify .onion')
socksPort = sys.argv[2]
proxies = {'http': 'socks5://127.0.0.1:' + str(socksPort), 'https': 'socks5://127.0.0.1:' + str(socksPort)}
'''We use socks5h to use tor as DNS'''
proxies = {'http': 'socks5h://127.0.0.1:' + str(socksPort), 'https': 'socks5h://127.0.0.1:' + str(socksPort)}
headers = {'user-agent': 'PyOnionr'}
url = 'http://' + peer + '/public/?action=' + action
if data != None:
url = url + '&data=' + data
try:
r = requests.get(url, headers=headers, proxies=proxies)
except requests.exceptions.RequestException:
logger.warn(action + " failed with peer " + peer)
except requests.exceptions.RequestException as e:
logger.warn(action + " failed with peer " + peer + ": " + e)
return False
return r.text

View File

@ -259,11 +259,16 @@ class Core:
key = base64.b64encode(os.urandom(32))
return key
def listPeers(self):
def listPeers(self, randomOrder=True):
'''Return a list of peers
randomOrder determines if the list should be in a random order
'''
conn = sqlite3.connect(self.peerDB)
c = conn.cursor()
if randomOrder:
peers = c.execute('SELECT * FROM peers order by RANDOM();')
else:
peers = c.execute('SELECT * FROM peers;')
peerList = []
for i in peers:
@ -310,6 +315,14 @@ class Core:
iterCount += 1
conn.close()
return retVal
def setPeerInfo(self, peer, key, data):
'''update a peer for a key'''
conn = sqlite3.connect(self.peerDB)
c = conn.cursor()
command = (peer,)
# TODO: validate key on whitelist
c.execute('UPDATE peers SET ' + key + ' = ' + data + ' where id=?', command)
def getBlockList(self, unsaved=False):
'''get list of our blocks'''

View File

@ -38,6 +38,7 @@ class NetController:
'''
return
def generateTorrc(self):
'''generate a torrc file for our tor instance'''
if os.path.exists(self.torConfigLocation):
os.remove(self.torConfigLocation)
torrcData = '''SocksPort ''' + str(self.socksPort) + '''
@ -53,7 +54,15 @@ HiddenServicePort 80 127.0.0.1:''' + str(self.hsPort) + '''
'''Start Tor with onion service on port 80 & socks proxy on random port
'''
self.generateTorrc()
tor = subprocess.Popen(['tor', '-f', self.torConfigLocation], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if os.path.exists('./tor'):
torBinary = './tor'
else:
torBinary = 'tor'
try:
tor = subprocess.Popen([torBinary, '-f', self.torConfigLocation], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except FileNotFoundError:
logger.error("Tor was not found in your path or the Onionr directory. Install Tor and try again.")
sys.exit(1)
# wait for tor to get to 100% bootstrap
for line in iter(tor.stdout.readline, b''):
if 'Bootstrapped 100%: Done' in line.decode():
@ -61,7 +70,8 @@ HiddenServicePort 80 127.0.0.1:''' + str(self.hsPort) + '''
elif 'Opening Socks listener' in line.decode():
logger.debug(line.decode())
else:
logger.error('Failed to start Tor')
logger.error('Failed to start Tor. Try killing any other Tor processes owned by this user.')
return False
logger.info('Finished starting Tor')
self.readyState = True
myID = open('data/hs/hostname', 'r')
@ -70,7 +80,7 @@ HiddenServicePort 80 127.0.0.1:''' + str(self.hsPort) + '''
torPidFile = open('data/torPid.txt', 'w')
torPidFile.write(str(tor.pid))
torPidFile.close()
return
return True
def killTor(self):
'''properly kill tor based on pid saved to file'''
try:

View File

@ -25,6 +25,11 @@ import gui, api, core
from onionrutils import OnionrUtils
from netcontroller import NetController
try:
from urllib3.contrib.socks import SOCKSProxyManager
except ImportError:
raise Exception("You need the PySocks module (for use with socks5 proxy to use Tor)")
class Onionr:
def __init__(self):
'''Main Onionr class. This is for the CLI program, and does not handle much of the logic.
@ -104,6 +109,12 @@ class Onionr:
os.remove('.onionr-lock')
elif command == 'stop':
self.killDaemon()
elif command in ('addmsg', 'addmessage'):
while True:
messageToAdd = input('Broadcast message to network: ')
if len(messageToAdd) >= 1:
break
self.onionrCore.setData(messageToAdd)
elif command == 'stats':
self.showStats()
elif command == 'help' or command == '--help':
@ -124,7 +135,8 @@ class Onionr:
if not os.environ.get("WERKZEUG_RUN_MAIN") == "true":
net = NetController(self.config['CLIENT']['PORT'])
logger.info('Tor is starting...')
net.startTor()
if not net.startTor():
sys.exit(1)
logger.info('Started Tor .onion service: ' + logger.colors.underline + net.myID)
time.sleep(1)
subprocess.Popen(["./communicator.py", "run", str(net.socksPort)])
@ -148,6 +160,4 @@ class Onionr:
def showHelp(self):
'''Show help for Onionr'''
return
Onionr()