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_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)