def terminate_connection(self, conn, why, notify_client=True, log_it=True, lvl=logging.INFO): """Terminates the client connection conn. This event will be logged unless log_it is False. If notify_client is True, then the client will be sent a VNSClose message with an explanation.""" # terminate the client if conn.connected: if notify_client: for m in VNSClose.get_banners_and_close(why): conn.send(m) conn.transport.loseConnection() if log_it: logging.log(lvl, 'terminating client (%s): %s' % (conn, why)) # cleanup client and topology info tid = self.clients.get(conn) if tid is not None: del self.clients[conn] topo = self.topologies[tid] topo.client_disconnected(conn) if not topo.is_active(): if topo.has_gateway(): self.resolver.unregister_topology(topo) with self.topologies_lock: del self.topologies[tid] self.topologies_changed = True DBService.run_and_wait(topo.get_stats().finalize) if topo.is_temporary(): AddressAllocation.free_topology(tid) else: AddressAllocation.deallocate_from_topology(topo.t) for ti_conn in topo.interactors: self.terminate_ti_connection(ti_conn, 'GOODBYE: Topology %d has been shutdown' % tid)
def terminate_connection(self, conn, why, notify_client=True, log_it=True, lvl=logging.INFO): """Terminates the client connection conn. This event will be logged unless log_it is False. If notify_client is True, then the client will be sent a VNSClose message with an explanation.""" # terminate the client if conn.connected: if notify_client: for m in VNSClose.get_banners_and_close(why): conn.send(m) conn.transport.loseConnection() if log_it: logging.log(lvl, 'terminating client (%s): %s' % (conn, why)) # cleanup client and topology info tid = self.clients.get(conn) if tid is not None: del self.clients[conn] topo = self.topologies[tid] topo.client_disconnected(conn) if not topo.is_active(): if topo.has_gateway(): self.resolver.unregister_topology(topo) with self.topologies_lock: del self.topologies[tid] self.topologies_changed = True topo.get_stats().finalize() if topo.is_temporary(): AddressAllocation.free_topology(tid) for ti_conn in topo.interactors: self.terminate_ti_connection(ti_conn, 'GOODBYE: Topology %d has been shutdown' % tid)
def __init__(self): # close out any hanging stats records (shouldn't be any unless the # server was shutdown abnormally with no chance to cleanup) db.UsageStats.objects.filter(active=True).update(active=False) # free any hanging temporary topologies for t in db.Topology.objects.filter(temporary=True): AddressAllocation.free_topology(t.id) self.topologies = {} # maps active topology ID to its Topology object self.resolver = TopologyResolver() # maps MAC/IP addresses to a Topology self.clients = {} # maps active conn to the topology ID it is conn to self.server = create_vns_server(VNS_DEFAULT_PORT, self.handle_recv_msg, self.handle_new_client, self.handle_client_disconnected) self.ti_clients = {} # maps active TI conns to the topology ID it is conn to self.ti_server = create_ti_server(TI_DEFAULT_PORT, self.handle_recv_ti_msg, self.handle_new_client, self.handle_ti_client_disconnected) if BORDER_DEV_NAME: self.__start_raw_socket(BORDER_DEV_NAME) # run pcap in another thread (it will run forever) reactor.callInThread(self.__run_pcap, BORDER_DEV_NAME) else: self.raw_socket = None # lock used to prevent self.topologies from being *changed* by the main # twisted thread while the topology queue service thread is reading it self.topologies_lock = Lock() # communicates from the main twisted thread to the topology queue # service thread that the topologies dictionary has changed self.topologies_changed = False # The topology queue service thread will wait on this condition for a # a chosen/dequeued job to be finish (so it can pick the next one). self.service_condition = Condition() # Is set when a job is enqueued. Is cleared when the queues are empty. # The topology queue service thread will clear this event if it makes a # a pass over all the queues and they are empty. If it makes a pass # and this event is cleared, then it will wait on this event. self.job_available_event = Event() # run the topology queue service thread reactor.callInThread(self.__run_topology_queue_service_thread) self.periodic_callback()
def handle_open_template_msg(self, conn, ot): try: template = DBService.run_and_wait(db.TopologyTemplate.objects.get(name=ot.template_name)) except db.TopologyTemplate.DoesNotExist: self.terminate_connection(conn, "template '%s' does not exist" % ot.template_name) return # find an IP block to allocate IPs from for this user blocks = DBService.run_and_wait(db.IPBlock.objects.filter(org=conn.vns_user_profile.org)) if not blocks: self.terminate_connection(conn, "your organization (%s) has no available IP blocks" % conn.vns_user_profile.org) return ip_block_from = blocks[0] if ot.get_src_filters() == VNSOpenTemplate.NO_SRC_FILTERS: src_filters = [] else: src_filters = ot.get_src_filters() err_msg, topo, alloc, tree = AddressAllocation.instantiate_template(conn.vns_user_profile.user, template, ip_block_from, src_filters, True, True) if err_msg: self.terminate_connection(conn, err_msg) else: s2intfnum = '2' if ot.template_name == '1-router 2-server' else '1' rtable_msg = VNSRtable(ot.vrhost, VNSSimulator.build_rtable(topo, s2intfnum)) conn.send(rtable_msg) logging.debug('Sent client routing table message: %s' % rtable_msg) self.handle_connect_to_topo(conn, topo.id, ot.vrhost)
def handle_open_template_msg(self, conn, ot): try: template = db.TopologyTemplate.objects.get(name=ot.template_name) except db.TopologyTemplate.DoesNotExist: self.terminate_connection(conn, "template '%s' does not exist" % ot.template_name) return # find an IP block to allocate IPs from for this user blocks = db.IPBlock.objects.filter(org=conn.vns_user_profile.org) if not blocks: self.terminate_connection(conn, "your organization (%s) has no available IP blocks" % conn.vns_user_profile.org) return ip_block_from = blocks[0] if ot.get_src_filters() == VNSOpenTemplate.NO_SRC_FILTERS: src_filters = [] else: src_filters = ot.get_src_filters() err_msg, topo, alloc, tree = AddressAllocation.instantiate_template(conn.vns_user_profile.user, template, ip_block_from, src_filters, True, True) if err_msg: self.terminate_connection(conn, err_msg) else: s2intfnum = '2' if ot.template_name == '1-router 2-server' else '1' rtable_msg = VNSRtable(ot.vrhost, VNSSimulator.build_rtable(topo, s2intfnum)) conn.send(rtable_msg) logging.debug('Sent client routing table message: %s' % rtable_msg) self.handle_connect_to_topo(conn, topo.id, ot.vrhost)
def __free_hanging_temp_topos(topos): for t in topos: AddressAllocation.free_topology(t.id)