def handle_map_register(received_message, control_plane_sockets, data_plane_sockets): map_register = received_message.message assert isinstance(map_register, MapRegisterMessage) processed_records = [] saved_key = "" for record in map_register.records: assert isinstance(record, MapRegisterRecord) # Look up the address in the tree instance_id, afi, prefix = determine_instance_id_and_afi(record.eid_prefix) tree_node = resolve(instance_id, afi, prefix) if isinstance(tree_node, MapServerNode): try: tree_node.handle_map_register_record( received_message, record, control_plane_sockets, data_plane_sockets ) # Record processed: store the record, and keep the authentication key in case we want to send back a notify processed_records.append(record) saved_key = tree_node.key except MapServerException, e: logger.error("MapServerNode could not process record {0}: {1}".format(record, e.message)) else: logger.warn( u"Received a Map-Register message for {0}" ", but we are not a MapServer for that EID space".format(prefix) )
def handle_map_request(received_message, control_plane_sockets, data_plane_sockets): map_request = received_message.message assert isinstance(map_request, MapRequestMessage) if len(map_request.eid_prefixes) != 1: logger.warn(u"Ignoring message {0}: Map-Request with eid-prefix count != 1".format(received_message.message_nr)) return eid_prefix = map_request.eid_prefixes[0] instance_id, afi, eid_prefix = determine_instance_id_and_afi(eid_prefix) nodes = resolve_path(instance_id, afi, eid_prefix) if not nodes: logger.warn( u"Ignoring message {0}: Map-Request for unknown" " instance {1} with AFI {2}".format(received_message.message_nr, instance_id, afi) ) return if not isinstance(nodes[0], ETRNode): # Not for us: drop logger.warn( u"Ignoring message {0}: Map-Request for prefix {1} in instance {2} " "for which we are not an ETR".format(received_message.message_nr, eid_prefix, instance_id) ) return nodes[0].handle_map_request(received_message, eid_prefix, control_plane_sockets, data_plane_sockets)
def handle_map_register_record(self, received_message, record, control_plane_sockets, data_plane_sockets): assert isinstance(received_message, ReceivedMessage) assert isinstance(record, MapRegisterRecord) map_register = received_message.message assert isinstance(map_register, MapRegisterMessage) # Before we go any further we check the authentication data if not map_register.verify_authentication_data(self.key): raise MapServerAuthenticationError(u"Ignoring a MapRegister message for {0} " "with invalid authentication data".format(record.eid_prefix)) # Extract the prefix info dummy, dummy, prefix = determine_instance_id_and_afi(record.eid_prefix) # Check for invalid prefixes if not prefix.overlaps(self.prefix) \ or prefix.prefixlen < self.prefix.prefixlen: raise MapServerScopeError(u"MapRegister message received by Map-Server {0} for prefix {1}".format(self.prefix, prefix)) # Check for more-specifics if prefix.prefixlen > self.prefix.prefixlen \ and not self.allow_more_specifics: raise MapServerScopeError(u'ETR tried to register more-specific {0} in {1}'.format(prefix, self.prefix)) # Determine canonical source if map_register.xtr_id: source = '{site_id:x}-{xtr_id:x}'.format(site_id=map_register.site_id, xtr_id=map_register.xtr_id) else: source = received_message.source[0] # Store the data for now with self.registrations_lock: if prefix not in self.registrations: self.registrations[prefix] = {} # Store registration locators = ', '.join(map(lambda locator: unicode(locator.address), record.locator_records)) if source not in self.registrations[prefix]: logger.info('New MapServerRegistration from {source} for {prefix}: {locators}'.format(source=source, prefix=prefix, locators=locators)) else: logger.debug('Updating MapServerRegistration from {source} for {prefix}: {locators}'.format(source=source, prefix=prefix, locators=locators)) self.registrations[prefix][source] = MapServerRegistration(proxy_map_reply=map_register.proxy_map_reply, record=record)
def handle_map_notify(received_message, control_plane_sockets, data_plane_sockets): map_notify = received_message.message assert isinstance(map_notify, MapNotifyMessage) for record in map_notify.records: assert isinstance(record, MapRegisterRecord) # Look up the address in the tree instance_id, afi, prefix = determine_instance_id_and_afi(record.eid_prefix) tree_node = resolve(instance_id, afi, prefix) if isinstance(tree_node, ETRNode): tree_node.handle_map_notify_record(received_message, record, control_plane_sockets, data_plane_sockets) else: logger.warn( u"Received a Map-Notify message for {0}" ", but we are not a MapServerClient for that EID space".format(prefix) )
def handle_info_message(received_message, control_plane_sockets, data_plane_sockets): info_message = received_message.message assert isinstance(info_message, InfoMessage) logger.debug("HANDLING {0!r}".format(received_message)) if not received_message.message.is_reply: logger.error(u"We are not an RTR, we can only handle InfoMessage replies") return eid_prefix = info_message.eid_prefix instance_id, afi, eid_prefix = determine_instance_id_and_afi(eid_prefix) node = resolve(instance_id, afi, eid_prefix) if not isinstance(node, ETRNode): # Not for us: drop logger.warn( u"Ignoring message {0}: Info-Message for prefix {1} in instance {2} " "for which we are not an ETR".format(received_message.message_nr, eid_prefix, instance_id) ) return node.handle_info_message_reply(received_message, control_plane_sockets, data_plane_sockets)
def handle_ddt_map_request(received_message, control_plane_sockets, data_plane_sockets): ecm = received_message.message # TODO: Implement security [LISP-Security] if ecm.security: logger.error("We can't handle LISP-Security yet") return # Look up the address in the tree map_request = received_message.inner_message instance_id, afi, req_prefix = determine_instance_id_and_afi(map_request.eid_prefixes[0]) tree_nodes = resolve_path(instance_id, afi, req_prefix) # Find the handling node and its children auth_node = None handling_node = None more_specific_nodes = [] for tree_node in tree_nodes[::-1]: # Mark that we are authoritative for this request if isinstance(tree_node, (AuthContainerNode, MapServerNode)): auth_node = tree_node # Do we already have a handler? if handling_node is not None: # We have a handler, collect the more specific nodes more_specific_nodes.append(tree_node) else: if isinstance(tree_node, DDTReferralNode): # DDTReferralNodes are an answer by themselves handling_node = tree_node break elif isinstance(tree_node, MapServerNode): # MapServerNodes handle themselves handling_node = tree_node break else: # We don't really care about other node types pass # Didn't find any handling node if not handling_node: # We are not authoritative send_not_authoritative(received_message) return # We have all the information: handle it if isinstance(handling_node, DDTReferralNode): # Handle this as a DDT referral referral = handling_node.get_referral() send_answer(received_message, referral) return elif isinstance(tree_node, MapServerNode): # Handle this as a DDT Map-Server # Let he MapServerNode send the Map-Request to the ETR or answer as a proxy handled = handling_node.handle_map_request(received_message, control_plane_sockets, data_plane_sockets) # Send DDT response if handled: send_ms_ack(received_message=received_message, ms_prefix=handling_node.prefix, other_map_servers=(auth_node and auth_node.ddt_nodes or [])) else: send_ms_not_registered(received_message=received_message, ms_prefix=handling_node.prefix, other_map_servers=(auth_node and auth_node.ddt_nodes or [])) elif auth_node: # We are authoritative and no matching targets, we seem to have a hole send_delegation_hole(received_message) else: # We are not authoritative send_not_authoritative(received_message)