basic lan syncing support is done

This commit is contained in:
Kevin 2020-06-19 00:55:13 -05:00
parent bae8b38f08
commit eeab5ef2c2
2 changed files with 59 additions and 31 deletions

View File

@ -8,6 +8,10 @@ from typing import Set
from onionrtypes import LANIP from onionrtypes import LANIP
from utils.bettersleep import better_sleep from utils.bettersleep import better_sleep
import logger
from coredb.blockmetadb import get_block_list
from onionrblocks.blockimporter import import_block_from_data
from ..server import ports
from threading import Thread from threading import Thread
""" """
@ -29,30 +33,35 @@ connected_lan_peers: Set[LANIP] = set([])
def _lan_work(peer: LANIP): def _lan_work(peer: LANIP):
identified_port = lambda: None def _sync_peer(url):
identified_port.port = 0 our_blocks = get_block_list()
def find_port(start=1024, max=0): blocks = requests.get(url + 'blist/0').text.splitlines()
for i in range(start, 65535): for block in blocks:
if i > max and max > 0: if block not in our_blocks:
import_block_from_data(requests.get(url + f'get/{block}', stream=True).raw.read(6000000))
for port in ports:
try:
root = f'http://{peer}:{port}/'
if requests.get(f'{root}ping').text != 'onionr!':
connected_lan_peers.remove(peer)
else:
logger.info(f'[LAN] Connected to {peer}:{port}', terminal=True)
while True:
try:
_sync_peer(root)
except requests.exceptions.ConnectionError:
break
break break
if identified_port.port != 0: except requests.exceptions.ConnectionError:
break pass
try: else:
if requests.get(f'http://{peer}:{i}/ping', timeout=1) == 'onionr!': connected_lan_peers.remove(peer)
print("Found", peer, i)
identified_port.port = i
break
except requests.exceptions.ConnectionError:
pass
#Thread(target=find_port, args=[1024, 32767], daemon=True).start()
#Thread(target=find_port, args=[32767, 65535], daemon=True).start()
#while identified_port.port == 0:
# better_sleep(1)
i = 1337
print(requests.get(f'http://{peer}:{i}/ping'))
def connect_peer(peer: LANIP): def connect_peer(peer: LANIP):
Thread(target=_lan_work, args=[peer], daemon=True).start() if peer not in connected_lan_peers:
connected_lan_peers.add(peer) connected_lan_peers.add(peer)
Thread(target=_lan_work, args=[peer], daemon=True).start()

View File

@ -2,6 +2,9 @@
LAN transport server thread LAN transport server thread
""" """
import ipaddress
from threading import Thread
from gevent.pywsgi import WSGIServer from gevent.pywsgi import WSGIServer
from flask import Flask from flask import Flask
from flask import Response from flask import Response
@ -13,10 +16,11 @@ from httpapi.fdsafehandler import FDSafeHandler
from netcontroller import get_open_port from netcontroller import get_open_port
import config import config
from coredb.blockmetadb import get_block_list from coredb.blockmetadb import get_block_list
from lan.getip import best_ip from lan.getip import best_ip, lan_ips
from onionrutils import stringvalidators from onionrutils import stringvalidators
from httpapi.miscpublicapi.upload import accept_upload from httpapi.miscpublicapi.upload import accept_upload
import logger import logger
from utils.bettersleep import better_sleep
""" """
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -31,7 +35,7 @@ import logger
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
ports = range(1337, 1340)
class LANServer: class LANServer:
def __init__(self, shared_state): def __init__(self, shared_state):
@ -45,6 +49,8 @@ class LANServer:
@app.before_request @app.before_request
def dns_rebinding_prevention(): def dns_rebinding_prevention():
if request.remote_addr in lan_ips or ipaddress.ip_address(request.remote_addr).is_loopback:
abort(403)
if request.host != f'{self.host}:{self.port}': if request.host != f'{self.host}:{self.port}':
logger.warn('Potential DNS rebinding attack on LAN server:') logger.warn('Potential DNS rebinding attack on LAN server:')
logger.warn(f'Hostname {request.host} was used instead of {self.host}:{self.port}') logger.warn(f'Hostname {request.host} was used instead of {self.host}:{self.port}')
@ -70,9 +76,22 @@ class LANServer:
return accept_upload(request) return accept_upload(request)
def start_server(self): def start_server(self):
self.server = WSGIServer((self.host, 1337), def _show_lan_bind(port):
self.app, log=None, better_sleep(1)
handler_class=FDSafeHandler) if self.server.started and port == self.server.server_port:
self.port = self.server.server_port logger.info(f'Serving to LAN on {self.host}:{self.port}', terminal=True)
logger.info(f'Serving to LAN on {self.host}:{self.port}', terminal=True) for i in ports:
self.server.serve_forever() self.server = WSGIServer((self.host, i),
self.app, log=None,
handler_class=FDSafeHandler)
self.port = self.server.server_port
try:
Thread(target=_show_lan_bind, args=[i], daemon=True).start()
self.server.serve_forever()
except OSError:
pass
else:
break
else:
logger.warn("Could not bind to any LAN ports " + str(min(ports)) + "-" + str(max(ports)), terminal=True)
return