def data_received(self, data): # Connection is initialized once we already know the url # as we need to know it to filter what RecvNetwork is # able to accept the request. if not self.url: self.url = hpxclient_utils.get_host_from_headers(data) # full_url = hpxclient_utils.get_url_from_headers(data) # if data.startswith(b'GET') and not hpxclient_utils.is_captive_platform(full_url): # msg = self.create_http_message(""" # <h1>Http protocol not supported, try using https.</h1> # <script> # window.location.href = window.location.href.replace("http:","https:") # </script>""", 200) # self.transport.write(msg.encode()) # self.transport.close() # self.processor.close_conn(self.conn_id) # return if not self.conn_initialized: self.processor.init_conn(self.conn_id, self.url) self.conn_initialized = True if FETCHER is None: logger.info("Listener transport closed as fetcher is none.") self.transport.close() return if self.conn_id not in listener_consumers.BROWSER_TASKS: logger.warning("BrowserListener closed %s!", self.conn_id) self.transport.close() return self.processor.trans_conn(self.conn_id, data)
async def create_connection(cls, protocol_factory, host=None, port=None, sock=None, ssl=None, retry_initial_connection=True): assert (host and port) or sock, "Provide sock or address:port data." from hpxclient.mng import service as manager_service loop = asyncio.get_event_loop() wrapper = cls(protocol_factory, host, port) delayed_timeout = DEFAULT_DELAY_TIMEOUT while True: try: if sock: await loop.create_connection(lambda: wrapper, sock=sock) else: logger.debug("Create connection for %s, %s, %s, %s", wrapper, host, port, ssl) await loop.create_connection(lambda: wrapper, host=host, port=port, ssl=manager_service.ssl_context) return except OSError as e: if not retry_initial_connection: logger.info("Not retrying closed connection: %s", protocol_factory) break #raise print(e) print("Disconnected. Trying to connect in {} seconds".format(delayed_timeout)) delayed_timeout *= 2 await asyncio.sleep(delayed_timeout)
def register_broadcast(self): """ Sends broadcast data to the p2p rendezvous server. """ self.local_addr = self.transport.get_extra_info("sockname") logger.info("My transport sockname (local address) is: {}".format(self.local_addr)) self.write_data(bridge_producers.RegisterBroadcastProducer(self.local_addr, self.session_id)) # was session
async def configure_service(user_id, session_id, public_key, ssl_context): loop = asyncio.get_event_loop() fetcher_ = FetcherProtocol(user_id=user_id, session_id=session_id, public_key=public_key) logger.info("Proxy listening at %s", hpxclient_settings.PROXY_LISTENER_LOCAL_PORT) global BROWSER_LISTENER if not BROWSER_LISTENER: BROWSER_LISTENER = await asyncio.wait([ loop.create_server( BrowserListenerServer, '127.0.0.1', hpxclient_settings.PROXY_LISTENER_LOCAL_PORT, ), ]) await asyncio.wait([ protocols.ReconnectingProtocolWrapper.create_connection( lambda: fetcher_, host=hpxclient_settings.PROXY_LISTENER_SERVER_IP, port=hpxclient_settings.PROXY_LISTENER_SERVER_PORT, ssl=ssl_context), ])
def process(self): from hpxclient.listener.consumers import BROWSER_TASKS conn_id, data = self.data[b'conn_id'], self.data[b'data'] logger.info("CONSUMER transfer data: %s : %s", self.data[b"conn_id"], self.data[b"data"]) if conn_id in BROWSER_TASKS: BROWSER_TASKS[conn_id].write(data)
def process(self): username = self.data[b'username'].decode() password = self.data[b'password'].decode() auth_result = username == hpxclient_settings.RPC_USERNAME \ and password == hpxclient_settings.RPC_PASSWORD logger.info("Auth result: %s", auth_result) self.protocol.write_data( protocols.RPCAuthResponseProducer(result=auth_result))
def connection_lost(self, exc): """ The connection with the P2P peer was closed. It must be taken out from the P2P clients pool. """ if self.pid in P2P_CLIENTS: del P2P_CLIENTS[self.pid] logger.info("Connection with %s was closed. Error: %s", self.pid, exc) else: logger.error("Public key %s was not in P2P clients! Error: %s", self.pid, exc)
def connection_made(self, transport): self.transport = transport self.processor = self.get_processor() logger.info( """Connection %s made to client.LocalListener Processor: %s""", self.conn_id, self.processor) if self.processor is None: self.transport.close() return listener_consumers.BROWSER_TASKS[self.conn_id] = self
def process(self): error = self.data[b'error'] if not error: self.protocol.session_id = self.data[b'session_id'] self.protocol.user_id = self.data[b'user_id'] self.protocol.public_key = self.data[b'public_key'] self.protocol.is_authenticated = True logger.info("Connection authorized. Starting all services.") asyncio.ensure_future(self.protocol.start_services()) else: logger.error("Unexpected error: %s", error.decode()) self.protocol.error = error.decode()
def load_data_config_file(config_file): from hpxclient import settings as hpxclient_settings if not config_file: config_file = os.path.join(hpxclient_settings.HPROX_DIR, hpxclient_consts.HPROX_CONFIG_NAME) config = configparser.ConfigParser() try: config.read_file(open(config_file)) logger.info("Loading settings from %s", config_file) except FileNotFoundError: logger.info("No file settings found: %s", config_file) # This list prunes some parameters that can be in consts.py but # they cannot be defined via hprox.cfg _NOT_ALLOWED_IN_CONF = [ "SECRET_KEY", ] # Loading settings from the config file. for section in config.sections(): for name, value in config[section].items(): logger.debug(">> Setting from config file. Key: %s, value: %s", name, value) # We consider as a valid configuration parameter anything # that is listed in hpxclient.settings. try: getattr(hpxclient_settings, name.upper()) except NameError: raise argparse.ArgumentTypeError( "Not valid configuration parameter: %s" % name) if 'DOMAIN' in name.upper(): set_ips(hpxclient_settings, value) if 'DEBUG' in name.upper(): value = True if value.lower() == 'true' else False if name.upper() in _NOT_ALLOWED_IN_CONF: raise argparse.ArgumentTypeError( "Not valid configuration parameter: %s" % name) setattr(hpxclient_settings, name.upper(), cast_value(name, value)) if hasattr(hpxclient_settings, 'SECRET_KEY_FILE') \ and hpxclient_settings.SECRET_KEY_FILE: try: with open(hpxclient_settings.SECRET_KEY_FILE) as f: logger.debug(">> Setting SECRET KEY from file: %s", hpxclient_settings.SECRET_KEY_FILE) hpxclient_settings.SECRET_KEY = f.readline().strip() except FileNotFoundError: pass
async def ping_service(self): """ Ping the other peer and we check when was the last time that he pinged us. If it's longer than PING_TIMEOUT we break the connection. """ while True: self.ping_peer() now = int(time.time()) if self.last_ping_response is not None \ and bridge_consts.PEER_PING_TIMEOUT < now - self.last_ping_response: logger.info("Closed connection due to PING TIMEOUT") self.transport.close() await asyncio.sleep(bridge_consts.PEER_PING_INTERVAL)
def connection_lost(self, exc): logger.info( "[Consumer] Sending Close-Transfer-ACK: %s bytes for conn id %s", self.amount_data_downloaded, self.conn_id) manager_service.MANAGER.send_transfer_consumer_close( self.conn_id, self.amount_data_downloaded) self.amount_data_downloaded = 0 if FETCHER is not None: FETCHER.close_conn(self.conn_id) if self.conn_id in listener_consumers.BROWSER_TASKS: logger.warning("[LocalListener] Deleting CONN ID %s from TASKS", self.conn_id) del listener_consumers.BROWSER_TASKS[self.conn_id]
def write_to_browser(self, data): if self.transport.is_closing(): return self.transport.write(data) self.amount_data_downloaded += len(data) if mng_consts.TRANSFER_DATA_ACK_BLOCK_SIZE < self.amount_data_downloaded: amount_left = self.amount_data_downloaded % mng_consts.TRANSFER_DATA_ACK_BLOCK_SIZE amount_ack = self.amount_data_downloaded - amount_left logger.info( "[CONSUMER] Sending Transfer-ACK: %s bytes for conn id %s", amount_ack, self.conn_id) manager_service.MANAGER.send_transfer_consumer_ack( self.conn_id, amount_ack) self.amount_data_downloaded = amount_left
def get_processor(self): """ Return object that will 'process' the request: - Fetcher: The URL-task-request would be sent to our server-fetcher and it would be relayed to another client that was also connected to the fetcher. - P2P client: The URL-task-request would be sent to another client directly through the P2PBridge connection. Before starting """ return FETCHER try: p2p_public_key = random.choice( list(bridge_service.P2P_CLIENTS.keys())) logger.info("Selected P2P processor: %s.", p2p_public_key) return bridge_service.P2P_CLIENTS[p2p_public_key] except IndexError: logger.info("Selected FETCHER processor.") return FETCHER
def trans_conn(self, conn_id, data): now = hpxclient_utils.get_utime_ms() self.amount_data_downloaded += len(data) diff = now - self.utime_last_ack if 0 < self.amount_data_downloaded and \ (diff > mng_consts.TRANSFER_DATA_ACK_MAX_PERIOD or mng_consts.TRANSFER_DATA_ACK_BLOCK_SIZE < self.amount_data_downloaded): logger.info( "[CONSUMER] Sending Transfer-ACK: " "%s bytes for conn id %s", self.amount_data_downloaded, conn_id) manager_service.MANAGER.send_transfer_consumer_ack( conn_id, self.amount_data_downloaded) self.amount_data_downloaded = 0 self.utime_last_ack = now self.write_data( protocols.TransferDataProducer(conn_id=conn_id, session_id=self.session_id, data=data))
def register_conn(self): logger.info("Registering connection from bridge to p2p server.") self.write_data(protocols.RegisterConnProducer(self.pid, self.conn_id))
def process(self): logger.info("Message: %s", self.data)
def register_conn(self): logger.info("Registering connection from bridge to p2p server.") self.write_data(protocols.RegisterConnPIDProducer(user_id=self.user_id, session_id=self.session_id, public_key=self.public_key))
def load_config(): """ Load configuration settings from hprox.cfg. If any extra parameter is supplied via command overwrites the configuration file. We consider as a valid configuration setting all items listed in the hpxclient.consts. """ from hpxclient import settings as hpxclient_settings parser = argparse.ArgumentParser() parser.add_argument("-v", "--verbose", type=int, choices=[0, 1, 2], help="increase output verbosity") parser.add_argument("-rpc", "--rpc-local-port", dest="RPC_LOCAL_PORT", type=int, help="Define the LOCAL PORT for the RPC protocol.") parser.add_argument("-p", "--port", dest="PROXY_LISTENER_LOCAL_PORT", type=int, help="Define the LOCAL PORT for the listener service.") parser.add_argument("-pk", "--public-key", dest="PUBLIC_KEY", help="Define the network's access PUBLIC KEY.") parser.add_argument( "-skf", "--secret-key-file", dest="SECRET_KEY_FILE", help="Define the file that contains the network's access SECRET KEY.") parser.add_argument("-c", "--config", dest="config_file", help="Define configuration file.") args = parser.parse_args() config_file = args.config_file # Loading settings from config file. load_data_config_file(config_file) # Loading settings from the command line. They overwrite config file. for name, value in args.__dict__.items(): if value: setattr(hpxclient_settings, name, cast_value(name, value)) # Loading settings from environ. They overwrite everything. if "HPROX_PUBLIC_KEY" in os.environ: logger.info("Reading PUBLIC KEY from environment.") hpxclient_settings.PUBLIC_KEY = os.environ["HPROX_PUBLIC_KEY"] if "HPROX_SECRET_KEY" in os.environ: logger.info("Reading SECRET KEY from environment.") hpxclient_settings.SECRET_KEY = os.environ["HPROX_SECRET_KEY"]
def process(self): logger.info('Session %s was closed from server', self.data[b'session_id']) self.protocol.transport.close()
def process(self): logger.info("[Bridge] validating public/ secret key.")
def connection_lost(self, exc): logger.info("Connection lost to fetcher: %s", exc) global FETCHER FETCHER = None