diff --git a/src/lan/client/__init__.py b/src/lan/client/__init__.py index 95a639de..aa0a53da 100644 --- a/src/lan/client/__init__.py +++ b/src/lan/client/__init__.py @@ -8,6 +8,10 @@ from typing import Set from onionrtypes import LANIP 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 """ @@ -29,30 +33,35 @@ connected_lan_peers: Set[LANIP] = set([]) def _lan_work(peer: LANIP): - identified_port = lambda: None - identified_port.port = 0 - def find_port(start=1024, max=0): - for i in range(start, 65535): - if i > max and max > 0: + def _sync_peer(url): + our_blocks = get_block_list() + blocks = requests.get(url + 'blist/0').text.splitlines() + for block in blocks: + 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 - if identified_port.port != 0: - break - try: - if requests.get(f'http://{peer}:{i}/ping', timeout=1) == 'onionr!': - 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')) + except requests.exceptions.ConnectionError: + pass + else: + connected_lan_peers.remove(peer) def connect_peer(peer: LANIP): - Thread(target=_lan_work, args=[peer], daemon=True).start() - connected_lan_peers.add(peer) + if peer not in connected_lan_peers: + connected_lan_peers.add(peer) + Thread(target=_lan_work, args=[peer], daemon=True).start() + diff --git a/src/lan/server/__init__.py b/src/lan/server/__init__.py index 74f1f335..57729bb0 100644 --- a/src/lan/server/__init__.py +++ b/src/lan/server/__init__.py @@ -2,6 +2,9 @@ LAN transport server thread """ +import ipaddress +from threading import Thread + from gevent.pywsgi import WSGIServer from flask import Flask from flask import Response @@ -13,10 +16,11 @@ from httpapi.fdsafehandler import FDSafeHandler from netcontroller import get_open_port import config 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 httpapi.miscpublicapi.upload import accept_upload import logger +from utils.bettersleep import better_sleep """ 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 @@ -31,7 +35,7 @@ import logger You should have received a copy of the GNU General Public License along with this program. If not, see . """ - +ports = range(1337, 1340) class LANServer: def __init__(self, shared_state): @@ -45,6 +49,8 @@ class LANServer: @app.before_request 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}': logger.warn('Potential DNS rebinding attack on LAN server:') logger.warn(f'Hostname {request.host} was used instead of {self.host}:{self.port}') @@ -70,9 +76,22 @@ class LANServer: return accept_upload(request) def start_server(self): - self.server = WSGIServer((self.host, 1337), - self.app, log=None, - handler_class=FDSafeHandler) - self.port = self.server.server_port - logger.info(f'Serving to LAN on {self.host}:{self.port}', terminal=True) - self.server.serve_forever() + def _show_lan_bind(port): + better_sleep(1) + if self.server.started and port == self.server.server_port: + logger.info(f'Serving to LAN on {self.host}:{self.port}', terminal=True) + for i in ports: + 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