def tunnel(self, conn, env): logging.debug('TUNNEL') if 'HTTP_X_MIFCHO_TUNNEL_ID' in env: # We requested the tunnel logging.debug('We requested the tunnel...') tunnel = self.cm.tunnels[env['HTTP_X_MIFCHO_TUNNEL_ID']] tunnel.peer_connection = conn messages.send_response(conn, code = 101, message = 'Switching Protocols', headers = [ ('X-Mifcho-Id', env['mifcho.id']) ] ) tunnel.event.set() else: # We did not request the tunnel so this is an indirect tunnel carrier. logging.debug('We did not request it...') ep_address = ( env['HTTP_X_MIFCHO_TUNNEL_ENDPOINTHOST'], int(headers['X_MIFCHO_TUNNEL_ENDPOINTPORT']) ) ep_conn = self.cm.connect(ep_address) if conn and ep_conn: logging.debug('Successfully contacted endpoint...') tunnel = Tunnel.fromconnections(conn, ep_conn) tunnel.id = str(uuid.uuid4()) self.cm.add_tunnel(tunnel) messages.send_response(conn, code = 101, message = 'Switching Protocols', headers = [ ('X-Mifcho-Id', self.cm.identifier) ] ) pipe = Piper(self.cm, conn, ep_conn, 4096, sink_recovery=(ep_address, None)) pipe.start() self.cm.pipes.append(pipe) else: logging.error('Failed connecting to endpoint [%s].' % repr(address)) self.cm.teardown(conn)
def tunnel_request(self, conn, env): logging.debug('TUNNEL_REQUEST') # Get params from request peer_id = env['HTTP_X_MIFCHO_ID'] tunnel_id = env['HTTP_X_MIFCHO_TUNNEL_ID'] ep_address = ( headers['HTTP_X_MIFCHO_TUNNEL_ENDPOINTHOST'], int(headers['HTTP_X_MIFCHO_TUNNEL_ENDPOINTPORT']) ) # Lookup the peer in peer-list to get the interface to connect to peer = self.cm.get_peer(peer_id) # Connect to peer, with the carrier-connection peer_conn = self.cm.connect((peer.interface[0], peer.interface[1])) messages.send_request( peer_conn, type = 'POST', url = '/mifcho/tunnel', headers=[ ('X-Mifcho-Id', self.cm.identifier), ('X-Mifcho-Tunnel-Id', tunnel_id), ] ) # Connect to end-point ep_conn = self.cm.connect(ep_address) if peer_conn and ep_conn: # All is good pipe = Piper(self.cm, peer_conn, ep_conn, 4096, sink_recovery=(ep_address, peer_id)) pipe.start() self.cm.pipes.append(pipe) elif not ep_conn: # Inform peer that we could not create connection self.cm.teardown(conn) else: logging.error('Some other error [%s].' % repr(address)) self.cm.teardown(conn)
def work(self, job): try: (conn, address, data) = job (ep_host, ep_port, peer_id) = data address=(ep_host, ep_port) except: logging.debug("Error when unwrapping arguments...", exc_info=3) try: ep_conn = self.cm.connect(address, peer_id, False) # TODO: tls should be optional if ep_conn: pipe = Piper(self.cm, conn, ep_conn, self.buffer_size) pipe.start() self.cm.pipes.append(pipe) else: logging.error('Failed connecting to endpoint [%s].' % repr(address)) self.cm.teardown(conn) except: logging.debug('Probably a connection-failure... %s.', exc_info=3) self.cm.teardown(conn)