def connect(self, address, peer_id=None, use_tls=False): """Create a connection to address. Possible via another mifcho instance.""" logging.debug( "Connecting to: %s %s %s." % (pprint.pformat(address), pprint.pformat(peer_id), pprint.pformat(use_tls)) ) conn = None peer = self.get_peer(peer_id) if not peer and not peer_id: # Connect "directly" to address try: conn = Connection.fromaddress(address, use_tls) if conn: # Add to opened connections self.opened.append(conn) except socket.error: logging.error("%s when connecting to %s." % (sys.exc_info()[1], address)) except: logging.error("Unexpected error", exc_info=3) elif peer and peer.interface: # Connect via peer interface # Extract address and parameters of peer interface. peer_address = (peer.interface[0], peer.interface[1]) try: peer_conn = self.connect(peer_address) # Socket Connect messages.send_request( # Send TunnelReq peer_conn, type="POST", url="/mifcho/tunnel", headers=[ ("X-Mifcho-Id", self.identifier), ("X-Mifcho-Tunnel-EndpointHost", address[0]), ("X-Mifcho-Tunnel-EndpointPort", address[1]), ], ) resp = (version, status, reason, headers) = messages.get_response(peer_conn) # Wait for response except: logging.error("Failed connecting to socket!") logging.debug("Failed receiving response!", exc_info=3) peer_conn = None resp = (version, status, reason, headers) = ("", 404, "Not Found", []) conn = peer_conn elif peer and not peer.interface: # Connect via peer control-line # and "callback". peer.lock.acquire() # CRITICAL ZONE START... tunnel = Tunnel.fromconnections(None, None) self.add_tunnel(tunnel) try: # Send request for tunnel messages.send_request( peer.connection, type="POST", url="/mifcho/tunnel_request", headers=[ ("X-Mifcho-Id", self.identifier), ("X-Mifcho-Tunnel-Id", tunnel.id), ("X-Mifcho-Tunnel-EndpointHost", address[0]), ("X-Mifcho-Tunnel-EndpointPort", address[1]), ], ) except: logging.error("Error sending request to peer!", exc_info=3) try: # Wait for response resp = (version, status, reason, headers) = messages.get_response(peer.connection) except: logging.error("Failed receiving response!") logging.debug("Failed receiving response!", exc_info=3) resp = (version, status, reason, headers) = ("", 404, "Not Found", []) peer.lock.release() # CRITICAL ZONE END.... if int(status) == 200: # All is good # Wait for PeerHandler to set tunnel-event wait_for_tunnel = True while status == 200 and self.running and wait_for_tunnel: tunnel.event.wait(1) wait_for_tunnel = not tunnel.event.is_set() conn = tunnel.peer_connection else: conn = None elif peer_id and not peer: logging.error("Could not find peer %s." % repr(peer_id)) logging.debug("Peers=[%s]" % repr(self.peers)) else: logging.error("Invalid params.") return conn