<?xml version='1.0' encoding='utf-8'?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" version="3" category="info" consensus="false" docName="draft-schanzen-r5n-00" indexInclude="true" ipr="trust200902" prepTime="2022-08-19T18:01:31" scripts="Common,Latin" sortRefs="false" submissionType="IETF" symRefs="true" tocDepth="3" tocInclude="true" xml:lang="en">
  <front>
    <title abbrev="The R5N Distributed Hash Table">The R5N Distributed Hash Table</title>
    <seriesInfo name="Internet-Draft" value="draft-schanzen-r5n-00" stream="IETF"/>
    <author fullname="Martin Schanzenbach" initials="M." surname="Schanzenbach">
      <organization showOnFrontPage="true">GNUnet e.V.</organization>
      <address>
        <postal>
          <street>Boltzmannstrasse 3</street>
          <city>Garching</city>
          <code>85748</code>
          <country>DE</country>
        </postal>
        <email>schanzen@gnunet.org</email>
      </address>
    </author>
    <author fullname="Christian Grothoff" initials="C." surname="Grothoff">
      <organization showOnFrontPage="true">Berner Fachhochschule</organization>
      <address>
        <postal>
          <street>Hoeheweg 80</street>
          <city>Biel/Bienne</city>
          <code>2501</code>
          <country>CH</country>
        </postal>
        <email>grothoff@gnunet.org</email>
      </address>
    </author>
    <author fullname="Bernd Fix" initials="B." surname="Fix">
      <organization showOnFrontPage="true">GNUnet e.V.</organization>
      <address>
        <postal>
          <street>Boltzmannstrasse 3</street>
          <city>Garching</city>
          <code>85748</code>
          <country>DE</country>
        </postal>
        <email>fix@gnunet.org</email>
      </address>
    </author>
    <date day="19" month="08" year="2022"/>
    <!-- Meta-data Declarations -->
    <area>General</area>
    <workgroup>Independent Stream</workgroup>
    <keyword>distributed hash tables</keyword>
    <abstract pn="section-abstract">
      <t indent="0" pn="section-abstract-1">This document contains the R<sup>5</sup>N DHT technical specification.</t>
      <t indent="0" pn="section-abstract-2">
        This document defines the normative wire format of resource records,
        resolution processes, cryptographic routines and security considerations for
        use by implementers.
      </t>
      <t indent="0" pn="section-abstract-3">
        This specification was developed outside the IETF and does not have IETF
        consensus. It is published here to guide implementation of R<sup>5</sup>N and to
        ensure interoperability among implementations.
      </t>
    </abstract>
    <boilerplate>
      <section anchor="status-of-memo" numbered="false" removeInRFC="false" toc="exclude" pn="section-boilerplate.1">
        <name slugifiedName="name-status-of-this-memo">Status of This Memo</name>
        <t indent="0" pn="section-boilerplate.1-1">
        This Internet-Draft is submitted in full conformance with the
        provisions of BCP 78 and BCP 79.
        </t>
        <t indent="0" pn="section-boilerplate.1-2">
        Internet-Drafts are working documents of the Internet Engineering Task
        Force (IETF). Note that other groups may also distribute working
        documents as Internet-Drafts. The list of current Internet-Drafts is
        at <eref target="https://datatracker.ietf.org/drafts/current/" brackets="none"/>.
        </t>
        <t indent="0" pn="section-boilerplate.1-3">
        Internet-Drafts are draft documents valid for a maximum of six months
        and may be updated, replaced, or obsoleted by other documents at any
        time. It is inappropriate to use Internet-Drafts as reference
        material or to cite them other than as "work in progress."
        </t>
        <t indent="0" pn="section-boilerplate.1-4">
        This Internet-Draft will expire on 20 February 2023.
        </t>
      </section>
      <section anchor="copyright" numbered="false" removeInRFC="false" toc="exclude" pn="section-boilerplate.2">
        <name slugifiedName="name-copyright-notice">Copyright Notice</name>
        <t indent="0" pn="section-boilerplate.2-1">
            Copyright (c) 2022 IETF Trust and the persons identified as the
            document authors. All rights reserved.
        </t>
        <t indent="0" pn="section-boilerplate.2-2">
            This document is subject to BCP 78 and the IETF Trust's Legal
            Provisions Relating to IETF Documents
            (<eref target="https://trustee.ietf.org/license-info" brackets="none"/>) in effect on the date of
            publication of this document. Please review these documents
            carefully, as they describe your rights and restrictions with
            respect to this document. Code Components extracted from this
            document must include Revised BSD License text as described in
            Section 4.e of the Trust Legal Provisions and are provided without
            warranty as described in the Revised BSD License.
        </t>
      </section>
    </boilerplate>
    <toc>
      <section anchor="toc" numbered="false" removeInRFC="false" toc="exclude" pn="section-toc.1">
        <name slugifiedName="name-table-of-contents">Table of Contents</name>
        <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1">
          <li pn="section-toc.1-1.1">
            <t indent="0" keepWithNext="true" pn="section-toc.1-1.1.1"><xref derivedContent="1" format="counter" sectionFormat="of" target="section-1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-introduction">Introduction</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.1.2">
              <li pn="section-toc.1-1.1.2.1">
                <t indent="0" keepWithNext="true" pn="section-toc.1-1.1.2.1.1"><xref derivedContent="1.1" format="counter" sectionFormat="of" target="section-1.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-requirements-notation">Requirements Notation</xref></t>
              </li>
              <li pn="section-toc.1-1.1.2.2">
                <t indent="0" keepWithNext="true" pn="section-toc.1-1.1.2.2.1"><xref derivedContent="1.2" format="counter" sectionFormat="of" target="section-1.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-structure-of-this-document">Structure of This Document</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.2">
            <t indent="0" pn="section-toc.1-1.2.1"><xref derivedContent="2" format="counter" sectionFormat="of" target="section-2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-terminology">Terminology</xref></t>
          </li>
          <li pn="section-toc.1-1.3">
            <t indent="0" pn="section-toc.1-1.3.1"><xref derivedContent="3" format="counter" sectionFormat="of" target="section-3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-architecture">Architecture</xref></t>
          </li>
          <li pn="section-toc.1-1.4">
            <t indent="0" pn="section-toc.1-1.4.1"><xref derivedContent="4" format="counter" sectionFormat="of" target="section-4"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-application-api">Application API</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.4.2">
              <li pn="section-toc.1-1.4.2.1">
                <t indent="0" pn="section-toc.1-1.4.2.1.1"><xref derivedContent="4.1" format="counter" sectionFormat="of" target="section-4.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-the-get-procedure">The GET procedure</xref></t>
              </li>
              <li pn="section-toc.1-1.4.2.2">
                <t indent="0" pn="section-toc.1-1.4.2.2.1"><xref derivedContent="4.2" format="counter" sectionFormat="of" target="section-4.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-the-put-procedure">The PUT procedure</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.5">
            <t indent="0" pn="section-toc.1-1.5.1"><xref derivedContent="5" format="counter" sectionFormat="of" target="section-5"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-underlay">Underlay</xref></t>
          </li>
          <li pn="section-toc.1-1.6">
            <t indent="0" pn="section-toc.1-1.6.1"><xref derivedContent="6" format="counter" sectionFormat="of" target="section-6"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-bootstrapping">Bootstrapping</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.6.2">
              <li pn="section-toc.1-1.6.2.1">
                <t indent="0" pn="section-toc.1-1.6.2.1.1"><xref derivedContent="6.1" format="counter" sectionFormat="of" target="section-6.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-hello-urls">HELLO URLs</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.7">
            <t indent="0" pn="section-toc.1-1.7.1"><xref derivedContent="7" format="counter" sectionFormat="of" target="section-7"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-bloom-filters">Bloom Filters</xref></t>
          </li>
          <li pn="section-toc.1-1.8">
            <t indent="0" pn="section-toc.1-1.8.1"><xref derivedContent="8" format="counter" sectionFormat="of" target="section-8"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-routing">Routing</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.8.2">
              <li pn="section-toc.1-1.8.2.1">
                <t indent="0" pn="section-toc.1-1.8.2.1.1"><xref derivedContent="8.1" format="counter" sectionFormat="of" target="section-8.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-routing-table">Routing Table</xref></t>
              </li>
              <li pn="section-toc.1-1.8.2.2">
                <t indent="0" pn="section-toc.1-1.8.2.2.1"><xref derivedContent="8.2" format="counter" sectionFormat="of" target="section-8.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-peer-discovery">Peer Discovery</xref></t>
              </li>
              <li pn="section-toc.1-1.8.2.3">
                <t indent="0" pn="section-toc.1-1.8.2.3.1"><xref derivedContent="8.3" format="counter" sectionFormat="of" target="section-8.3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-peer-bloom-filter">Peer Bloom Filter</xref></t>
              </li>
              <li pn="section-toc.1-1.8.2.4">
                <t indent="0" pn="section-toc.1-1.8.2.4.1"><xref derivedContent="8.4" format="counter" sectionFormat="of" target="section-8.4"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-routing-functions">Routing Functions</xref></t>
              </li>
              <li pn="section-toc.1-1.8.2.5">
                <t indent="0" pn="section-toc.1-1.8.2.5.1"><xref derivedContent="8.5" format="counter" sectionFormat="of" target="section-8.5"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-pending-table">Pending Table</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.9">
            <t indent="0" pn="section-toc.1-1.9.1"><xref derivedContent="9" format="counter" sectionFormat="of" target="section-9"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-message-processing">Message Processing</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.9.2">
              <li pn="section-toc.1-1.9.2.1">
                <t indent="0" pn="section-toc.1-1.9.2.1.1"><xref derivedContent="9.1" format="counter" sectionFormat="of" target="section-9.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-message-components">Message components</xref></t>
                <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.9.2.1.2">
                  <li pn="section-toc.1-1.9.2.1.2.1">
                    <t indent="0" pn="section-toc.1-1.9.2.1.2.1.1"><xref derivedContent="9.1.1" format="counter" sectionFormat="of" target="section-9.1.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-flags">Flags</xref></t>
                  </li>
                  <li pn="section-toc.1-1.9.2.1.2.2">
                    <t indent="0" pn="section-toc.1-1.9.2.1.2.2.1"><xref derivedContent="9.1.2" format="counter" sectionFormat="of" target="section-9.1.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-path-element">Path Element</xref></t>
                  </li>
                </ul>
              </li>
              <li pn="section-toc.1-1.9.2.2">
                <t indent="0" pn="section-toc.1-1.9.2.2.1"><xref derivedContent="9.2" format="counter" sectionFormat="of" target="section-9.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-hellomessage">HelloMessage</xref></t>
                <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.9.2.2.2">
                  <li pn="section-toc.1-1.9.2.2.2.1">
                    <t indent="0" pn="section-toc.1-1.9.2.2.2.1.1"><xref derivedContent="9.2.1" format="counter" sectionFormat="of" target="section-9.2.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-wire-format">Wire Format</xref></t>
                  </li>
                  <li pn="section-toc.1-1.9.2.2.2.2">
                    <t indent="0" pn="section-toc.1-1.9.2.2.2.2.1"><xref derivedContent="9.2.2" format="counter" sectionFormat="of" target="section-9.2.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-processing">Processing</xref></t>
                  </li>
                </ul>
              </li>
              <li pn="section-toc.1-1.9.2.3">
                <t indent="0" pn="section-toc.1-1.9.2.3.1"><xref derivedContent="9.3" format="counter" sectionFormat="of" target="section-9.3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-putmessage">PutMessage</xref></t>
                <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.9.2.3.2">
                  <li pn="section-toc.1-1.9.2.3.2.1">
                    <t indent="0" pn="section-toc.1-1.9.2.3.2.1.1"><xref derivedContent="9.3.1" format="counter" sectionFormat="of" target="section-9.3.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-wire-format-2">Wire Format</xref></t>
                  </li>
                  <li pn="section-toc.1-1.9.2.3.2.2">
                    <t indent="0" pn="section-toc.1-1.9.2.3.2.2.1"><xref derivedContent="9.3.2" format="counter" sectionFormat="of" target="section-9.3.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-processing-2">Processing</xref></t>
                  </li>
                </ul>
              </li>
              <li pn="section-toc.1-1.9.2.4">
                <t indent="0" pn="section-toc.1-1.9.2.4.1"><xref derivedContent="9.4" format="counter" sectionFormat="of" target="section-9.4"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-getmessage">GetMessage</xref></t>
                <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.9.2.4.2">
                  <li pn="section-toc.1-1.9.2.4.2.1">
                    <t indent="0" pn="section-toc.1-1.9.2.4.2.1.1"><xref derivedContent="9.4.1" format="counter" sectionFormat="of" target="section-9.4.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-wire-format-3">Wire Format</xref></t>
                  </li>
                  <li pn="section-toc.1-1.9.2.4.2.2">
                    <t indent="0" pn="section-toc.1-1.9.2.4.2.2.1"><xref derivedContent="9.4.2" format="counter" sectionFormat="of" target="section-9.4.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-result-filter">Result Filter</xref></t>
                  </li>
                  <li pn="section-toc.1-1.9.2.4.2.3">
                    <t indent="0" pn="section-toc.1-1.9.2.4.2.3.1"><xref derivedContent="9.4.3" format="counter" sectionFormat="of" target="section-9.4.3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-processing-3">Processing</xref></t>
                  </li>
                </ul>
              </li>
              <li pn="section-toc.1-1.9.2.5">
                <t indent="0" pn="section-toc.1-1.9.2.5.1"><xref derivedContent="9.5" format="counter" sectionFormat="of" target="section-9.5"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-resultmessage">ResultMessage</xref></t>
                <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.9.2.5.2">
                  <li pn="section-toc.1-1.9.2.5.2.1">
                    <t indent="0" pn="section-toc.1-1.9.2.5.2.1.1"><xref derivedContent="9.5.1" format="counter" sectionFormat="of" target="section-9.5.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-wire-format-4">Wire Format</xref></t>
                  </li>
                  <li pn="section-toc.1-1.9.2.5.2.2">
                    <t indent="0" pn="section-toc.1-1.9.2.5.2.2.1"><xref derivedContent="9.5.2" format="counter" sectionFormat="of" target="section-9.5.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-processing-4">Processing</xref></t>
                  </li>
                </ul>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.10">
            <t indent="0" pn="section-toc.1-1.10.1"><xref derivedContent="10" format="counter" sectionFormat="of" target="section-10"/>. <xref derivedContent="" format="title" sectionFormat="of" target="name-blocks">Blocks</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.10.2">
              <li pn="section-toc.1-1.10.2.1">
                <t indent="0" pn="section-toc.1-1.10.2.1.1"><xref derivedContent="10.1" format="counter" sectionFormat="of" target="section-10.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-block-operations">Block Operations</xref></t>
              </li>
              <li pn="section-toc.1-1.10.2.2">
                <t indent="0" pn="section-toc.1-1.10.2.2.1"><xref derivedContent="10.2" format="counter" sectionFormat="of" target="section-10.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-hello-blocks">HELLO Blocks</xref></t>
              </li>
              <li pn="section-toc.1-1.10.2.3">
                <t indent="0" pn="section-toc.1-1.10.2.3.1"><xref derivedContent="10.3" format="counter" sectionFormat="of" target="section-10.3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-persistence">Persistence</xref></t>
                <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.10.2.3.2">
                  <li pn="section-toc.1-1.10.2.3.2.1">
                    <t indent="0" pn="section-toc.1-1.10.2.3.2.1.1"><xref derivedContent="10.3.1" format="counter" sectionFormat="of" target="section-10.3.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-approximate-search-consider">Approximate Search Considerations</xref></t>
                  </li>
                  <li pn="section-toc.1-1.10.2.3.2.2">
                    <t indent="0" pn="section-toc.1-1.10.2.3.2.2.1"><xref derivedContent="10.3.2" format="counter" sectionFormat="of" target="section-10.3.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-caching-strategy-considerat">Caching Strategy Considerations</xref></t>
                  </li>
                </ul>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.11">
            <t indent="0" pn="section-toc.1-1.11.1"><xref derivedContent="11" format="counter" sectionFormat="of" target="section-11"/>. <xref derivedContent="" format="title" sectionFormat="of" target="name-security-considerations">Security Considerations</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.11.2">
              <li pn="section-toc.1-1.11.2.1">
                <t indent="0" pn="section-toc.1-1.11.2.1.1"><xref derivedContent="11.1" format="counter" sectionFormat="of" target="section-11.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-approximate-result-filterin">Approximate Result Filtering</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.12">
            <t indent="0" pn="section-toc.1-1.12.1"><xref derivedContent="12" format="counter" sectionFormat="of" target="section-12"/>. <xref derivedContent="" format="title" sectionFormat="of" target="name-iana-considerations">IANA Considerations</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.12.2">
              <li pn="section-toc.1-1.12.2.1">
                <t indent="0" pn="section-toc.1-1.12.2.1.1"><xref derivedContent="12.1" format="counter" sectionFormat="of" target="section-12.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-gnunet-uri-scheme-registrat">GNUnet URI Scheme Registration</xref></t>
              </li>
              <li pn="section-toc.1-1.12.2.2">
                <t indent="0" pn="section-toc.1-1.12.2.2.1"><xref derivedContent="12.2" format="counter" sectionFormat="of" target="section-12.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-r5n-uri-scheme-registration">R5N URI Scheme Registration</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.13">
            <t indent="0" pn="section-toc.1-1.13.1"><xref derivedContent="13" format="counter" sectionFormat="of" target="section-13"/>. <xref derivedContent="" format="title" sectionFormat="of" target="name-gana-considerations">GANA Considerations</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.13.2">
              <li pn="section-toc.1-1.13.2.1">
                <t indent="0" pn="section-toc.1-1.13.2.1.1"><xref derivedContent="13.1" format="counter" sectionFormat="of" target="section-13.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-block-type-registry">Block Type Registry</xref></t>
              </li>
              <li pn="section-toc.1-1.13.2.2">
                <t indent="0" pn="section-toc.1-1.13.2.2.1"><xref derivedContent="13.2" format="counter" sectionFormat="of" target="section-13.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-gnunet-uri-schema-subregist">GNUnet URI schema Subregistry</xref></t>
              </li>
              <li pn="section-toc.1-1.13.2.3">
                <t indent="0" pn="section-toc.1-1.13.2.3.1"><xref derivedContent="13.3" format="counter" sectionFormat="of" target="section-13.3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-gnunet-signature-purpose-re">GNUnet Signature Purpose Registry</xref></t>
              </li>
              <li pn="section-toc.1-1.13.2.4">
                <t indent="0" pn="section-toc.1-1.13.2.4.1"><xref derivedContent="13.4" format="counter" sectionFormat="of" target="section-13.4"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-gnunet-message-type-registr">GNUnet Message Type Registry</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.14">
            <t indent="0" pn="section-toc.1-1.14.1"><xref derivedContent="14" format="counter" sectionFormat="of" target="section-14"/>. <xref derivedContent="" format="title" sectionFormat="of" target="name-test-vectors">Test Vectors</xref></t>
          </li>
          <li pn="section-toc.1-1.15">
            <t indent="0" pn="section-toc.1-1.15.1"><xref derivedContent="15" format="counter" sectionFormat="of" target="section-15"/>. <xref derivedContent="" format="title" sectionFormat="of" target="name-normative-references">Normative References</xref></t>
          </li>
          <li pn="section-toc.1-1.16">
            <t indent="0" pn="section-toc.1-1.16.1"><xref derivedContent="16" format="counter" sectionFormat="of" target="section-16"/>. <xref derivedContent="" format="title" sectionFormat="of" target="name-informative-references">Informative References</xref></t>
          </li>
          <li pn="section-toc.1-1.17">
            <t indent="0" pn="section-toc.1-1.17.1"><xref derivedContent="" format="none" sectionFormat="of" target="section-appendix.a"/><xref derivedContent="" format="title" sectionFormat="of" target="name-authors-addresses">Authors' Addresses</xref></t>
          </li>
        </ul>
      </section>
    </toc>
  </front>
  <middle>
    <section anchor="introduction" numbered="true" toc="include" removeInRFC="false" pn="section-1">
      <name slugifiedName="name-introduction">Introduction</name>
      <!--
          - Lean. Can be implemented. Not overengineered.
          - Path tracking (more difficult) -> Not built in
          - Certificates central server ?
          - "self-signed certificates can be used in closed networks."
          - "Security Framework:  A P2P network will often be established among a
      set of peers that do not trust each other.  RELOAD leverages a
      central enrollment server to provide credentials for each peer,
      which can then be used to authenticate each operation.  This
          greatly reduces the possible attack surface." bizarre statement.
          - For a PUT, reload requires that
          "Each element is signed by a credential which is authorized to
      write this Kind at this Resource-ID.  If this check fails, the
      request <bcp14>MUST</bcp14> be rejected with an Error_Forbidden error."
        -->
        <!--FIXME: Here we should also cite and discuss RELOAD (https://datatracker.ietf.org/doc/html/rfc6940)
        and establish why we need this spec and are not a "Topology plugin"
        in RELOAD. The argumentation revolves around the trust model (openness) and
        security aspects (path signatures).-->
      <t indent="0" pn="section-1-1">
        Distributed Hash Tables (DHTs) are a key data structure for the
        construction of decentralized applications.
        DHTs are important because they generally provide a robust and
        efficient means to distribute the storage and retrieval of
        key-value pairs.
      </t>
      <t indent="0" pn="section-1-2">
        While <xref target="RFC6940" format="default" sectionFormat="of" derivedContent="RFC6940"/> already provides a peer-to-peer (P2P)
        signaling protocol with extensible routing and topology mechanisms,
        it also relies on strict admission control through the use of either
        centralized enrollment servers or pre-shared keys.
        Some decentralized applications require a more open system that
        enables ad-hoc participation and other means to prevent common attacks
        on P2P overlays.
      </t>
      <t indent="0" pn="section-1-3">
        This document contains the technical specification
        of the R<sup>5</sup>N DHT <xref target="R5N" format="default" sectionFormat="of" derivedContent="R5N"/>, a secure DHT routing algorithm
        and data structure for decentralized applications.
        R<sup>5</sup>N is an open P2P overlay routing mechanism which supports ad-hoc
        permissionless participation and support for
        topologies in restricted-route environments.  R<sup>5</sup>N also
	includes advanced features like tracing paths messages take through the
	network, response filters and on-path application-specific data validation.
      </t>
      <t indent="0" pn="section-1-4">
        This document defines the normative wire format of peer-to-peer
        messages, routing algorithms, cryptographic routines and security
        considerations for use by implementors.
      </t>
      <section numbered="true" toc="include" removeInRFC="false" pn="section-1.1">
        <name slugifiedName="name-requirements-notation">Requirements Notation</name>
        <t indent="0" pn="section-1.1-1">
          The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
          "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
          "OPTIONAL" in this document are to be interpreted as described in
          BCP 14 <xref target="RFC2119" format="default" sectionFormat="of" derivedContent="RFC2119"/> <xref target="RFC8174" format="default" sectionFormat="of" derivedContent="RFC8174"/> when, and only
          when, they appear in all capitals, as shown here.
        </t>
      </section>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-1.2">
        <name slugifiedName="name-structure-of-this-document">Structure of This Document</name>
        <t indent="0" pn="section-1.2-1">
            <xref target="terminology" format="default" sectionFormat="of" derivedContent="Section 2"/> gives an overview of the terminology used in
	    this document.
	    <xref target="architecture" format="default" sectionFormat="of" derivedContent="Section 3"/> then describes the overall architecture and
	    the scope of this specification.
	    <xref target="overlay" format="default" sectionFormat="of" derivedContent="Section 4"/> describes the application API, which clarifies
	    the semantics provided by R<sup>5</sup>N for applications
	    and thus is crucial as it motivates the rest of the design.
	    <xref target="underlay" format="default" sectionFormat="of" derivedContent="Section 5"/> describes the underlay interface. This is the
	    abstraction that applications must provide to R<sup>5</sup>N
	    and thus a prerequisite for using the DHT.
	    Before a DHT is usable, it must be bootstrapped.
	    Bootstrapping is described in <xref target="bootstrapping" format="default" sectionFormat="of" derivedContent="Section 6"/>.
	    Bloom filters, a key data structure used in various
	    places, are introduced in <xref target="bloom_filters" format="default" sectionFormat="of" derivedContent="Section 7"/>
	    The central operation of a DHT is routing, which is
	    detailed in <xref target="routing" format="default" sectionFormat="of" derivedContent="Section 8"/>. The processing of the various
	    network messages is described in <xref target="p2p_messages" format="default" sectionFormat="of" derivedContent="Section 9"/>.  Handling
	    of Blocks, including validation and storage are described
	    in <xref target="blockstorage" format="default" sectionFormat="of" derivedContent="Section 10"/>. General security considerations are detailed
	    in <xref target="security" format="default" sectionFormat="of" derivedContent="Section 11"/>. IANA and GANA registry updates are listed
	    in <xref target="iana" format="default" sectionFormat="of" derivedContent="Section 12"/> and <xref target="gana" format="default" sectionFormat="of" derivedContent="Section 13"/>. The document concludes with test
	    vectors in <xref target="testvectors" format="default" sectionFormat="of" derivedContent="Section 14"/> and appendices with references.
        </t>
      </section>
    </section>
    <section anchor="terminology" numbered="true" removeInRFC="false" toc="include" pn="section-2">
      <name slugifiedName="name-terminology">Terminology</name>
      <dl indent="3" newline="false" spacing="normal" pn="section-2-1">
        <dt pn="section-2-1.1">Peer:</dt>
        <dd pn="section-2-1.2">
          A host that is participating in the overlay.  Peers are
          responsible for holding some portion of the data that has been
          stored in the overlay, and they are responsible for routing
          messages on behalf of other hosts as needed by the Routing
          Algorithm.
        </dd>
        <dt pn="section-2-1.3">Peer ID:</dt>
        <dd pn="section-2-1.4">
          The <tt>Peer ID</tt> is the public key which is used to authenticate
          a peer in the underlay.
         The Peer ID is the public key of the corresponding
         Ed25519<xref target="ed25519" format="default" sectionFormat="of" derivedContent="ed25519"/> peer private key.

        </dd>
        <dt pn="section-2-1.5">Peer Address:</dt>
        <dd pn="section-2-1.6">
          The <tt>Peer Address</tt> is the identifier used on the Overlay
          to address a peer.
	  It is a SHA-512 hash of the <tt>Peer ID</tt>.
        </dd>
        <dt pn="section-2-1.7">Key</dt>
        <dd pn="section-2-1.8">
          512-bit identifier of a location in the DHT. Multiple <tt>Block</tt>s can be
	  stored under the same key. <tt>Peer Addresses</tt> are valid keys.
        </dd>
        <dt pn="section-2-1.9">Neighbor:</dt>
        <dd pn="section-2-1.10">
          A neighbor is a peer which is directly able to communicate
	  with our peer via the <tt>Underlay Interface</tt>.
        </dd>
        <dt pn="section-2-1.11">Block:</dt>
        <dd pn="section-2-1.12">
          Variable-size unit of payload stored in the DHT
	  under a <tt>Key</tt>. Commonly also called a "value" when talking
	  about a DHT as a "key-value store".
        </dd>
        <dt pn="section-2-1.13">Block-Type:</dt>
        <dd pn="section-2-1.14">
          A unique 32-bit value identifying the data format of a <tt>Block</tt>.
          Block-Types are either private or allocated by GANA (see <xref target="gana" format="default" sectionFormat="of" derivedContent="Section 13"/>).
        </dd>
        <dt pn="section-2-1.15">Block Storage</dt>
        <dd pn="section-2-1.16">
          The <tt>Block Storage</tt> component is used to persist and manage <tt>Block</tt> data
          by peers. It includes logic for enforcing storage quotas, caching strategies and
          data validation.
        </dd>
        <dt pn="section-2-1.17">Responsible Peer:</dt>
        <dd pn="section-2-1.18">
          The peer <tt>N</tt> that is responsible for a specific key <tt>K</tt>, as defined by
          the <tt>SelectClosestPeer(K, P)</tt> algorithm (see <xref target="routing" format="default" sectionFormat="of" derivedContent="Section 8"/>.
        </dd>
        <dt pn="section-2-1.19">Applications</dt>
        <dd pn="section-2-1.20">
          Applications are components which directly use the DHT overlay
          interfaces. Possible applications include the GNU Name System
          <xref target="I-D.draft-schanzen-gns" format="default" sectionFormat="of" derivedContent="I-D.draft-schanzen-gns"/> and the CADET transport system
          <xref target="cadet" format="default" sectionFormat="of" derivedContent="cadet"/>.
        </dd>
        <dt pn="section-2-1.21">Application API</dt>
        <dd pn="section-2-1.22">
          The application API exposes the core operations of the DHT overlay
          to applications.
          This includes storing blocks in the DHT and retrieving blocks from the DHT.
        </dd>
        <dt pn="section-2-1.23">Message Processing</dt>
        <dd pn="section-2-1.24">
          The Message Processing component processes requests from and
	  generates responses to applications and the underlay network.
        </dd>
        <dt pn="section-2-1.25">Routing</dt>
        <dd pn="section-2-1.26">
          The Routing component includes the routing table as well as
          routing and peer selection logic. It facilitates the R<sup>5</sup>N routing
          algorithm with required data structures and algorithms.
        </dd>
        <dt pn="section-2-1.27">Underlay Interface</dt>
        <dd pn="section-2-1.28">
          The Underlay Interface is an abstraction layer on top of the
          supported links of a peer. Peers may be linked by a variety of
          different transports, including "classical" protocols such as
          TCP, UDP and TLS or advanced protocols such as GNUnet, I2P or Tor.
        </dd>
      </dl>
    </section>
    <section anchor="architecture" numbered="true" toc="include" removeInRFC="false" pn="section-3">
      <name slugifiedName="name-architecture">Architecture</name>
      <t indent="0" pn="section-3-1">
        R<sup>5</sup>N is an overlay network with a pluggable transport layer.
        The following figure shows the R<sup>5</sup>N architecture.
      </t>
      <figure align="left" suppress-title="false" pn="figure-1">
        <name slugifiedName="name-the-r5n-architecture">The R5N Architecture.</name>
        <artwork align="left" pn="section-3-2.1">
             |  +-----------------+  +-------+
Applications |  | GNU Name System |  | CADET |  ...
             |  +-----------------+  +-------+
-------------+------------------------------------ Application API
             |  ^
             |  |   +---------------+
             |  |   | Block Storage |
             |  |   +---------------+
             |  |    ^
R5N          |  v    v
             | +--------------------+    +---------+
             | | Message Processing |&lt;--&gt;| Routing |
             | +--------------------+    +---------+
             |  ^                          ^
             |  v                          v
-------------+------------------------------------ Underlay Interface
             | +--------+  +--------+
             | |GNUnet  |  |IP      |  ...
Connectivity | |Underlay|  |Underlay|
             | |Link    |  |Link    |
             | +--------+  +--------+

        </artwork>
      </figure>
      <t indent="0" pn="section-3-3">
        Specifics about the protocols of the underlays providing
	connectivity or the applications using the DHT are out of
	the scope of this document.  However, we note that peers
	implementing disjoint sets of underlay protocols may
	experience difficulties communicating (unless other peers
	bridge the respective underlays). Similarly, peers that
	do not support a particular application will not be able
	to validate application-specific payloads and may thus be
	tricked into storing or forwarding corrupt blocks.
      </t>
    </section>
    <section anchor="overlay" numbered="true" toc="include" removeInRFC="false" pn="section-4">
      <name slugifiedName="name-application-api">Application API</name>
      <t indent="0" pn="section-4-1">
        An implementation of this specification commonly exposes the two API
        procedures "GET" and "PUT".
        The following are non-normative examples of such APIs and their
        behaviour are detailed in order to give implementers a fuller picture of the protocol.
      </t>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-4.1">
        <name slugifiedName="name-the-get-procedure">The GET procedure</name>
        <t indent="0" pn="section-4.1-1">
          A basic GET procedure may be exposed as:
        </t>
        <t indent="0" pn="section-4.1-2">
          <tt>GET(Query-Key, Block-Type) -&gt; Results as List</tt>
        </t>
        <t indent="0" pn="section-4.1-3">
          The procedure typically takes at least two arguments to initiate a lookup:
        </t>
        <dl indent="3" newline="false" spacing="normal" pn="section-4.1-4">
          <dt pn="section-4.1-4.1"><tt>QueryKey</tt>:</dt>
          <dd pn="section-4.1-4.2">
            is the 512-bit key to look for in the DHT.
          </dd>
          <dt pn="section-4.1-4.3">Block-Type:</dt>
          <dd pn="section-4.1-4.4">
            is the type of block to look for, possibly "any".
          </dd>
        </dl>
        <t indent="0" pn="section-4.1-5">
          The GET procedure may allow a set of optional parameters in order to
          control or modify the query:
        </t>
        <dl indent="3" newline="false" spacing="normal" pn="section-4.1-6">
          <dt pn="section-4.1-6.1">Replication-Level:</dt>
          <dd pn="section-4.1-6.2">
            is an integer which controls how many nearest peers the request
            should reach.
          </dd>
          <dt pn="section-4.1-6.3">Flags:</dt>
          <dd pn="section-4.1-6.4">
            is a 16-bit vector which indicates certain
            processing requirements for messages.
            Any combination of flags as defined in <xref target="route_flags" format="default" sectionFormat="of" derivedContent="Section 9.1.1"/>
            may be specified.
          </dd>
          <dt pn="section-4.1-6.5">eXtended-Query (XQuery):</dt>
          <dd pn="section-4.1-6.6">
            is medatadata which may be
            required depending on the respective <tt>Block-Type</tt>.
            A <tt>Block-Type</tt> must define if the <tt>XQuery</tt> can or must
            be used and what the specific format of its contents should be.
            Extended queries are in general used to implement domain-specific filters.
            These might be particularly useful in combination with FindApproximate
            to add a well-defined filter by an application-specific distance.
            Regardless, the DHT does not define any particular semantics for an XQuery.
            See also <xref target="blockstorage" format="default" sectionFormat="of" derivedContent="Section 10"/>.
          </dd>
          <dt pn="section-4.1-6.7">Result-Filter:</dt>
          <dd pn="section-4.1-6.8">
            is data for a <tt>Block-type</tt>-specific filter
	    which allows applications to
	    indicate results which are
	    not relevant anymore to the
            caller (see <xref target="result_filter" format="default" sectionFormat="of" derivedContent="Section 9.4.2"/>).
          </dd>
        </dl>
        <t indent="0" pn="section-4.1-7">
          The GET procedure should be implemented as an asynchronous
	  operation that returns individual results as they are found
	  in the DHT.  It should terminate only once the application
	  explicitly cancels the operation.  A single result commonly
	  consists of:</t>
        <dl indent="3" newline="false" spacing="normal" pn="section-4.1-8">
          <dt pn="section-4.1-8.1">Block-Type:</dt>
          <dd pn="section-4.1-8.2">
            is the desired type of block in the result.
          </dd>
          <dt pn="section-4.1-8.3">Block-Data:</dt>
          <dd pn="section-4.1-8.4">
            is the application-specific block payload. Contents are specific to the <tt>Block-Type</tt>.
          </dd>
          <dt pn="section-4.1-8.5">Block-Expiration:</dt>
          <dd pn="section-4.1-8.6">
            is the expiration time of the block. After this time, the result should no
	    longer be used.
          </dd>
          <dt pn="section-4.1-8.7">Key:</dt>
          <dd pn="section-4.1-8.8">
            is the key under which the block was stored. This may be different from the
            key that was queried if the flag FindApproximate was set.
          </dd>
          <dt pn="section-4.1-8.9">GET-Path:</dt>
          <dd pn="section-4.1-8.10">
            is a signed path of the IDs of peers which the query
	    traversed through the network. The DHT will try to make
	    the path available if the <tt>RecordRoute</tt> flag was set by
	    the application calling the PUT procedure. The reported
	    path may have been silently truncated from the beginning.
          </dd>
          <dt pn="section-4.1-8.11">PUT-Path:</dt>
          <dd pn="section-4.1-8.12">
            is a signed path of the IDs of peers which the
	    result message traversed.  The DHT will try to make the
	    path available if the <tt>RecordRoute</tt> flag was set for the GET procedure.
	    The reported path may have been silently truncated from the beginning.
	    As the block was cached by the node at the end of this
	    path, this path is more likely to be stale compared to the
	    <tt>GET-Path</tt>.
          </dd>
        </dl>
      </section>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-4.2">
        <name slugifiedName="name-the-put-procedure">The PUT procedure</name>
        <t indent="0" pn="section-4.2-1">
          A PUT procedure may be exposed as:
        </t>
        <t indent="0" pn="section-4.2-2">
          <tt>PUT(Key, Block-Type, Block-Expiration, Block-Data)</tt>
        </t>
        <t indent="0" pn="section-4.2-3">
          The procedure typically takes at least four parameters:
        </t>
        <dl indent="3" newline="false" spacing="normal" pn="section-4.2-4">
          <dt pn="section-4.2-4.1">Key:</dt>
          <dd pn="section-4.2-4.2">is the key under which to store the block.</dd>
          <dt pn="section-4.2-4.3">Block-Type:</dt>
          <dd pn="section-4.2-4.4">is the type of the block to store.</dd>
          <dt pn="section-4.2-4.5">Block-Expiration:</dt>
          <dd pn="section-4.2-4.6">specifies when the block should expire.</dd>
          <dt pn="section-4.2-4.7">Block-Data:</dt>
          <dd pn="section-4.2-4.8">is the application-specific payload of the block to store.</dd>
        </dl>
        <t indent="0" pn="section-4.2-5">
          The PUT procedure may allow a set of optional parameters in order to
          control or modify the query:
        </t>
        <dl indent="3" newline="false" spacing="normal" pn="section-4.2-6">
          <dt pn="section-4.2-6.1">Replication-Level:</dt>
          <dd pn="section-4.2-6.2">
            is an integer which controls how many nearest peers the request
            should reach.
          </dd>
          <dt pn="section-4.2-6.3">Flags:</dt>
          <dd pn="section-4.2-6.4">
            is a bit-vector which indicates certain
            processing requirements for messages.
            Any combination of flags as defined in <xref target="route_flags" format="default" sectionFormat="of" derivedContent="Section 9.1.1"/>
            may be specified.
          </dd>
        </dl>
        <t indent="0" pn="section-4.2-7">
          The PUT procedure does not necessarily yield any information.
        </t>
      </section>
    </section>
    <section anchor="underlay" numbered="true" toc="include" removeInRFC="false" pn="section-5">
      <name slugifiedName="name-underlay">Underlay</name>
      <t indent="0" pn="section-5-1">
        In the network underlay, a peer is addressable by traditional
        means out of scope of this document. For example, the peer may
        have a TCP/IP address, or a HTTPS endpoint.
        While the specific addressing options and mechanisms are out of scope
        for this document, it is necessary to define a universal addressing
        format in order to facilitate the distribution of connectivity
        information to other peers in the DHT overlay.
        This format is the "HELLO" Block (described in <xref target="hello_block" format="default" sectionFormat="of" derivedContent="Section 10.2"/>),
	which contains URIs. The scheme of each URI indicates which underlay understands the
	respective address given in the rest of the URI.
      </t>
      <!--
        1) The current API is always fire+forget, it doesn't allow for flow
        control. I think we need to add that, possibly for sending and receiving.

        IDK.

        2) I'm not sure what to do with the crypto: mandate EdDSA or allow the
        underlay to do whatever public keys it likes.

        We need keys in the overlay. (Path signatures). Do they need to
        be the same keys???

        3) I think we may want to mandate that the lower layer at least
        authenticate the other peer (i.e. every UDP message could be in
        cleartext, but would need to come with an EdDSA signature, alas 92 byte
        overhead and a signature verification _required_).  Otherwise, I don't
        see how we can offer even the most minimal protections against peer
        impersonation attacks. WDYT?

        Security considerations? Prerequisites?
      -->
      <t indent="0" pn="section-5-2">
        It is expected that the underlay provides basic mechanisms to
        manage peer connectivity and addressing.
        The required functionalities can be represented by the following
        API:
      </t>
      <dl indent="3" newline="false" spacing="normal" pn="section-5-3">
        <dt pn="section-5-3.1">
          <tt>TRY_CONNECT(N, A)</tt>
        </dt>
        <dd pn="section-5-3.2">
          A function which allows the local peer to attempt the establishment of
          a connection to another peer <tt>N</tt> using an address <tt>A</tt>.
          When the connection attempt is successful, information on the new
          peer is offered through the <tt>PEER_CONNECTED</tt> signal.
        </dd>
        <dt pn="section-5-3.3">
          <tt>HOLD(P)</tt>
        </dt>
        <dd pn="section-5-3.4">
          A function which tells the underlay to keep a hold on to a connection
          to a peer <tt>P</tt>.  Underlays are usually limited in the number
	  of active connections.  With this function the DHT can indicate to the
	  underlay which connections should preferably be preserved.
        </dd>
        <dt pn="section-5-3.5">
          <tt>DROP(P)</tt>
        </dt>
        <dd pn="section-5-3.6">
          A function which tells the underlay to drop the connection to a
          peer <tt>P</tt>.  This function is only there for symmetry and
	  used during the peer's shutdown to release all of the remaining
	  HOLDs.  As R<sup>5</sup>N always prefers the longest-lived
	  connections, it would never drop an active connection that it
	  has called HOLD() on before. Nevertheless, underlay implementations
	  should not rely on this always being true.  A call to DROP() also
	  does not imply that the underlay must close the connection: it merely
	  removes the preference to preserve the connection that was established
	  by HOLD().
        </dd>
        <dt pn="section-5-3.7">
          <tt>SEND(P, M)</tt>
        </dt>
        <dd pn="section-5-3.8">
          A function that allows the local peer to send a protocol message
          <tt>M</tt> to a peer <tt>P</tt>.
        </dd>
        <dt pn="section-5-3.9">
          <tt>L2NSE = ESTIMATE_NETWORK_SIZE()</tt>
        </dt>
        <dd pn="section-5-3.10">
          A procedure that provides an estimate of the network size.
          The result, <tt>L2NSE</tt>, must be the base-2 logarithm of the estimated number of peers in the network.
          It is used by the routing algorithm.
          If the underlay does not support a protocol for network size estimation (such as cite paper NSE) the value
          <bcp14>MAY</bcp14> be provided as a configuration parameter to the implementation.
        </dd>
      </dl>
      <t indent="0" pn="section-5-4">
        The above procedures are meant to be actively
        executed by the implementation as part of the peer-to-peer protocol.
	In addition, the underlay is expected to emit
        the following signals (usually implemented as callbacks)
	based on network events observed by the underlay implementation:
      </t>
      <dl indent="3" newline="false" spacing="normal" pn="section-5-5">
        <dt pn="section-5-5.1">
          <tt>PEER_CONNECTED -&gt; P</tt>
        </dt>
        <dd pn="section-5-5.2">
          is a signal that allows the DHT to react to a newly connected peer
          <tt>P</tt>.
          Such an event triggers, for example, updates in the
          routing table and gossiping of HELLOs to that peer.
        </dd>
        <dt pn="section-5-5.3">
          <tt>PEER_DISCONNECTED -&gt; P</tt>
        </dt>
        <dd pn="section-5-5.4">
          is a signal that allows the DHT to react to a recently disconnected
          peer.
          Such an event triggers, for example, updates in the
          routing table.
        </dd>
        <dt pn="section-5-5.5">
          <tt>ADDRESS_ADDED -&gt; A</tt>
        </dt>
        <dd pn="section-5-5.6">
          The underlay signals indicates that an address <tt>A</tt> was added for our
          local peer and that henceforth the peer may be reachable under this address.
          This information is used to advertise
          connectivity information about the local peer to other peers.
          <tt>A</tt> must be a URI suitable for inclusion in a HELLO payload
          <xref target="hello_block" format="default" sectionFormat="of" derivedContent="Section 10.2"/>.
        </dd>
        <dt pn="section-5-5.7">
          <tt>ADDRESS_DELETED -&gt; A</tt>
        </dt>
        <dd pn="section-5-5.8">
          This underlay signals indicates that an address <tt>A</tt> was removed
	  from the set of addresses the local peer is possibly reachable
	  under. Addresses must have been added before they may be deleted.
          This information is used to no longer advertise
          this address to other peers.
        </dd>
        <dt pn="section-5-5.9">
          <tt>RECEIVE -&gt; (P, M)</tt>
        </dt>
        <dd pn="section-5-5.10">
          This signal informs the local peer that a protocol
          message <tt>M</tt> was received from a peer <tt>P</tt>.
        </dd>
      </dl>
      <t indent="0" pn="section-5-6">
	These signals then drive updates of the routing table, local storage
	and message transmission.
      </t>
    </section>
    <section anchor="bootstrapping" numbered="true" removeInRFC="false" toc="include" pn="section-6">
      <name slugifiedName="name-bootstrapping">Bootstrapping</name>
      <t indent="0" pn="section-6-1">
        Initially, the implementation depends upon either the Underlay providing at
        least one initial connection to a peer (signalled through
        <tt>PEER_CONNECTED</tt>), or the application/end-user providing at
        least one working HELLO to the DHT for bootstrapping.
        While details on how the first connection is established <bcp14>MAY</bcp14>
        depend on the specific implementation, this <bcp14>SHOULD</bcp14> usually be done
        by an out-of-band exchange of the information from a HELLO block.
        For this, section <xref target="hello_url" format="default" sectionFormat="of" derivedContent="Section 6.1"/> specifies a URL format for encoding HELLO
        blocks as text strings which <bcp14>SHOULD</bcp14> be supported by implementations.
      </t>
      <t indent="0" pn="section-6-2">
        Regardless of how the initial connections are established, the
        peers resulting from these initial connections
        are subsequently stored in the routing table component
        <xref target="routing_table" format="default" sectionFormat="of" derivedContent="Section 8.1"/>.
      </t>
      <t indent="0" pn="section-6-3">
        Furthermore, the Underlay <bcp14>SHOULD</bcp14> provide the implementation with one or more
        addresses signalled through <tt>ADDRESS_ADDED</tt>.  Zero addresses <bcp14>MAY</bcp14> be
        provided if a peer can only establish outgoing connections and is otherwise unreachable.
        The implementation periodically advertises all
        active addresses in a HELLO block <xref target="hello_block" format="default" sectionFormat="of" derivedContent="Section 10.2"/>.
      </t>
      <t indent="0" pn="section-6-4">
        In order to fill its routing table by finding close peers in the network, an
        implementation <bcp14>MUST</bcp14> now periodically send peer discovery messages
        <xref target="find_peer" format="default" sectionFormat="of" derivedContent="Section 8.2"/>.
      </t>
      <t indent="0" pn="section-6-5">
        The frequency of advertisement and peer discovery messages
        <bcp14>MAY</bcp14> be adapted according to network conditions,
        the set of already connected neighbors,
        the workload of the system and other factors which are at the discretion of
        the developer.
      </t>
      <t indent="0" pn="section-6-6">
        Any implementation encountering a HELLO GET request <bcp14>MUST</bcp14> respond
        with its own HELLO block except if that block is
        filtered by the request's result filter (see <xref target="result_filter" format="default" sectionFormat="of" derivedContent="Section 9.4.2"/>).
        Implementations <bcp14>MAY</bcp14> respond
        with additional valid HELLO blocks of other peers with keys
        closest to the key of the GET request.  A HELLO block is "valid"
        if it is non-expired and
        is not excluded by the result filter.  "closest" is defined
        by considering the distances between the request's key and the
        peer addresses of all of the valid HELLO blocks known at the local node.
      </t>
      <section anchor="hello_url" numbered="true" removeInRFC="false" toc="include" pn="section-6.1">
        <name slugifiedName="name-hello-urls">HELLO URLs</name>
        <t indent="0" pn="section-6.1-1">
	  The general format of a HELLO URL uses "gnunet://"
          as the scheme, followed by "hello/" for the name
          of the GNUnet subsystem, followed by "/"-separated values
          with the GNS
	  Base32 encoding (FIXME: described here or reference GNS draft?) of
          the <tt>Peer ID</tt>, a Base32-encoded EdDSA signature, and an expiration
          time in seconds since the UNIX Epoch in decimal format.
	  After this a "?" begins a list of key-value pairs where the key
          is the URI scheme of one of the peer's addresses and the value
          is the URL-escaped payload of the address URI without the "://".
        </t>
        <t indent="0" pn="section-6.1-2">
          For example, consider the following URL:
        </t>
        <figure align="left" suppress-title="false" pn="figure-2">
          <artwork type="abnf" align="left" pn="section-6.1-3.1">
gnunet://hello/RH1M20EPK834M6MHZ72\
G3CMBSF3ECKNY4W0T9VAQP9Z7SZEM6Y3G/\
NGRTAH6RA04X467CGCH7M7CEXR5F9CV5HT\
ZFK0G9BWETY3CCE2QWGVT4WA7JN5M9HMWG\
60A00R71F1PJP8N5628EKGHHBAGA7M8JW3\
0/1647134480?udp=127.0.0.1%3A2086

FIXME: signature is invalid, should
maybe generate proper test vector.

        </artwork>
        </figure>
        <t indent="0" pn="section-6.1-4">
          It specifies that the peer with the ID "RH1M...6Y3G"
          is reachable via "udp" at 127.0.0.1 on port 2086 until
          1647134480 seconds after the Epoch.  Note that "udp"
	  here is underspecified and just used as a simple example.
	  In practice, the key (addr-name)
	  <bcp14>MUST</bcp14> refer to a scheme supported by a
	  DHT Underlay.
        </t>
        <t indent="0" pn="section-6.1-5">
          The general syntax of HELLO URLs specified using
          Augmented Backus-Naur Form (ABNF) of <xref target="RFC5234" format="default" sectionFormat="of" derivedContent="RFC5234"/> is:
        </t>
        <figure align="left" suppress-title="false" pn="figure-3">
          <artwork type="abnf" align="left" pn="section-6.1-6.1">
hello-URL = "gnunet://hello/" meta [ "?" addrs ]
meta = pid "/" sig "/" exp
pid = *bchar
sig = *bchar
exp = *DIGIT
addrs = addr *( "&amp;" addr )
addr = addr-name "=" addr-value
addr-name = scheme
addr-value = *pchar
bchar = *(ALPHA / DIGIT)

        </artwork>
        </figure>
        <t indent="0" pn="section-6.1-7">
         'scheme' is defined in <xref target="RFC3986" format="default" sectionFormat="of" derivedContent="RFC3986"/> in Section 3.1.
         'pchar' is defined in <xref target="RFC3986" format="default" sectionFormat="of" derivedContent="RFC3986"/>, Appendix A.
        </t>
      </section>
    </section>
    <section anchor="bloom_filters" numbered="true" toc="include" removeInRFC="false" pn="section-7">
      <name slugifiedName="name-bloom-filters">Bloom Filters</name>
      <t indent="0" pn="section-7-1">
	R<sup>5</sup>N uses Bloom filters in several places.  This section
	gives some general background on Bloom filters and defines functions
	on this data structure shared by the various use-cases in R<sup>5</sup>N.
      </t>
      <t indent="0" pn="section-7-2">
        A Bloom filter (BF) is a space-efficient probabilistic datastructure
        to test if an element is part of a set of elements.
        Elements are identified by an element ID.
        Since a BF is a probabilistic datastructure, it is possible to have
        false-positives: when asked if an element is in the set, the answer from
        a BF is either "no" or "maybe".
      </t>
      <t indent="0" pn="section-7-3">
        Bloom filters are defined as a string of <tt>L</tt> bits always
        initially empty, consisting only of zeroes.
        There are two functions which can be invoked on the Bloom filter:
        BF-SET(bf, e) and BF-TEST(bf, e) where "e" is an element which is to
        be added to the Bloom filter or queried against the set.
        The mapping function <tt>M</tt> is defined as follows:
      </t>
      <t indent="0" pn="section-7-4">
        The element <tt>e</tt> is hashed using SHA-512.
        The resulting byte string is interpreted as a string of 16
        32-bit integers in network byte order.
      </t>
      <t indent="0" pn="section-7-5">
        When adding an element to the Bloom filter <tt>bf</tt> using
        <tt>BF-SET(bf,e)</tt>, each integer <tt>n</tt> of the mapping
        <tt>M(e)</tt> is interpreted as a bit offset <tt>n mod L</tt> within
        <tt>bf</tt> and set to 1.
      </t>
      <t indent="0" pn="section-7-6">
        When testing if an element may be in the Bloom filter <tt>bf</tt> using
        <tt>BF-TEST(bf,e)</tt>, each bit offset <tt>n mod L</tt> within
        <tt>bf</tt> <bcp14>MUST</bcp14> have been set to 1.
        Otherwise, the element is not considered to be in the Bloom filter.
      </t>
    </section>
    <section anchor="routing" numbered="true" toc="include" removeInRFC="false" pn="section-8">
      <name slugifiedName="name-routing">Routing</name>
      <t indent="0" pn="section-8-1">
        In order to select peers which are suitable destinations for
        routing messages, R<sup>5</sup>N uses a hybrid approach:
        Given an estimated network size N, the peer selection for the
        first N hops is random. After the initial N hops, peer selection
        follows an XOR-based peer distance calculation.
      </t>
      <t indent="0" pn="section-8-2">
        To enable routing, any R<sup>5</sup>N implementation must keep
	information about its current set of neighbors.
        Upon receiving a connection notification from the Underlay through
        <tt>PEER_CONNECTED</tt>, information on the new neighbor
        <bcp14>MUST</bcp14> be added, and similarly when
        a disconnect is indicated by the Underlay through
        <tt>PEER_DISCONNECTED</tt> the peer <bcp14>MUST</bcp14> be removed.
      </t>
      <t indent="0" pn="section-8-3">
        In order to achieve O(log n) routing performance,
        the data structure for managing neighbors and their
        metadata <bcp14>MUST</bcp14> be implemented using the k-buckets concept of
        <xref target="Kademlia" format="default" sectionFormat="of" derivedContent="Kademlia"/>  as defined in <xref target="routing_table" format="default" sectionFormat="of" derivedContent="Section 8.1"/>.
        Maintenance of the routing table (after bootstrapping) is
        described in <xref target="find_peer" format="default" sectionFormat="of" derivedContent="Section 8.2"/>.
      </t>
      <t indent="0" pn="section-8-4">
        Unlike <xref target="Kademlia" format="default" sectionFormat="of" derivedContent="Kademlia"/>, routing decisions in
        R<sup>5</sup>N are also influenced by a Bloom filter in the message
        that prevents routing loops. This data structure is discussed in
	<xref target="routing_bloomfilter" format="default" sectionFormat="of" derivedContent="Section 8.3"/>.  <xref target="routing_functions" format="default" sectionFormat="of" derivedContent="Section 8.4"/>
        describes the key functions provided on top of these data structures.
      </t>
      <section anchor="routing_table" numbered="true" removeInRFC="false" toc="include" pn="section-8.1">
        <name slugifiedName="name-routing-table">Routing Table</name>
        <t indent="0" pn="section-8.1-1">
          The routing table consists of an array of k-buckets. Each
          k-bucket contains a list of neighbors.
          The i-th k-bucket stores neighbors whose peer IDs are between distance 2^i and 2^(i+1) from the local peer.
          System constraints will typically force an implementation to impose some
          upper limit on the number of neighbors kept per k-bucket.
        </t>
        <t indent="0" pn="section-8.1-2">
          Implementations <bcp14>SHOULD</bcp14> try to keep at least
          5 entries per k-bucket.  Embedded systems that cannot manage
          this number of connections <bcp14>MAY</bcp14> use connection-level
          signalling to indicate that they are merely a client utilizing a
          DHT and not able to participate in routing.  DHT peers receiving
          such connections <bcp14>MUST NOT</bcp14> include connections to
          such restricted systems in their k-buckets, thereby effectively
	  excluding them when making routing decisions.
        </t>
        <t indent="0" pn="section-8.1-3">
          If a system hits constraints with respect to
          the number of active connections, an implementation
          <bcp14>MUST</bcp14> evict peers from those k-buckets with the
          largest number of neighbors. The eviction strategy <bcp14>MUST</bcp14> be
          to drop the shortest-lived connections first.
        </t>
      </section>
      <section anchor="find_peer" numbered="true" removeInRFC="false" toc="include" pn="section-8.2">
        <name slugifiedName="name-peer-discovery">Peer Discovery</name>
        <t indent="0" pn="section-8.2-1">
          To build its routing table, a peer will send out requests
          asking for blocks of type HELLO using its own location as the key,
          but filtering all of its neighbors via the Bloom filter described
          in <xref target="result_filter" format="default" sectionFormat="of" derivedContent="Section 9.4.2"/>.
          These requests <bcp14>MUST</bcp14> use the FindApproximate and DemultiplexEverywhere
          flags. FindApproximate will ensure that other peers will reply
          with keys they merely consider close-enough, while DemultiplexEverywhere
          will cause each peer on the path to respond, which is likely to yield
          HELLOs of peers that are useful somewhere in the routing table.
        </t>
        <t indent="0" pn="section-8.2-2">
          To facilitate peer discovery, each peer <bcp14>MUST</bcp14> broadcast its own
          HELLO message to all peers in the routing table periodically.
          The specific frequency <bcp14>MAY</bcp14> depend on available bandwidth
          but <bcp14>SHOULD</bcp14> be a fraction of the expiration period.
          Whenever a peer receives such a HELLO message from another peer,
          it must cache it as long as that peer is in its routing table
          (or until the HELLO expires) and serve it in response to
          Peer Discovery requests.  Details about the format of the
          HELLO message are given in <xref target="p2p_hello_wire" format="default" sectionFormat="of" derivedContent="Section 9.2.1"/>.
        </t>
      </section>
      <section anchor="routing_bloomfilter" numbered="true" removeInRFC="false" toc="include" pn="section-8.3">
        <name slugifiedName="name-peer-bloom-filter">Peer Bloom Filter</name>
        <t indent="0" pn="section-8.3-1">
          As DHT <tt>GetMessage</tt>s and <tt>PutMessage</tt>s traverse a random path through the network for the
          first N hops, it is essential that routing loops are avoided.
          In R<sup>5</sup>N, a Bloom filter is used as part of the routing metadata in
          messages. The Bloom filter is updates at each hop with the hops
          peer identity.
          For the next hop selection in both the random and the deterministic
          case, any peer which is in the Bloom filter for the respective message
          is not included in the peer selection process.
        </t>
        <t indent="0" pn="section-8.3-2">
          The peer Bloom filter is used to prevent circular routes.
          Any peer which is forwarding <tt>GetMessage</tt>s or <tt>PutMessage</tt>s
          (<xref target="p2p_messages" format="default" sectionFormat="of" derivedContent="Section 9"/>) adds its own peer ID to the
          peer Bloom filter.
          This allows other peers to (probabilistically) exclude already
          traversed peers when searching for the next hops in the routing table.
        </t>
        <t indent="0" pn="section-8.3-3">
          The peer Bloom filter is always a 128 byte field. The elements
	  hashed into the Bloom filter are the 32 byte peer IDs.  We note
	  that the peer Bloom filter may exclude peers due to false-postive
	  matches.  This is acceptable as routing should nevertheless
	  terminate (with high probability) in close vicinity of the key.
        </t>
      </section>
      <section anchor="routing_functions" numbered="true" removeInRFC="false" toc="include" pn="section-8.4">
        <name slugifiedName="name-routing-functions">Routing Functions</name>
        <t indent="0" pn="section-8.4-1">
           Using the data structures described so far,
	   the R<sup>5</sup>N routing component provides
	   the following functions for
	   message processing (<xref target="p2p_messages" format="default" sectionFormat="of" derivedContent="Section 9"/>):
        </t>
        <dl indent="3" newline="false" spacing="normal" pn="section-8.4-2">
          <dt pn="section-8.4-2.1">
            <tt>GetDistance(A, B) -&gt; Distance as Integer</tt>
          </dt>
          <dd pn="section-8.4-2.2">
            This function calculates the binary XOR between A and B.
            The resulting distance is interpreted as an integer where
            the leftmost bit is the most significant bit.
          </dd>
          <dt pn="section-8.4-2.3">
            <tt>SelectClosestpeer(K, B) -&gt; N</tt>
          </dt>
          <dd pn="section-8.4-2.4">
            This function selects the neighbor <tt>N</tt> from our
            routing table with the shortest XOR-distance to the key <tt>K</tt>.
            This means that for all other peers <tt>N'</tt> in the routing table
            <tt>GetDistance(N, K) &lt; GetDistance(N',K)</tt>.
            Peers with a positive test against the peer Bloom
	    filter <tt>B</tt> are not considered.
          </dd>
          <dt pn="section-8.4-2.5">
            <tt>SelectRandompeer(B) -&gt; N</tt>
          </dt>
          <dd pn="section-8.4-2.6">
            This function selects a random peer <tt>N</tt> from
	    all neighbors.
            Peers with a positive test in the peer Bloom
	    filter <tt>B</tt> are not considered.
          </dd>
          <dt pn="section-8.4-2.7">
            <tt>Selectpeer(K, H, B) -&gt; N</tt>
          </dt>
          <dd pn="section-8.4-2.8">
            This function selects a neighbor <tt>N</tt> depending on the
            number of hops <tt>H</tt> parameter.
            If <tt>H &lt; NETWORK_SIZE_ESTIMATE</tt>
            this function <bcp14>MUST</bcp14> return <tt>SelectRandompeer(B)</tt> and
            <tt>SelectClosestpeer(K, B)</tt> otherwise.
          </dd>
          <dt pn="section-8.4-2.9">
            <tt>IsClosestpeer(N, K, B) -&gt; true | false</tt>
          </dt>
          <dd pn="section-8.4-2.10">
            This function checks if <tt>N</tt> is the closest peer for <tt>K</tt>
            (cf. <tt>SelectClosestpeer(K)</tt>).
            Peers with a positive test in the Bloom filter <tt>B</tt> are not considered.
          </dd>
          <dt pn="section-8.4-2.11">
            <tt>ComputeOutDegree(REPL_LVL, HOPCOUNT, L2NSE) -&gt; Number</tt>
          </dt>
          <dd pn="section-8.4-2.12">
            <t indent="0" pn="section-8.4-2.12.1">
            This function computes the number of neighbors
	    that a message should be forwarded to.  The arguments
	    are the desired replication level (<tt>REPL_LVL</tt>), the <tt>HOPCOUNT</tt> of the message so far, and
	    the base-2 logarithm of the current network
	    size estimate (<tt>L2NSE</tt>) as provided
	    by the underlay.  The result
	    is the non-negative number of next hops to
	    select.  The following figure gives the
	    pseudocode for computing the number of neighbors
	    the peer should attempt to forward the message to.
            </t>
            <figure anchor="compute_out_degree" align="left" suppress-title="false" pn="figure-4">
              <name slugifiedName="name-computing-the-number-of-nex">Computing the number of next hops.</name>
              <artwork name="" type="" align="left" alt="" pn="section-8.4-2.12.2.1">
function ComputeOutDegree(REPL_LVL, HOPCOUNT, L2NSE)
BEGIN
  if (HOPCOUNT &gt; L2NSE * 4)
    return 0;
  if (HOPCOUNT &gt; L2NSE * 2)
    return 1;
  if (0 = REPL_LEVL)
    REPL_LEVL = 1
  if (REPL_LEVEL &gt; 16)
    REPL_LEVEL = 16
  RM1 = REPL_LEVEL - 1
  return 1 + (RM1 / (L2NSE + RM1 * HOPCOUNT))
</artwork>
            </figure>
            <t indent="0" pn="section-8.4-2.12.3">
	      The above calculation may yield values that are
	      not discrete. Hence, the result <bcp14>MUST</bcp14> be
	      rounded probabilistically to the nearest
	      discrete value, using the fraction
	      as the probability for rounding up.
            </t>
          </dd>
        </dl>
      </section>
      <section anchor="pending_table" numbered="true" removeInRFC="false" toc="include" pn="section-8.5">
        <name slugifiedName="name-pending-table">Pending Table</name>
        <t indent="0" pn="section-8.5-1">
	  R<sup>5</sup>N performs stateful routing where the messages
	  only carry the query hash and do not encode the ultimate
	  source or destination of the request.  Routing a request
	  towards the key is doing hop-by-hop using the routing table and the
	  query hash.  The pending table is used to route responses
	  back to the originator.  In the pending table each peer
	  primarily associates a query hash with the associated
	  originator of the request.  The pending table <bcp14>MUST</bcp14>
	  store entries for the last <tt>MAX_RECENT</tt> requests
	  the peer has encountered.  To ensure that the peer does
	  not run out of memory, information about older requests
	  is discarded.  The value of <tt>MAX_RECENT</tt> <bcp14>MAY</bcp14> be
	  configurable and <bcp14>SHOULD</bcp14> be at least 128k.
        </t>
        <t indent="0" pn="section-8.5-2">
	  For each entry in the pending table, the DHT <bcp14>MUST</bcp14> track
	  not only the query key and the origin, but also the
	  extended query, requested block type and flags, and the
	  result filter.  If the query did not provide
	  a result filter, a fresh result filter
	  <bcp14>MUST</bcp14> still be created to filter duplicate replies.
	  Details of how a result filter works depend on the
	  type, as described in <xref target="block_functions" format="default" sectionFormat="of" derivedContent="Section 10.1"/>.
        </t>
        <t indent="0" pn="section-8.5-3">
	  When a second query from the same origin for the
	  same query hash is received, the DHT <bcp14>MUST</bcp14>
	  attempt to merge the new request with the state for
	  the old request.  If this is not possible, the
	  existing result filter <bcp14>MUST</bcp14> be
	  discarded and replaced with the result
	  filter of the incoming message.
        </t>
        <t indent="0" pn="section-8.5-4">
	  We note that for local applications, a fixed limit on
	  the number of concurrent requests may be problematic.
	  Hence, it is <bcp14>RECOMMENDED</bcp14> that implementations
	  track requests from local applications separately and
	  preserve the information until the application explicitly
	  stops the request.
        </t>
      </section>
    </section>
    <section anchor="p2p_messages" numbered="true" toc="include" removeInRFC="false" pn="section-9">
      <name slugifiedName="name-message-processing">Message Processing</name>
      <t indent="0" pn="section-9-1">
        The implementation <bcp14>MUST</bcp14> listen for <tt>RECEIVE(P, M)</tt> signals
        from the Underlay and respond to the respective messages sent by
        the peer <tt>P</tt>.
        In the following, the wire formats of the messages and the required
        processing are detailed.
        Where required, the local peer's ID is referred to as <tt>SELF</tt>.
      </t>
      <section anchor="message_components" numbered="true" removeInRFC="false" toc="include" pn="section-9.1">
        <name slugifiedName="name-message-components">Message components</name>
        <t indent="0" pn="section-9.1-1">
	  This section describes some data structures and fields shared
	  by various message types.
        </t>
        <section anchor="route_flags" numbered="true" removeInRFC="false" toc="include" pn="section-9.1.1">
          <name slugifiedName="name-flags">Flags</name>
          <t indent="0" pn="section-9.1.1-1">
            Flags is a 16-bit vector representing binary options.
            Each flag is represented by a bit in the field starting from 0 as
            the rightmost bit to 15 as the leftmost bit.
            <!--FIXME: Actually, we set those bits and then store the resulting
		value in NBO...-->
          </t>
          <dl indent="3" newline="false" spacing="normal" pn="section-9.1.1-2">
            <dt pn="section-9.1.1-2.1">0: DemultiplexEverywhere</dt>
            <dd pn="section-9.1.1-2.2">
	    This bit indicates that each peer along the way should process the request.
            If the bit is not set, intermediate peers only route the message and only
            peers which consider themselves closest to the key look for answers
            in their local storage for <tt>GetMessage</tt>s and cache the
	          block in their local storage for <tt>PutMessage</tt>s and <tt>ResultMessage</tt>s.
          </dd>
            <dt pn="section-9.1.1-2.3">1: RecordRoute</dt>
            <dd pn="section-9.1.1-2.4">
            This bit indicates to keep track of the path that the message takes
            in the P2P network.
          </dd>
            <dt pn="section-9.1.1-2.5">2: FindApproximate</dt>
            <dd pn="section-9.1.1-2.6">
            This bit allows results where the key does not match exactly.
          </dd>
            <dt pn="section-9.1.1-2.7">3: Truncated</dt>
            <dd pn="section-9.1.1-2.8">
            This is a special flag which is set if a peer truncated the path
            and thus the first hop on the path is given without a signature
            to enable checking of the next signature. MUST never be set in
            a query.
          </dd>
            <dt pn="section-9.1.1-2.9">4-15: Reserved</dt>
            <dd pn="section-9.1.1-2.10">
            The remaining bits are reserved for future use and
	    <bcp14>MUST</bcp14> be set to 0 when initiating an operation.
	    If non-zero bits are received, implementations <bcp14>MUST</bcp14>
	    preserve these bits when forwarding messages.
          </dd>
          </dl>
        </section>
        <section anchor="p2p_pathelement" numbered="true" removeInRFC="false" toc="include" pn="section-9.1.2">
          <!-- TODO-GROTHOFF: Discuss this change again. The text is currently not correct
             it is very difficult to understand. Is it worth 32 byte -->
        <name slugifiedName="name-path-element">Path Element</name>
          <t indent="0" pn="section-9.1.2-1">
          A Path Element represents a hop in the path a message has taken
          through the network.
          The wire format of a Path Element is illustrated in
          <xref target="figure_pathelement" format="default" sectionFormat="of" derivedContent="Figure 5"/>.
          </t>
          <figure anchor="figure_pathelement" align="left" suppress-title="false" pn="figure-5">
            <name slugifiedName="name-the-wire-format-of-a-path-e">The Wire Format of a Path Element.</name>
            <artwork name="" type="" align="left" alt="" pn="section-9.1.2-2.1">
0     8     16    24    32    40    48    56
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  SIGNATURE                    |
|                  (64 byte)                    |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  PEER ID                      |
|                  (32 byte)                    |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
         </artwork>
          </figure>
          <t indent="0" pn="section-9.1.2-3">where:</t>
          <dl indent="3" newline="false" spacing="normal" pn="section-9.1.2-4">
            <dt pn="section-9.1.2-4.1">SIGNATURE</dt>
            <dd pn="section-9.1.2-4.2">
            is a 64 byte EdDSA signature using the current hop's private
            key affirming the previous and next hops.
          </dd>
            <dt pn="section-9.1.2-4.3">PEER ID</dt>
            <dd pn="section-9.1.2-4.4">
            is the EdDSA public key of the peer on the path.
          </dd>
          </dl>
          <t indent="0" pn="section-9.1.2-5">
          An ordered list of Path Elements may be appended to any routed
          <tt>PutMessage</tt>s or <tt>ResultMessage</tt>s.
          The signature of a Path Element is created by the current hop
          after it made its routing decision identifiying the successor peer.
          The wire format of an example path from Peers A over B and C as it
           would be received by D in a <tt>PutMessage</tt> or <tt>ResultMessage</tt>
          is illustrated in <xref target="figure_path_ex" format="default" sectionFormat="of" derivedContent="Figure 6"/>.
          A <tt>ResultMessage</tt> would indicate in the <tt>PATH_LEN</tt> field
          a length of 3.
          A <tt>PutMessage</tt> would indicate a length of 3 as the sum of
          <tt>PUTPATH_L</tt> and <tt>GETPATH_L</tt> fields.
          </t>
          <figure anchor="figure_path_ex" align="left" suppress-title="false" pn="figure-6">
            <name slugifiedName="name-example-of-a-path-from-peer">Example of a path from Peer A to Peer D.</name>
            <artwork name="" type="" align="left" alt="" pn="section-9.1.2-6.1">
0     8     16    24    32    40    48    56
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  SIGNATURE A                  |
|                  (64 byte)                    |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  PEER A                       |
|                  (32 byte)                    |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  SIGNATURE B                  |
|                  (64 byte)                    |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  PEER B                       |
|                  (32 byte)                    |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  SIGNATURE C                  |
|                  (64 byte)                    |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  PEER C                       |
|                  (32 byte)                    |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  SIGNATURE D                  |
|                  (64 byte)                    |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
         </artwork>
          </figure>
          <t indent="0" pn="section-9.1.2-7">
          A path may be truncated in which case the signature of the truncated
          Path Element is omitted leaving only the Peer ID required for the
          verification of the subsequent Path Element signature.
          Such a truncated path is indicated with the respective flag (<xref target="route_flags" format="default" sectionFormat="of" derivedContent="Section 9.1.1"/>).
          The Peer ID of the last Path Element is omitted as it must be that of
          the sender of the PutMesssage or ResultMessage.
          The wire format of a truncated example path from Peers B over C to D
            is illustrated in <xref target="figure_path_ex_trunc" format="default" sectionFormat="of" derivedContent="Figure 7"/>.
          The wire format of an example path from Peers B over C as it
          would be received by D in a <tt>PutMessage</tt> or <tt>ResultMessage</tt>
          is illustrated in <xref target="figure_path_ex_trunc" format="default" sectionFormat="of" derivedContent="Figure 7"/>.
          A <tt>ResultMessage</tt> would indicate in the <tt>PATH_LEN</tt> field
          a length of 1.
          A <tt>PutMessage</tt> would indicate a length of 1 as the sum of
          <tt>PUTPATH_L</tt> and <tt>GETPATH_L</tt> fields.
          </t>
          <figure anchor="figure_path_ex_trunc" align="left" suppress-title="false" pn="figure-7">
            <name slugifiedName="name-example-of-a-truncated-path">Example of a truncated path from Peer B to Peer D.</name>
            <artwork name="" type="" align="left" alt="" pn="section-9.1.2-8.1">
0     8     16    24    32    40    48    56
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  PEER B                       |
|                  (32 byte)                    |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  SIGNATURE C                  |
|                  (64 byte)                    |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  PEER C                       |
|                  (32 byte)                    |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  SIGNATURE D                  |
|                  (64 byte)                    |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
         </artwork>
          </figure>
          <t indent="0" pn="section-9.1.2-9">
          The SIGNATURE field in a Path Element covers a 64-bit contextualization header, the
          the block expiration, a hash of the block
          payload, as well as the predecessor peer ID and the peer ID of the
          successor that the peer making the signature is routing the
	  message to.  Thus, the signature made by SELF basically says that
          SELF received the block payload from PEER PREDECESSOR and has forwarded
	  it to PEER SUCCESSOR.  The wire format is illustrated
          in <xref target="figure_pathelewithpseudo" format="default" sectionFormat="of" derivedContent="Figure 8"/>.
          </t>
          <figure anchor="figure_pathelewithpseudo" align="left" suppress-title="false" pn="figure-8">
            <name slugifiedName="name-the-wire-format-of-the-path">The Wire Format of the Path Element for Signing.</name>
            <artwork name="" type="" align="left" alt="" pn="section-9.1.2-10.1">
0     8     16    24    32    40    48    56
+-----+-----+-----+-----+-----+-----+-----+-----+
|         SIZE          |       PURPOSE         |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                   EXPIRATION                  |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  BLOCK HASH                   |
|                  (64 byte)                    |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  PEER PREDECESSOR             |
|                  (32 byte)                    |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  PEER SUCCESSOR               |
|                  (32 byte)                    |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
         </artwork>
          </figure>
          <dl indent="3" newline="false" spacing="normal" pn="section-9.1.2-11">
            <dt pn="section-9.1.2-11.1">SIZE</dt>
            <dd pn="section-9.1.2-11.2">
            A 32-bit value containing the length of the signed data in bytes
            in network byte order.
            The length of the signed data <bcp14>MUST</bcp14> be 144 bytes.
          </dd>
            <dt pn="section-9.1.2-11.3">PURPOSE</dt>
            <dd pn="section-9.1.2-11.4">
            A 32-bit signature purpose flag. This field <bcp14>MUST</bcp14> be 6 (in network
            byte order).
          </dd>
            <dt pn="section-9.1.2-11.5">EXPIRATION</dt>
            <dd pn="section-9.1.2-11.6">
            denotes the absolute 64-bit expiration date of the block.
            In microseconds since midnight (0 hour), January 1, 1970 UTC in
            network byte order.
          </dd>
            <dt pn="section-9.1.2-11.7">BLOCK HASH</dt>
            <dd pn="section-9.1.2-11.8">
            a SHA-512 hash over the block payload.
          </dd>
            <dt pn="section-9.1.2-11.9">PEER PREDECESSOR</dt>
            <dd pn="section-9.1.2-11.10">
            the Peer ID of the previous hop. If the signing peer initiated
            the PUT, this field is set to all zeroes.
          </dd>
            <dt pn="section-9.1.2-11.11">PEER SUCCESSOR</dt>
            <dd pn="section-9.1.2-11.12">
            the Peer ID of the next hop (not of the signer).
          </dd>
          </dl>
        </section>
      </section>
      <section anchor="p2p_hello" numbered="true" toc="include" removeInRFC="false" pn="section-9.2">
        <name slugifiedName="name-hellomessage">HelloMessage</name>
        <t indent="0" pn="section-9.2-1">
	  <tt>HelloMessage</tt>s are used to inform neighbors of
	  a peer about the sender's available addresses. The
	  recipients use these messages to inform their respective
	  Underlays about ways to sustain the connections and to
	  generate HELLO blocks (see <xref target="hello_block" format="default" sectionFormat="of" derivedContent="Section 10.2"/>)
          to answer peer discovery queries
	  from other peers. In contrast to a HELLO block, a
	  <tt>HelloMessage</tt> does not contain the ID of
	  the peer the address information is about: in a
	  <tt>HelloMessage</tt>, the address information is always
	  about the sender. Since
	  the Underlay is responsible to determine the
	  peer ID of the sender for all messages, it would thus be
	  redundant to also include the peer ID in the
	  <tt>HelloMessage</tt>.
        </t>
        <section anchor="p2p_hello_wire" numbered="true" removeInRFC="false" toc="include" pn="section-9.2.1">
          <name slugifiedName="name-wire-format">Wire Format</name>
          <figure anchor="figure_hellomsg" align="left" suppress-title="false" pn="figure-9">
            <name slugifiedName="name-the-hellomessage-wire-forma">The HelloMessage Wire Format.</name>
            <artwork name="" type="" align="left" alt="" pn="section-9.2.1-1.1">
0     8     16    24    32    40    48    56
+-----+-----+-----+-----+-----+-----+-----+-----+
|  MSIZE    |   MTYPE   | RESERVED  | URL_CTR   |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                    SIGNATURE                  /
/                   (64 byte)                   |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                    EXPIRATION                 |
+-----+-----+-----+-----+-----+-----+-----+-----+
/ ADDRESSES (variable length)                   /
+-----+-----+-----+-----+-----+-----+-----+-----+
</artwork>
          </figure>
          <t indent="0" pn="section-9.2.1-2">where:</t>
          <dl indent="3" newline="false" spacing="normal" pn="section-9.2.1-3">
            <dt pn="section-9.2.1-3.1">MSIZE</dt>
            <dd pn="section-9.2.1-3.2">
              denotes the size of this message in network byte order.
            </dd>
            <dt pn="section-9.2.1-3.3">MTYPE</dt>
            <dd pn="section-9.2.1-3.4">
              is the 16-bit message type. It must be set to
              the value 157 in network byte order.
            </dd>
            <dt pn="section-9.2.1-3.5">RESERVED</dt>
            <dd pn="section-9.2.1-3.6">
              is a 16-bit field that must be zero.
            </dd>
            <dt pn="section-9.2.1-3.7">URL_CTR</dt>
            <dd pn="section-9.2.1-3.8">
              is a 16-bit number that gives the total number of
              addresses encoded in the ADDRESSES field.
              In network byte order.
            </dd>
            <dt pn="section-9.2.1-3.9">SIGNATURE</dt>
            <dd pn="section-9.2.1-3.10">
              is a 64 byte EdDSA signature using the sender's private
              key affirming the information contained in the message.
              The signature is signing exactly the same data that is being
              signed in a HELLO block as described in <xref target="hello_block" format="default" sectionFormat="of" derivedContent="Section 10.2"/>.
            </dd>
            <dt pn="section-9.2.1-3.11">EXPIRATION</dt>
            <dd pn="section-9.2.1-3.12">
              denotes the absolute 64-bit expiration date of the content.
              The value specified is microseconds since midnight (0 hour),
              January 1, 1970, but must be a multiple of one million
              (so that it can be represented in seconds in a HELLO URL).
              Stored in network byte order.
            </dd>
            <dt pn="section-9.2.1-3.13">ADDRESSES</dt>
            <dd pn="section-9.2.1-3.14">
              A sequence of exactly URL_CTR
              0-terminated URIs in UTF-8 encoding representing addresses
              of this peer. Each URI must begin with a non-empty
              URI scheme terminated by "://" and followed by some
              non-empty Underlay- and scheme-specific address encoding.
            </dd>
          </dl>
        </section>
        <section anchor="p2p_hello_processing" numbered="true" removeInRFC="false" toc="include" pn="section-9.2.2">
          <name slugifiedName="name-processing">Processing</name>
          <t indent="0" pn="section-9.2.2-1">
            Upon receiving a <tt>HelloMessage</tt> from a peer <tt>P</tt>
            an implementation <bcp14>MUST</bcp14> process it step by step as follows:
          </t>
          <ol indent="adaptive" spacing="normal" start="1" type="1" pn="section-9.2.2-2">
            <li pn="section-9.2.2-2.1" derivedCounter="1.">
              If <tt>P</tt> is not in its routing table, the message
              is discarded.
            </li>
            <li pn="section-9.2.2-2.2" derivedCounter="2.">
              The signature is verified, including a check that the expiration time is in the future. If the signature is invalid, the message is discarded.
            </li>
            <li pn="section-9.2.2-2.3" derivedCounter="3.">
              The HELLO information is cached in the routing table until it expires, the peer is removed from the routing table, or the information is replaced by another message from the peer.
            </li>
          </ol>
          <t indent="0" pn="section-9.2.2-3">
	    The address information about P should then also be made
	    available to each respective Underlays to enable the
	    Underlay to maintain optimal connectivity to the
	    neighbor.
          </t>
        </section>
      </section>
      <section anchor="p2p_put" numbered="true" toc="include" removeInRFC="false" pn="section-9.3">
        <name slugifiedName="name-putmessage">PutMessage</name>
        <t indent="0" pn="section-9.3-1">
	  <tt>PutMessage</tt>s are used to store information at other peers in the DHT.
        </t>
        <section anchor="p2p_put_wire" numbered="true" removeInRFC="false" toc="include" pn="section-9.3.1">
          <name slugifiedName="name-wire-format-2">Wire Format</name>
          <figure anchor="figure_putmsg" align="left" suppress-title="false" pn="figure-10">
            <name slugifiedName="name-the-putmessage-wire-format">The PutMessage Wire Format.</name>
            <artwork name="" type="" align="left" alt="" pn="section-9.3.1-1.1">
0     8     16    24    32    40    48    56
+-----+-----+-----+-----+-----+-----+-----+-----+
|  MSIZE    |   MTYPE   |         BTYPE         |
+-----+-----+-----+-----+-----+-----+-----+-----+
|   FLAGS   | HOPCOUNT  | REPL_LVL  | PATH_LEN  |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                    EXPIRATION                 |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                   PEER_BF                     /
/                 (128 byte)                    |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  BLOCK_KEY                    /
/                 (64 byte)                     |
+-----+-----+-----+-----+-----+-----+-----+-----+
/       TRUNCATED ORIGIN (0 or 32 bytes)        /
+-----+-----+-----+-----+-----+-----+-----+-----+
/              PUTPATH (variable length)        /
+-----+-----+-----+-----+-----+-----+-----+-----+
/      LAST HOP SIGNATURE (0 or 64 bytes)       /
+-----+-----+-----+-----+-----+-----+-----+-----+
/              BLOCK (variable length)          /
+-----+-----+-----+-----+-----+-----+-----+-----+
</artwork>
          </figure>
          <t indent="0" pn="section-9.3.1-2">where:</t>
          <dl indent="3" newline="false" spacing="normal" pn="section-9.3.1-3">
            <dt pn="section-9.3.1-3.1">MSIZE</dt>
            <dd pn="section-9.3.1-3.2">
              denotes the size of this message in network byte order.
            </dd>
            <dt pn="section-9.3.1-3.3">MTYPE</dt>
            <dd pn="section-9.3.1-3.4">
              is the 16-bit message type. It must be set to
              the value 146 in network byte order.
            </dd>
            <dt pn="section-9.3.1-3.5">BTYPE</dt>
            <dd pn="section-9.3.1-3.6">
              is a 32-bit block type. The block type indicates the content
              type of the payload. In network byte order.
            </dd>
            <dt pn="section-9.3.1-3.7">FLAGS</dt>
            <dd pn="section-9.3.1-3.8">
              is a 16-bit vector with binary options (see <xref target="route_flags" format="default" sectionFormat="of" derivedContent="Section 9.1.1"/>).
            </dd>
            <dt pn="section-9.3.1-3.9">HOPCOUNT</dt>
            <dd pn="section-9.3.1-3.10">
              is a 16-bit number indicating how many hops this message has
              traversed to far. In network byte order.
            </dd>
            <dt pn="section-9.3.1-3.11">REPL_LVL</dt>
            <dd pn="section-9.3.1-3.12">
              is a 16-bit number indicating the desired replication level of
              the data. In network byte order.
            </dd>
            <dt pn="section-9.3.1-3.13">PATH_LEN</dt>
            <dd pn="section-9.3.1-3.14">
              is a 16-bit number indicating the length of the PUT path recorded
              in PUTPATH.
              As PUTPATH is optional, this value may be zero.
              In network byte order.
            </dd>
            <dt pn="section-9.3.1-3.15">EXPIRATION</dt>
            <dd pn="section-9.3.1-3.16">
              denotes the absolute 64-bit expiration date of the content.
              In microseconds since midnight (0 hour), January 1, 1970 in network
              byte order.
            </dd>
            <dt pn="section-9.3.1-3.17">PEER_BF</dt>
            <dd pn="section-9.3.1-3.18">
              A peer Bloom filter to stop circular routes (see <xref target="routing_bloomfilter" format="default" sectionFormat="of" derivedContent="Section 8.3"/>).
            </dd>
            <dt pn="section-9.3.1-3.19">BLOCK_KEY</dt>
            <dd pn="section-9.3.1-3.20">
              The key under which the <tt>PutMessage</tt> wants to store content
              under.
            </dd>
            <dt pn="section-9.3.1-3.21">TRUNCATED ORIGIN</dt>
            <dd pn="section-9.3.1-3.22">
              is only provided if the TRUNCATED flag
              is set in FLAGS. If present, this is
              the public key of the peer just before
              the first entry on the PUTPATH and the
              first peer on the PUTPATH is not the
              actual origin of the message.  Thus, to
              verify the first signature on the PUTPATH,
              this public key must be used.  Note that
              due to the truncation, this last hop
              cannot be verified to exist.
            </dd>
            <dt pn="section-9.3.1-3.23">PUTPATH</dt>
            <dd pn="section-9.3.1-3.24">
              the variable-length PUT path.
              The path consists of a list of PATH_LEN Path Elements.
            </dd>
            <dt pn="section-9.3.1-3.25">LAST HOP SIGNATURE</dt>
            <dd pn="section-9.3.1-3.26">
              is only provided if the RECORD ROUTE flag
              is set in FLAGS. If present, this is
              an EdDSA signature of the sender of this message
              (using the same format as the signatures in PUTPATH)
              affirming that the sender forwarded the message from
              the predecessor (all zeros if PATH_LEN is 0,
              otherwise the last peer in PUTPATH) to
              the target peer.
            </dd>
            <dt pn="section-9.3.1-3.27">BLOCK</dt>
            <dd pn="section-9.3.1-3.28">
              the variable-length block payload. The contents are determined
              by the BTYPE field.  The length is determined by MSIZE minus
	      the size of all of the other fields.
            </dd>
          </dl>
        </section>
        <section anchor="p2p_put_processing" numbered="true" removeInRFC="false" toc="include" pn="section-9.3.2">
          <name slugifiedName="name-processing-2">Processing</name>
          <t indent="0" pn="section-9.3.2-1">
            Upon receiving a <tt>PutMessage</tt> from a peer <tt>P</tt>
            an implementation <bcp14>MUST</bcp14> process it step by step as follows:
          </t>
          <ol indent="adaptive" spacing="normal" start="1" type="1" pn="section-9.3.2-2">
            <li pn="section-9.3.2-2.1" derivedCounter="1.">
              The <tt>EXPIRATION</tt> field is evaluated.
              If the message is expired, it <bcp14>MUST</bcp14> be discarded.
            </li>
            <li pn="section-9.3.2-2.2" derivedCounter="2.">
              If the <tt>BTYPE</tt> is not supported by the implementation,
              no validation of the block payload is performed and processing
              continues at (5).
              Else, the block <bcp14>MUST</bcp14> be validated as defined in (3) and (4).
            </li>
            <li pn="section-9.3.2-2.3" derivedCounter="3.">
              The message is evaluated using the block validation functions matching
              the <tt>BTYPE</tt>. First, the client attempts to
	      derive the key using the respective <tt>DeriveBlockKey</tt> procedure
	      as described in <xref target="block_functions" format="default" sectionFormat="of" derivedContent="Section 10.1"/>.  If a key can be
	      derived and does not match, the message <bcp14>MUST</bcp14> be discarded.
	    </li>
            <li pn="section-9.3.2-2.4" derivedCounter="4.">
	      Next, the <tt>ValidateBlockStoreRequest</tt> procedure for the <tt>BTYPE</tt>
	      as described in <xref target="block_functions" format="default" sectionFormat="of" derivedContent="Section 10.1"/> is used to
              validate the block payload. If the block payload
	      is invalid, the message <bcp14>MUST</bcp14> be discarded.
            </li>
            <li pn="section-9.3.2-2.5" derivedCounter="5.">
              The peer address of the sender peer <tt>P</tt> <bcp14>SHOULD</bcp14> be in <tt>PEER_BF</tt>.
              If not, the implementation <bcp14>MAY</bcp14> log an error, but <bcp14>MUST</bcp14> continue.
            </li>
            <li pn="section-9.3.2-2.6" derivedCounter="6.">
              If the <tt>RecordRoute</tt> flag is set in FLAGS,
              the local peer address <bcp14>MUST</bcp14> be appended to the <tt>PUTPATH</tt>
              of the message.  If the flag is not set, the <tt>PATH_LEN</tt>
              <bcp14>MUST</bcp14> be set to zero.
            </li>
            <li pn="section-9.3.2-2.7" derivedCounter="7.">
              If the <tt>PATH_LEN</tt> is non-zero,
              the local peer <bcp14>SHOULD</bcp14> verify the signatures from the <tt>PUTPATH</tt>.
	      Verification <bcp14>MAY</bcp14> involve checking all signatures or any random
	      subset of the signatures.  It is <bcp14>RECOMMENDED</bcp14> that peers adapt
	      their behavior to available computational resources so as to not make signature
	      verification a bottleneck.  If an invalid signature is found, the
	      <tt>PUTPATH</tt> <bcp14>MUST</bcp14> be truncated to only include the elements
	      following the invalid signature.
            </li>
            <li pn="section-9.3.2-2.8" derivedCounter="8.">
              If the local peer is the closest peer
              (cf. <tt>IsClosestpeer(SELF, BLOCK_KEY)</tt>) or the <tt>DemultiplexEverywhere</tt>
              flag ist set, the message <bcp14>MUST</bcp14>
              be stored locally in the block storage.
            </li>
            <li pn="section-9.3.2-2.9" derivedCounter="9.">
              If the <tt>MTYPE</tt> of the message indicates a HELLO block, the
              peer <bcp14>MUST</bcp14> be considered for the local routing
	      table if the respective k-bucket is not yet full. In this case,
	      the local peer <bcp14>MUST</bcp14> try to establish a connection
	      to the peer indicated in the HELLO block using the address information
              from the HELLO block. If a connection is established,
              the peer is added to the respective k-bucket of the routing table.
	      Note that the k-bucket <bcp14>MUST</bcp14> be determined by the
	      key computed using <tt>DeriveBlockKey</tt> and not by the <tt>QUERY_HASH</tt>.
            </li>
            <li pn="section-9.3.2-2.10" derivedCounter="10.">
              Given the value in <tt>REPL_LVL</tt>, <tt>HOPCOUNT</tt> and the
	      result of <tt>IsClosestpeer(SELF, BLOCK_KEY)</tt> the number of peers to
              forward to <bcp14>MUST</bcp14> be calculated
	      using <tt>ComputeOutDegree()</tt>.
              The implementation <bcp14>SHOULD</bcp14> select up to this
              number of peers to forward the message to. The implementation <bcp14>MAY</bcp14>
              forward to fewer or no peers in order to handle resource constraints
              such as limited bandwidth.
              Finally, the local peer address <bcp14>MUST</bcp14> be added to the
              <tt>PEER_BF</tt> before forwarding the message.
              For all peers with peer address <tt>P</tt> selected to forward the message
              to, <tt>SEND(P, PutMessage')</tt> is called. Here, <tt>PutMessage'</tt>
	      is the original message with updated fields. In particular, <tt>HOPCOUNT</tt>
              <bcp14>MUST</bcp14> be incremented by 1.
            </li>
          </ol>
        </section>
      </section>
      <section anchor="p2p_get" numbered="true" toc="include" removeInRFC="false" pn="section-9.4">
        <name slugifiedName="name-getmessage">GetMessage</name>
        <t indent="0" pn="section-9.4-1">
	  <tt>GetMessage</tt>s are used to request information from other peers in the DHT.
        </t>
        <section anchor="p2p_get_wire" numbered="true" removeInRFC="false" toc="include" pn="section-9.4.1">
          <name slugifiedName="name-wire-format-3">Wire Format</name>
          <figure anchor="figure_getmsg" align="left" suppress-title="false" pn="figure-11">
            <name slugifiedName="name-the-getmessage-wire-format">The GetMessage Wire Format.</name>
            <artwork name="" type="" align="left" alt="" pn="section-9.4.1-1.1">
0     8     16    24    32    40    48    56
+-----+-----+-----+-----+-----+-----+-----+-----+
|  MSIZE    |   MTYPE   |         BTYPE         |
+-----+-----+-----+-----+-----+-----+-----+-----+
|   FLAGS   |  HOPCOUNT | REPL_LVL  |  RF_SIZE  |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                 PEER_BF                       /
/                 (128 byte)                    |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                 QUERY_HASH                    /
/                 (64 byte)                     |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                 RESULT_FILTER                 /
/                 (variable length)             /
+-----+-----+-----+-----+-----+-----+-----+-----+
/                 XQUERY (variable length)      /
+-----+-----+-----+-----+-----+-----+-----+-----+
</artwork>
          </figure>
          <t indent="0" pn="section-9.4.1-2">where:</t>
          <dl indent="3" newline="false" spacing="normal" pn="section-9.4.1-3">
            <dt pn="section-9.4.1-3.1">MSIZE</dt>
            <dd pn="section-9.4.1-3.2">
              denotes the size of this message in network byte order.
            </dd>
            <dt pn="section-9.4.1-3.3">MTYPE</dt>
            <dd pn="section-9.4.1-3.4">
              is the 16-bit message type. It must be set to
              the value 147 in network byte order.
            </dd>
            <dt pn="section-9.4.1-3.5">BTYPE</dt>
            <dd pn="section-9.4.1-3.6">
              is a 32-bit block type field. The block type indicates the content
              type of the payload. In network byte order.
            </dd>
            <dt pn="section-9.4.1-3.7">FLAGS</dt>
            <dd pn="section-9.4.1-3.8">
              is a 16-bit vector with binary options (see <xref target="route_flags" format="default" sectionFormat="of" derivedContent="Section 9.1.1"/>).
            </dd>
            <dt pn="section-9.4.1-3.9">HOPCOUNT</dt>
            <dd pn="section-9.4.1-3.10">
              is a 16-bit number indicating how many hops this message has
              traversed to far. In network byte order.
            </dd>
            <dt pn="section-9.4.1-3.11">REPL_LVL</dt>
            <dd pn="section-9.4.1-3.12">
              is a 16-bit number indicating the desired replication level of
              the data. In network byte order.
            </dd>
            <dt pn="section-9.4.1-3.13">RF_SIZE</dt>
            <dd pn="section-9.4.1-3.14">
              is a 16-bit number indicating the length of the
              result filter RESULT_FILTER. In network byte order.
            </dd>
            <dt pn="section-9.4.1-3.15">PEER_BF</dt>
            <dd pn="section-9.4.1-3.16">
              A peer Bloom filter to stop circular routes (see <xref target="routing_bloomfilter" format="default" sectionFormat="of" derivedContent="Section 8.3"/>).
            </dd>
            <dt pn="section-9.4.1-3.17">QUERY_HASH</dt>
            <dd pn="section-9.4.1-3.18">
              The query used to indicate what the key is under which the originator is looking
              for blocks with this request.
              The block type may use a different evaluation logic to determine
              applicable result blocks.
            </dd>
            <dt pn="section-9.4.1-3.19">RESULT_FILTER</dt>
            <dd pn="section-9.4.1-3.20">
              the variable-length result filter, described in <xref target="result_filter" format="default" sectionFormat="of" derivedContent="Section 9.4.2"/>.
            </dd>
            <dt pn="section-9.4.1-3.21">XQUERY</dt>
            <dd pn="section-9.4.1-3.22">
              the variable-length extended query. Optional.
            </dd>
          </dl>
        </section>
        <section anchor="result_filter" numbered="true" removeInRFC="false" toc="include" pn="section-9.4.2">
          <name slugifiedName="name-result-filter">Result Filter</name>
          <t indent="0" pn="section-9.4.2-1">
            The result filter is used to indicate to other peers which results
            are not of interest when processing a <tt>GetMessage</tt>
            (<xref target="p2p_get" format="default" sectionFormat="of" derivedContent="Section 9.4"/>).
            Any peer which is processing <tt>GetMessage</tt>s and has a result
            which matches the query key <bcp14>MUST</bcp14> check the result filter
            and only send a reply message if the result does not test positive
	    under the result filter. Before forwarding the <tt>GetMessage</tt>, the
	    result filter <bcp14>MUST</bcp14> be updated to filter out all results
	    already returned by the local peer.
          </t>
          <t indent="0" pn="section-9.4.2-2">
            How a result filter is implemented depends on the block type
	    as described in <xref target="block_functions" format="default" sectionFormat="of" derivedContent="Section 10.1"/>.
	    Result filters may be probabilistic data structures. Thus,
	    it is possible that a desireable result is filtered by a result
	    filter because of a false-positive test.
          </t>
          <t indent="0" pn="section-9.4.2-3">
	    How exactly a block result is added to a result filter
	    <bcp14>MUST</bcp14> be
	    specified as part of the definition of a block type.
          </t>
        </section>
        <section anchor="p2p_get_processing" numbered="true" removeInRFC="false" toc="include" pn="section-9.4.3">
          <name slugifiedName="name-processing-3">Processing</name>
          <t indent="0" pn="section-9.4.3-1">
            Upon receiving a <tt>GetMessage</tt> from a peer an
            implementation <bcp14>MUST</bcp14> process it step by step as follows:
          </t>
          <ol indent="adaptive" spacing="normal" start="1" type="1" pn="section-9.4.3-2">
            <li pn="section-9.4.3-2.1" derivedCounter="1.">
              The <tt>QUERY_KEY</tt> and <tt>XQUERY</tt> fields are validated
              against the requested <tt>BTYPE</tt> as defined by its respective
              <tt>ValidateBlockQuery</tt> procedure.
              If validation
	      function yields <tt>REQUEST_INVALID</tt>, the message <bcp14>MUST</bcp14> be discarded.
              If the <tt>BTYPE</tt> is not supported, the message <bcp14>MUST</bcp14>
              be forwarded.
            </li>
            <li pn="section-9.4.3-2.2" derivedCounter="2.">
              The peer address of the sender peer <tt>P</tt> <bcp14>SHOULD</bcp14> be in the
              <tt>PEER_BF</tt> Bloom filter. If not, the
              implementation <bcp14>MAY</bcp14> log an error, but <bcp14>MUST</bcp14> continue.
            </li>
            <li pn="section-9.4.3-2.3" derivedCounter="3.">
              <t indent="0" pn="section-9.4.3-2.3.1">
                If the local peer is the closest peer
                (cf. <tt>IsClosestpeer (SELF, QueryHash)</tt>) or the
                <tt>DemultiplexEverywhere</tt> flag is set, a reply
                <bcp14>MUST</bcp14> be produced (if one is available) using the following
                steps:
              </t>
              <ol type="%c)" indent="adaptive" spacing="normal" start="1" pn="section-9.4.3-2.3.2">
                <!-- FIXME: It is not clear that this is a fallthrough statement -->
                <!-- FIXME: Are HELLO blocks according to the spec stored in block storage but never looked for? -->
                <li pn="section-9.4.3-2.3.2.1" derivedCounter="a)">
                  If <tt>BTYPE</tt> indicates a request for a HELLO block,
                  the peer <bcp14>MUST</bcp14> consult the HELLOs it has cached for the
                  peers in its routing table instead of the local block
                  storage (while continuing to respect flags like
                  <tt>DemultiplexEverywhere</tt>
                  and <tt>FindApproximate</tt>).
                </li>
                <li pn="section-9.4.3-2.3.2.2" derivedCounter="b)">
                  If <tt>FLAGS</tt> indicate a <tt>FindApproximate</tt> request,
                  the peer <bcp14>SHOULD</bcp14> try to respond with the closest block it
                  has that is not filtered by the
                  <tt>RESULT_BF</tt>.
                </li>
                <li pn="section-9.4.3-2.3.2.3" derivedCounter="c)">
                  Else, the peer <bcp14>MUST</bcp14> respond if it has a valid block
                  that matches the key exactly and that is
                  not filtered by the <tt>RESULT_BF</tt>.
                </li>
              </ol>
              <t indent="0" pn="section-9.4.3-2.3.3">
               Any such resulting block <bcp14>MUST</bcp14> be encapsulated in a
               <tt>ResultMessage</tt> and <bcp14>SHOULD</bcp14> be transmitted to the
               neighbor from which the request was received.  Implementations
	       <bcp14>MAY</bcp14> drop messages if they are resource-constrained.
	       However, <tt>ResultMessage</tt>s <bcp14>SHOULD</bcp14> be given the
	       highest priority among competing transmissions.
              </t>
              <t indent="0" pn="section-9.4.3-2.3.4">
	       If the <tt>BTYPE</tt> is supported and <tt>ValidateBlockReply</tt> for the given
	       query has yielded a status of <tt>FILTER_LAST</tt>, processing
	       <bcp14>MUST</bcp14> end and not continue with forwarding of
	       the request to other peers.
              </t>
            </li>
            <li pn="section-9.4.3-2.4" derivedCounter="4.">
              Given the value in <tt>REPL_LVL</tt>, the number of peers to forward to
              <bcp14>MUST</bcp14> be calculated using
	      <tt>ComputeOutDegree()</tt>.
	      If there is at least one
              peer to forward to, the implementation <bcp14>SHOULD</bcp14> select up to this
              number of peers to forward the message to. The implementation <bcp14>MAY</bcp14>
              forward to fewer or no peers in order to handle resource constraints
              such as bandwidth.
              The peer Bloom filter <tt>PEER_BF</tt> <bcp14>MUST</bcp14> be updated with the local
              peer address <tt>SELF</tt>.
              For all peers with peer address <tt>P'</tt> chosen to forward the message
              to, <tt>SEND(P', GetMessage')</tt> is called.  Here, <tt>GetMessage'</tt>
	      is the original message with updated fields. In particular, <tt>HOPCOUNT</tt>
              <bcp14>MUST</bcp14> be incremented by 1.
            </li>
          </ol>
        </section>
      </section>
      <section anchor="p2p_result" numbered="true" toc="include" removeInRFC="false" pn="section-9.5">
        <name slugifiedName="name-resultmessage">ResultMessage</name>
        <t indent="0" pn="section-9.5-1">
	  <tt>ResultMessage</tt>s are used to return information to other peers in the DHT.
        </t>
        <section anchor="p2p_result_wire" numbered="true" removeInRFC="false" toc="include" pn="section-9.5.1">
          <name slugifiedName="name-wire-format-4">Wire Format</name>
          <figure anchor="figure_resmsg" align="left" suppress-title="false" pn="figure-12">
            <name slugifiedName="name-the-resultmessage-wire-form">The ResultMessage Wire Format</name>
            <artwork name="" type="" align="left" alt="" pn="section-9.5.1-1.1">
0     8     16    24    32    40    48    56
+-----+-----+-----+-----+-----+-----+-----+-----+
|  MSIZE    |   MTYPE   |        BTYPE          |
+-----+-----+-----+-----+-----+-----+-----+-----+
|  RESERVED |   FLAGS   | PUTPATH_L | GETPATH_L |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                   EXPIRATION                  |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                  QUERY_HASH                   /
/                 (64 byte)                     |
+-----+-----+-----+-----+-----+-----+-----+-----+
/       TRUNCATED ORIGIN (0 or 32 bytes)        /
+-----+-----+-----+-----+-----+-----+-----+-----+
/                  PUTPATH                      /
/                 (variable length)             /
+-----+-----+-----+-----+-----+-----+-----+-----+
/                  GETPATH                      /
/                 (variable length)             /
+-----+-----+-----+-----+-----+-----+-----+-----+
/      LAST HOP SIGNATURE (0 or 64 bytes)       /
+-----+-----+-----+-----+-----+-----+-----+-----+
/                  BLOCK                        /
/                 (variable length)             /
+-----+-----+-----+-----+-----+-----+-----+-----+
</artwork>
          </figure>
          <t indent="0" pn="section-9.5.1-2">where:</t>
          <dl indent="3" newline="false" spacing="normal" pn="section-9.5.1-3">
            <dt pn="section-9.5.1-3.1">MSIZE</dt>
            <dd pn="section-9.5.1-3.2">
              denotes the size of this message in network byte order.
            </dd>
            <dt pn="section-9.5.1-3.3">MTYPE</dt>
            <dd pn="section-9.5.1-3.4">
              is the 16-bit message type. It must be set to
              the value 148 in network byte order.
            </dd>
            <dt pn="section-9.5.1-3.5">BTYPE</dt>
            <dd pn="section-9.5.1-3.6">
              is a 32-bit block type field. The block type indicates the content
              type of the payload. In network byte order.
            </dd>
            <dt pn="section-9.5.1-3.7">RESERVED</dt>
            <dd pn="section-9.5.1-3.8">
              is a 16-bit value. Implementations <bcp14>MUST</bcp14>
              set this value to zero when originating a result message.
              Implementations <bcp14>MUST</bcp14> forward
              this value unchanged even if it is non-zero.
            </dd>
            <dt pn="section-9.5.1-3.9">FLAGS</dt>
            <dd pn="section-9.5.1-3.10">
              is a 16-bit vector with binary options (see <xref target="route_flags" format="default" sectionFormat="of" derivedContent="Section 9.1.1"/>).
            </dd>
            <dt pn="section-9.5.1-3.11">PUTPATH_L</dt>
            <dd pn="section-9.5.1-3.12">
              is a 16-bit number indicating the length of the PUT path recorded
              in <tt>PUTPATH</tt>. As <tt>PUTPATH</tt> is optional, this value may be zero
	      even if the message has traversed several peers.
              In network byte order.
            </dd>
            <dt pn="section-9.5.1-3.13">GETPATH_L</dt>
            <dd pn="section-9.5.1-3.14">
              is a 16-bit number indicating the length of the GET path recorded
              in <tt>GETPATH</tt>. As <tt>GETPATH</tt> is optional, this value may be zero
	      even if the message has traversed several peers.
              In network byte order.
            </dd>
            <dt pn="section-9.5.1-3.15">EXPIRATION</dt>
            <dd pn="section-9.5.1-3.16">
              denotes the absolute 64-bit expiration date of the content.
              In microseconds since midnight (0 hour), January 1, 1970 in network
              byte order.
            </dd>
            <dt pn="section-9.5.1-3.17">QUERY_HASH</dt>
            <dd pn="section-9.5.1-3.18">
              the query hash corresponding to the <tt>GetMessage</tt> which
              caused this reply message to be sent.
            </dd>
            <dt pn="section-9.5.1-3.19">TRUNCATED ORIGIN</dt>
            <dd pn="section-9.5.1-3.20">
              is only provided if the TRUNCATED flag
              is set in FLAGS. If present, this is
              the public key of the peer just before
              the first entry on the PUTPATH and the
              first peer on the PUTPATH is not the
              actual origin of the message.  Thus, to
              verify the first signature on the PUTPATH,
              this public key must be used.  Note that
              due to the truncation, this last hop
              cannot be verified to exist.
            </dd>
            <dt pn="section-9.5.1-3.21">PUTPATH</dt>
            <dd pn="section-9.5.1-3.22">
              the variable-length PUT path.
              The path consists of a list of <tt>PUTPATH_L</tt> Path Elements.
            </dd>
            <dt pn="section-9.5.1-3.23">GETPATH</dt>
            <dd pn="section-9.5.1-3.24">
              the variable-length PUT path.
              The path consists of a list of <tt>GETPATH_L</tt> Path Elements.
            </dd>
            <dt pn="section-9.5.1-3.25">LAST HOP SIGNATURE</dt>
            <dd pn="section-9.5.1-3.26">
              is only provided if the RECORD ROUTE flag
              is set in FLAGS. If present, this is
              an EdDSA signature of the sender of this message
              (using the same format as the signatures in PUTPATH)
              affirming that the sender forwarded the message from
              the predecessor (all zeros if PATH_LEN is 0,
              otherwise the last peer in PUTPATH) to
              the target peer.
            </dd>
            <dt pn="section-9.5.1-3.27">BLOCK</dt>
            <dd pn="section-9.5.1-3.28">
              the variable-length resource record data payload.
              The contents are defined by the respective type of the resource record.
            </dd>
          </dl>
        </section>
        <section anchor="p2p_result_processing" numbered="true" removeInRFC="false" toc="include" pn="section-9.5.2">
          <name slugifiedName="name-processing-4">Processing</name>
          <t indent="0" pn="section-9.5.2-1">
            Upon receiving a <tt>ResultMessage</tt> from a connected peer
            an implementation <bcp14>MUST</bcp14> process it step by step as follows:
          </t>
          <ol indent="adaptive" spacing="normal" start="1" type="1" pn="section-9.5.2-2">
            <li pn="section-9.5.2-2.1" derivedCounter="1.">
              First, the <tt>EXPIRATION</tt> field is evaluated.
              If the message is expired, it <bcp14>MUST</bcp14> be discarded.
            </li>
            <li pn="section-9.5.2-2.2" derivedCounter="2.">
              If the <tt>BTYPE</tt> is supported, then the <tt>BLOCK</tt>
              <bcp14>MUST</bcp14> be validated against the
	      requested <tt>BTYPE</tt>.  To do this, the peer
	      checks that the block is valid using <tt>ValidateBlockStoreRequest</tt>.
	      If the result is <tt>BLOCK_INVALID</tt>, the message <bcp14>MUST</bcp14> be
	      discarded.
            </li>
            <li pn="section-9.5.2-2.3" derivedCounter="3.">
              If the <tt>PUTPATH_L</tt> or the <tt>GETPATH_L</tt> are non-zero,
              the local peer <bcp14>SHOULD</bcp14> verify the signatures from the <tt>PUTPATH</tt>
	      and the <tt>GETPATH</tt>.
	      Verification <bcp14>MAY</bcp14> involve checking all signatures or any random
	      subset of the signatures.  It is <bcp14>RECOMMENDED</bcp14> that peers adapt
	      their behavior to available computational resources so as to not make signature
	      verification a bottleneck.  If an invalid signature is found, the
	      path <bcp14>MUST</bcp14> be truncated to only include the elements
	      following the invalid signature.  In particular, any invalid signature
	      on the <tt>GETPATH</tt> will cause <tt>PUTPATH_L</tt> to be set to 0.
            </li>
            <li pn="section-9.5.2-2.4" derivedCounter="4.">
	      The peer also attempts to compute the
	      key using <tt>DeriveBlockKey</tt>.  This may result in <tt>NONE</tt>.
	      The result is used later.  Note that even if a key was computed, it
	      does not have to match the <tt>QUERY_HASH</tt>.
	    </li>
            <li pn="section-9.5.2-2.5" derivedCounter="5.">
              If the <tt>MTYPE</tt> of the message indicates a HELLO block, the
              peer <bcp14>MUST</bcp14> be considered for the local routing
	      table if the respective k-bucket is not yet full. In this case,
	      the local peer <bcp14>MUST</bcp14> try to establish a connection
	      to the peer indicated in the HELLO block using the address information
              from the HELLO block. If a connection is established,
              the peer is added to the respective k-bucket of the routing table.
	      Note that the k-bucket <bcp14>MUST</bcp14> be determined by the
	      key computed using <tt>DeriveBlockKey</tt> and not by the <tt>QUERY_HASH</tt>.
            </li>
            <li pn="section-9.5.2-2.6" derivedCounter="6.">
              <t indent="0" pn="section-9.5.2-2.6.1">
		If the <tt>QUERY_HASH</tt> of this <tt>ResultMessage</tt> is found in the
		list of pending local or remote queries, then
		for each matching pending query:
              </t>
              <ol type="%c)" indent="adaptive" spacing="normal" start="1" pn="section-9.5.2-2.6.2">
		<li pn="section-9.5.2-2.6.2.1" derivedCounter="a)">
		  If the <tt>FindApproximate</tt> flag was not set in the query and the <tt>BTYPE</tt> allowed the
		  implementation to compute the key from the block, the computed key must
		  exactly match the <tt>QUERY_HASH</tt>, otherwise the result does
		  not match the pending query and processing continues with the next pending query.
                </li>
                <li pn="section-9.5.2-2.6.2.2" derivedCounter="b)">
                  If the <tt>BTYPE</tt> is supported, result block <bcp14>MUST</bcp14>
		  be validated against the specific query using
		  the respective <tt>FilterBlockResult</tt> function. This function
		  <bcp14>MUST</bcp14> update
		  the result filter if a result is returned to the originator of the
		  query.
                </li>
                <li pn="section-9.5.2-2.6.2.3" derivedCounter="c)">
		  If the <tt>BTYPE</tt> is not supported, filtering of exact duplicate
		  replies <bcp14>MUST</bcp14> still be performed before forwarding
		  the reply.
		  Such duplicate filtering <bcp14>MAY</bcp14> be implemented
		  probabilistically, for example using a Bloom filter.
		  The result of this duplicate filtering is always either
		  <tt>FILTER_MORE</tt> or <tt>FILTER_DUPLICATE</tt>.
                </li>
                <li pn="section-9.5.2-2.6.2.4" derivedCounter="d)">
		  If the <tt>RecordRoute</tt> flag is set in FLAGS,
                  the local peer address <bcp14>MUST</bcp14> be appended to the <tt>GETPATH</tt>
                  of the message and the respective signature <bcp14>MUST</bcp14> be
                  set using the query origin as the <tt>PEER SUCCESSOR</tt> and the
		  response origin as the <tt>PEER PREDECESSOR</tt>.  If the flag is not set,
                  the <tt>GETPATH_L</tt> and <tt>PUTPATH_L</tt>
                  <bcp14>MUST</bcp14> be set to zero when forwarding the result.
                </li>
              </ol>
              <t indent="0" pn="section-9.5.2-2.6.3">
		If the result is either <tt>FILTER_MORE</tt> or <tt>FILTER_LAST</tt>,
		the result is forwarded to the origin of the query.  If the result
		was <tt>FILTER_LAST</tt>, the query is removed from the list of pending
		queries.
              </t>
            </li>
            <li pn="section-9.5.2-2.7" derivedCounter="7.">
	      Finally, the implementation <bcp14>MAY</bcp14> choose to
	      cache data from <tt>ResultMessage</tt>s.
            </li>
          </ol>
        </section>
      </section>
    </section>
    <section anchor="blockstorage" numbered="true" toc="include" removeInRFC="false" pn="section-10">
      <name slugifiedName="name-blocks">Blocks</name>
      <t indent="0" pn="section-10-1">
	This section describes various considerations R<sup>5</sup>N
	implementations must consider with respect to blocks.
	Specifically, implementations <bcp14>SHOULD</bcp14> be able
	to validate and persist blocks.  Implementations
	<bcp14>MAY</bcp14> not support validation for all types
	of blocks.  On some devices, storing blocks <bcp14>MAY</bcp14>
	also be impossible due to lack of storage capacity.
      </t>
      <t indent="0" pn="section-10-2">
        Applications can and should define their own block types.
        The block type determines the format and handling of the block
        payload by peers in <tt>PutMessage</tt>s and <tt>ResultMessage</tt>s.
        Block types <bcp14>MUST</bcp14> be registered with GANA
	(see <xref target="gana_block_type" format="default" sectionFormat="of" derivedContent="Section 13.1"/>).
      </t>
      <t indent="0" pn="section-10-3">
      </t>
      <section anchor="block_functions" numbered="true" removeInRFC="false" toc="include" pn="section-10.1">
        <name slugifiedName="name-block-operations">Block Operations</name>
        <t indent="0" pn="section-10.1-1">
            Block validation may be necessary for all types of DHT
	    messages.  To enable these validations, any block type
	    specification <bcp14>MUST</bcp14> define the following functions:
        </t>
        <dl indent="3" newline="false" spacing="normal" pn="section-10.1-2">
          <dt pn="section-10.1-2.1">ValidateBlockQuery(Key, XQuery)
	        -&gt; RequestEvaluationResult</dt>
          <dd pn="section-10.1-2.2">
            <t indent="0" pn="section-10.1-2.2.1">
              is used to evaluate the request for a block as part of
              <tt>GetMessage</tt> processing. Here, the block payload is unkown,
              but if possible the <tt>XQuery</tt> and <tt>Key</tt>
              <bcp14>SHOULD</bcp14> be verified.  Possible values for
	      the <tt>RequestEvaluationResult</tt> are:
            </t>
            <dl indent="3" newline="false" spacing="normal" pn="section-10.1-2.2.2">
              <dt pn="section-10.1-2.2.2.1">REQUEST_VALID</dt>
              <dd pn="section-10.1-2.2.2.2">Query is valid.</dd>
              <dt pn="section-10.1-2.2.2.3">REQUEST_INVALID</dt>
              <dd pn="section-10.1-2.2.2.4">
		 Query format does not match block type. For example, a
		 mandatory XQuery was not provided, or of the size of
		 the XQuery is not appropriate for the block type.
               </dd>
            </dl>
          </dd>
          <dt pn="section-10.1-2.3">DeriveBlockKey(Block) -&gt; Key | NONE</dt>
          <dd pn="section-10.1-2.4">
              is used to synthesize the block key from the block payload as
              part of <tt>PutMessage</tt> and <tt>ResultMessage</tt> processing.
	      The special return value of <tt>NONE</tt> implies that this block type does not
	      permit deriving the key from the block.  A Key may be returned
	      for a block that is ill-formed.
            </dd>
          <dt pn="section-10.1-2.5">ValidateBlockStoreRequest(Block)
	        -&gt; BlockEvaluationResult</dt>
          <dd pn="section-10.1-2.6">
            <t indent="0" pn="section-10.1-2.6.1">
              is used to evaluate a block payload
	      as part of <tt>PutMessage</tt> and <tt>ResultMessage</tt> processing.
	      Possible values for the <tt>BlockEvaluationResult</tt> are:
            </t>
            <dl indent="3" newline="false" spacing="normal" pn="section-10.1-2.6.2">
              <dt pn="section-10.1-2.6.2.1">BLOCK_VALID</dt>
              <dd pn="section-10.1-2.6.2.2">Block is valid.</dd>
              <dt pn="section-10.1-2.6.2.3">BLOCK_INVALID</dt>
              <dd pn="section-10.1-2.6.2.4">Block payload does not match the block type.
               </dd>
            </dl>
          </dd>
          <dt pn="section-10.1-2.7">SetupResultFilter(FilterSize, Mutator) -&gt; RF</dt>
          <dd pn="section-10.1-2.8">
	      is used to setup an empty result filter.  The arguments
	      are the set of results that must be filtered at the
	      initiator, and a <tt>MUTATOR</tt> value which <bcp14>MAY</bcp14>
	      be used to deterministically re-randomize
	      probabilistic data structures.  The specification <bcp14>MUST</bcp14>
	      also include the wire format for BF.
            </dd>
          <dt pn="section-10.1-2.9">FilterResult(Block, Key, RF, XQuery) -&gt; (FilterEvaluationResult, RF')</dt>
          <dd pn="section-10.1-2.10">
            <t indent="0" pn="section-10.1-2.10.1">
	      is used to filter results against specific queries.  This function
	      does not check the validity of Block itself or that it matches the given key,
	      as this must have been checked earlier.
	      Thus, locally stored blocks from previously observed
              <tt>ResultMessages</tt> and <tt>PutMessages</tt> use this
              function to perform filtering based on the request parameters
	      of a particular GET operation.
	      Possible values for the <tt>FilterEvaluationResult</tt> are:
            </t>
            <dl indent="3" newline="false" spacing="normal" pn="section-10.1-2.10.2">
              <dt pn="section-10.1-2.10.2.1">FILTER_MORE</dt>
              <dd pn="section-10.1-2.10.2.2">Valid result, and there may be more.</dd>
              <dt pn="section-10.1-2.10.2.3">FILTER_LAST</dt>
              <dd pn="section-10.1-2.10.2.4">Last possible valid result.</dd>
              <dt pn="section-10.1-2.10.2.5">FILTER_DUPLICATE</dt>
              <dd pn="section-10.1-2.10.2.6">Valid result, but duplicate (was filtered by the result filter).</dd>
              <dt pn="section-10.1-2.10.2.7">FILTER_IRRELEVANT</dt>
              <dd pn="section-10.1-2.10.2.8">Block does not satisfy the constraints imposed by the XQuery.</dd>
            </dl>
            <t indent="0" pn="section-10.1-2.10.3">
	      If the main evaluation result is <tt>FILTER_MORE</tt>, the function also returns
	      and updated result filter where the block is added to the set of
	      filtered replies.  An implementation is not expected to actually differenciate
	      between the <tt>FILTER_DUPLICATE</tt> and <tt>FILTER_IRRELEVANT</tt> return
	      values: in both cases the block is ignored for this query.
            </t>
          </dd>
        </dl>
      </section>
      <section anchor="hello_block" numbered="true" removeInRFC="false" toc="include" pn="section-10.2">
        <name slugifiedName="name-hello-blocks">HELLO Blocks</name>
        <t indent="0" pn="section-10.2-1">
            For bootstrapping and peer discovery, the DHT implementation uses
            its own block type called "HELLO".  HELLO blocks are the only type
	    of block that <bcp14>MUST</bcp14> be supported by every
	    R<sup>5</sup>N implementation. A block with this block type
            contains the peer ID of the peer that published the HELLO together
	    with a set of addresses of this peer.  The key of a HELLO block
            is the SHA-512 of the peer ID and thus the peer's address in the DHT.
        </t>
        <t indent="0" pn="section-10.2-2">
            The HELLO block type wire format is illustrated in
            <xref target="figure_hello" format="default" sectionFormat="of" derivedContent="Figure 13"/>. A query for block of type HELLO <bcp14>MUST NOT</bcp14>
            include extended query data (XQuery). Any implementation
            encountering a request for a HELLO with non-empty XQuery
	    data <bcp14>MUST</bcp14> consider the request invalid and ignore it.
        </t>
        <figure anchor="figure_hello" align="left" suppress-title="false" pn="figure-13">
          <name slugifiedName="name-the-hello-block-format">The HELLO Block Format.</name>
          <artwork name="" type="" align="left" alt="" pn="section-10.2-3.1">
0   8     16    24    32    40    48    56
+-----+-----+-----+-----+-----+-----+-----+-----+
|                     PEER-ID                   |
|                    (32 byte)                  |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                    SIGNATURE                  |
|                    (64 byte)                  |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                   EXPIRATION                  |
+-----+-----+-----+-----+-----+-----+-----+-----+
/                   ADDRESSES                   /
/               (variable length)               /
+-----+-----+-----+-----+-----+-----+-----+-----+
                </artwork>
        </figure>
        <dl indent="3" newline="false" spacing="normal" pn="section-10.2-4">
          <dt pn="section-10.2-4.1">PEER-ID</dt>
          <dd pn="section-10.2-4.2">
              is the Peer-ID of the peer which has generated this HELLO.
            </dd>
          <dt pn="section-10.2-4.3">EXPIRATION</dt>
          <dd pn="section-10.2-4.4">
              denotes the absolute 64-bit expiration date of the content.
              The value specified is microseconds since midnight (0 hour),
              January 1, 1970, but must be a multiple of one million (so that it
              can be represented in seconds in a HELLO URL).
              Stored in network byte order.
            </dd>
          <dt pn="section-10.2-4.5">ADDRESSES</dt>
          <dd pn="section-10.2-4.6">
            <t indent="0" pn="section-10.2-4.6.1">
              is a list of UTF-8 <xref target="RFC3629" format="default" sectionFormat="of" derivedContent="RFC3629"/> URIs
              <xref target="RFC3986" format="default" sectionFormat="of" derivedContent="RFC3986"/> which can be
              used as addresses to contact the peer.
              The strings <bcp14>MUST</bcp14> be 0-terminated.
              The set of URIs MAY be empty.
              An example of an addressing scheme used throughout
              this document is "r5n+ip+tcp", which refers to a standard TCP/IP socket
              connection. The "hier"-part of the URI must provide a suitable
              address for the given addressing scheme.
              The following is a non-normative example of address strings:
            </t>
            <figure align="left" suppress-title="false" pn="figure-14">
              <name slugifiedName="name-example-address-uris">Example Address URIs.</name>
              <artwork name="" type="" align="left" alt="" pn="section-10.2-4.6.2.1">
r5n+ip+udp://1.2.3.4:6789 \
gnunet+tcp://12.3.4.5/ \
             </artwork>
            </figure>
          </dd>
          <dt pn="section-10.2-4.7">SIGNATURE</dt>
          <dd pn="section-10.2-4.8">
            <t indent="0" pn="section-10.2-4.8.1">
            is the signature of the HELLO.
            It covers a 64-bit pseudo header
            conceptually prefixed to the block. The pseudo header includes
            the expiration, signature purpose and a hash over the addresses.
            The wire format is illustrated
            in <xref target="figure_hellowithpseudo" format="default" sectionFormat="of" derivedContent="Figure 15"/>.
            </t>
            <figure anchor="figure_hellowithpseudo" align="left" suppress-title="false" pn="figure-15">
              <name slugifiedName="name-the-wire-format-of-the-hell">The Wire Format of the HELLO for Signing.</name>
              <artwork name="" type="" align="left" alt="" pn="section-10.2-4.8.2.1">
0     8     16    24    32    40    48    56
+-----+-----+-----+-----+-----+-----+-----+-----+
|         SIZE          |       PURPOSE         |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                   EXPIRATION                  |
+-----+-----+-----+-----+-----+-----+-----+-----+
|                   H_ADDRS                     |
|                  (64 byte)                    |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
|                                               |
+-----+-----+-----+-----+-----+-----+-----+-----+
           </artwork>
            </figure>
            <dl indent="3" newline="false" spacing="normal" pn="section-10.2-4.8.3">
              <dt pn="section-10.2-4.8.3.1">SIZE</dt>
              <dd pn="section-10.2-4.8.3.2">
              A 32-bit value containing the length of the signed data in bytes
              in network byte order.
              The length of the signed data <bcp14>MUST</bcp14> be 80 bytes.
            </dd>
              <dt pn="section-10.2-4.8.3.3">PURPOSE</dt>
              <dd pn="section-10.2-4.8.3.4">
              A 32-bit signature purpose flag. This field <bcp14>MUST</bcp14> be 7 (in network
              byte order).
            </dd>
              <dt pn="section-10.2-4.8.3.5">EXPIRATION</dt>
              <dd pn="section-10.2-4.8.3.6">
              denotes the absolute 64-bit expiration date of the HELLO.
              In microseconds since midnight (0 hour), January 1, 1970 in network
              byte order.
            </dd>
              <dt pn="section-10.2-4.8.3.7">H_ADDRS</dt>
              <dd pn="section-10.2-4.8.3.8">
              a SHA-512 hash over the addresses in the HELLO.
              H_ADDRS is generated over the ADDRESSES field
              as provided in the HELLO block using SHA-512 <xref target="RFC4634" format="default" sectionFormat="of" derivedContent="RFC4634"/>.
            </dd>
            </dl>
          </dd>
        </dl>
        <t indent="0" pn="section-10.2-5">
            The HELLO block functions <bcp14>MUST</bcp14> be implemented
            as follows:
        </t>
        <dl indent="3" newline="false" spacing="normal" pn="section-10.2-6">
          <dt pn="section-10.2-6.1">ValidateBlockQuery(Key, XQuery)
	        -&gt; RequestEvaluationResult</dt>
          <dd pn="section-10.2-6.2">
              To validate a block query for a HELLO is to simply check that the XQuery is empty. If it is empty, REQUEST_VALID ist returned. Otherwise, REQUEST_INVALID.
          </dd>
          <dt pn="section-10.2-6.3">DeriveBlockKey(Block) -&gt; Key | NONE</dt>
          <dd pn="section-10.2-6.4">
            To derive a block key for a HELLO is to simply
            hash the peer ID from the HELLO. The result of this function
            is always: FIXME what hash
          </dd>
          <dt pn="section-10.2-6.5">ValidateBlockStoreRequest(Block)
	        -&gt; BlockEvaluationResult</dt>
          <dd pn="section-10.2-6.6">
	          To validate a block store request is to verify
            the EdDSA <tt>SIGNATURE</tt> over the hashed <tt>ADDRESSES</tt>
            against the public key from the peer ID field.
            If the signature is valid BLOCK_VALID is returned.
            Otherwise BLOCK_INVALID.
          </dd>
          <dt pn="section-10.2-6.7">SetupResultFilter(FilterSize, Mutator) -&gt; RF</dt>
          <dd pn="section-10.2-6.8">
            <t indent="0" pn="section-10.2-6.8.1">
	    The RESULT_FILTER for HELLO blocks is implemented using a
      Bloom filter.
            </t>
            <figure anchor="hello_rf" align="left" suppress-title="false" pn="figure-16">
              <name slugifiedName="name-the-hello-block-result-filt">The HELLO Block Result Filter.</name>
              <artwork name="" type="" align="left" alt="" pn="section-10.2-6.8.2.1">
0     8     16    24    32    40    48    56
+-----+-----+-----+-----+-----+-----+-----+-----+
|        MUTATOR        |  HELLO_BF             /
+-----+-----+-----+-----+  (variable length)    /
/                                               /
+-----+-----+-----+-----+-----+-----+-----+-----+
</artwork>
            </figure>
            <t indent="0" pn="section-10.2-6.8.3">where:</t>
            <dl indent="3" newline="false" spacing="normal" pn="section-10.2-6.8.4">
              <dt pn="section-10.2-6.8.4.1">MUTATOR</dt>
              <dd pn="section-10.2-6.8.4.2">
              The 32-bit mutator for the result filter.
            </dd>
              <dt pn="section-10.2-6.8.4.3">HELLO_BF</dt>
              <dd pn="section-10.2-6.8.4.4">
              The <tt>K</tt>-value for the HELLO_BF Bloom filter
	            is always 16.  The size <tt>S</tt> of the Bloom filter in bytes depends on
	            the number of elements <tt>F</tt> known to be filtered at the
	            initiator. If <tt>F</tt> is zero, the size <tt>S</tt> is just 8 (bytes).
	            Otherwise, <tt>S</tt> is set to the minimum of
	            2<sup>15</sup> and the lowest power
	            of 2 that is strictly larger than <tt>K*F/4</tt>
	            (in bytes).  The wire format of HELLO_BF is the resulting byte
              array. In particular, <tt>K</tt> is never transmitted.
            </dd>
            </dl>
            <t indent="0" pn="section-10.2-6.8.5">
	     R<sup>5</sup>N HELLO blocks use a <tt>MUTATOR</tt> value
       to additionally "randomize" the computation of the bloom filter while remaining
	    deterministic across peers.  The 32-bit <tt>MUTATOR</tt>
	    value is set by the peer initiating the GET request, and changed
	    every time the GET request is repeated by the initiator. Peers
	    forwarding GET requests <bcp14>MUST</bcp14> not change the
	    mutator value included in the <tt>RESULT_FILTER</tt> as they might not
	    be able to recalculate the result filter with a different <tt>MUTATOR</tt>
	    value.
            </t>
            <t indent="0" pn="section-10.2-6.8.6">
	    Consequently, repeated
	    requests have statistically independent probabilities of creating
	    false-positives in a result filter. Thus, even if for one request
	    a result filter may exclude a result as a false-positive
	    match, subsequent requests are likely to not have the same
	    false-positives.
            </t>
            <t indent="0" pn="section-10.2-6.8.7">
	    HELLO result filters can be merged if the
	    Bloom filters have the same size and
	    <tt>MUTATOR</tt> by setting all bits to 1 that are
	    set in either Bloom filter.  This is done whenever
	    a peer receives a query with the same <tt>MUTATOR</tt>,
	    predecessor and Bloom filter size.
            </t>
          </dd>
          <dt pn="section-10.2-6.9">FilterResult(Block, Key, RF, XQuery) -&gt; (FilterEvaluationResult, RF')</dt>
          <dd pn="section-10.2-6.10">
              To filter results of HELLO blocks using the Bloom filter, the
             <tt>H_ADDRS</tt> field (as computed using SHA-512 over
             the <tt>ADDRESSES</tt>) and XORed with the SHA-512
             hash of the <tt>MUTATOR</tt> (in network byte order).
             The resulting value is then used when hashing into the
             Bloom filter as described in <xref target="bloom_filters" format="default" sectionFormat="of" derivedContent="Section 7"/>.
             Consequently, HELLOs with completely identical sets of
             addresses will be filtered and FILTER_DUPLICATE is returned.
             Any small variation in the set of addresses will cause the block
             to no longer be filtered (with high probability) and
             FILTER_MORE is returned.
            </dd>
        </dl>
      </section>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-10.3">
        <name slugifiedName="name-persistence">Persistence</name>
        <t indent="0" pn="section-10.3-1">
          An implementation <bcp14>SHOULD</bcp14> provide a local persistence mechanism for
          blocks.  Embedded systems that lack storage capability <bcp14>MAY</bcp14> use
	  connection-level signalling to indicate that they are merely a client utilizing a
	  DHT and are not able to participate with storage.
          The local storage <bcp14>MUST</bcp14> provide the following functionality:
        </t>
        <dl indent="3" newline="false" spacing="normal" pn="section-10.3-2">
          <dt pn="section-10.3-2.1">Store(Key, Block)</dt>
          <dd pn="section-10.3-2.2">
            Stores a block under the specified key. If an block with identical
	    payload exists already under the same key, the meta data should
	    be set to the maximum expiration time of both blocks and use the
	    corresponding <tt>PUTPATH</tt> (and if applicable
            <tt>TRUNCATED ORIGIN</tt>) of that version of the block.
          </dd>
          <dt pn="section-10.3-2.3">Lookup(Key) -&gt; List of Blocks</dt>
          <dd pn="section-10.3-2.4">
            Retrieves blocks stored under the specified key.
          </dd>
          <dt pn="section-10.3-2.5">LookupApproximate(Key) -&gt; List of Blocks</dt>
          <dd pn="section-10.3-2.6">
            Retrieves the blocks stored under the specified key and
            any blocks under keys close to the specified key, in order
	    of decreasing proximity.
          </dd>
        </dl>
        <section numbered="true" removeInRFC="false" toc="include" pn="section-10.3.1">
          <name slugifiedName="name-approximate-search-consider">Approximate Search Considerations</name>
          <t indent="0" pn="section-10.3.1-1">
          Over time a peer may accumulate a significant number of blocks
          which are stored locally in the persistence layer.
          Due to the expected high number of blocks, the method to
          retrieve blocks close to the specified lookup key in the
          <tt>LookupApproximate</tt> API must be implemented with care
          with respect to efficiency.
          </t>
          <t indent="0" pn="section-10.3.1-2">
          It is <bcp14>RECOMMENDED</bcp14> to limit the number of results
          from the <tt>LookupApproximate</tt> procedure to a result size
          which is easily manageable by the local system.
          </t>
          <t indent="0" pn="section-10.3.1-3">
          In order to efficiently find a suitable result set, the implementation
          <bcp14>SHOULD</bcp14> follow the following procedure:
          </t>
          <ol indent="adaptive" spacing="normal" start="1" type="1" pn="section-10.3.1-4">
          <li pn="section-10.3.1-4.1" derivedCounter="1.">
            Sort all blocks by the block key in ascending (decending) order.
            The block keys are interpreted as integer.
          </li>
            <li pn="section-10.3.1-4.2" derivedCounter="2.">
            Alternatingly select a block with a key larger and smaller from
            the sortings.
            The resulting set is sorted by XOR distance.
            The selection process continues until the upper bound for the
            result set is reached and both sortings do not yield any closer
            blocks.
          </li>
          </ol>
          <t indent="0" pn="section-10.3.1-5">
          An implementation <bcp14>MAY</bcp14> decide to use a custom algorithm in order to
          find the closest blocks in the local storage.
          But, especially for more primitive approaches, such as only
          comparing XOR distances for all blocks in the storage, the
          procedure may become ineffective for large storages.
          </t>
        </section>
        <section numbered="true" removeInRFC="false" toc="include" pn="section-10.3.2">
          <name slugifiedName="name-caching-strategy-considerat">Caching Strategy Considerations</name>
          <t indent="0" pn="section-10.3.2-1">
            An implementation <bcp14>MUST</bcp14> implement an eviction strategy
            for blocks stored in the block storage layer.
          </t>
          <t indent="0" pn="section-10.3.2-2">
            In order to ensure the freshness of blocks, an implementation
            <bcp14>MUST</bcp14> evict expired blocks in favor of
            new blocks.
          </t>
          <t indent="0" pn="section-10.3.2-3">
            An implementation <bcp14>MAY</bcp14> preserve blocks which are often
            requested.
            This approach can be expensive as it requires the implementation
            to keep track of how often a block is requested.
          </t>
          <t indent="0" pn="section-10.3.2-4">
            An implementation <bcp14>MAY</bcp14> preserve blocks which are close
            to the local peer ID.
          </t>
          <t indent="0" pn="section-10.3.2-5">
            An implementation <bcp14>MAY</bcp14> provide configurable storage
            quotas and
            adapt its eviction strategy based on the current storage size
            or other constrained resources.
          </t>
        </section>
      </section>
    </section>
    <section anchor="security" numbered="true" toc="include" removeInRFC="false" pn="section-11">
      <name slugifiedName="name-security-considerations">Security Considerations</name>
      <!-- FIXME: Here we should (again) discuss how the system is open and
        does not have/require a trust anchor a priori. This is (again) in contrast
      to RELOAD -->
      <t indent="0" pn="section-11-1">
        If an upper bound to the maximum number of neighbors in a
        k-bucket is reached, the implementation <bcp14>MUST</bcp14>
        prefer to preserve the oldest working connections instead of
        new connections.  This makes Sybil attacks less effective
        as an adversary would have to invest more resources over time
        to mount an effective attack.
      </t>
      <t indent="0" pn="section-11-2">
	The <tt>ComputeOutDegree</tt> function limits the
	<tt>REPL_LVL</tt> to a maximum of 16. This imposes
	an upper limit on bandwidth amplification an attacker
	may achieve for a given network size and topology.
</t>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-11.1">
        <name slugifiedName="name-approximate-result-filterin">Approximate Result Filtering</name>
        <t indent="0" pn="section-11.1-1">
          When a FindApproximate request is encountered, a peer will try to
          respond with the closest block it has that is not filtered by the
          result bloom filter.
          Implementations <bcp14>MUST</bcp14> ensure that
          the cost of evaluating any such query is reasonably small.
          For example, implementations <bcp14>MAY</bcp14> consider to
          avoid an exhaustive search of their database.
          Not doing so can lead to denial of service attacks as there
          could be cases where too many local results are
          filtered by the result filter.
        </t>
      </section>
    </section>
    <section anchor="iana" numbered="true" toc="include" removeInRFC="false" pn="section-12">
      <name slugifiedName="name-iana-considerations">IANA Considerations</name>
      <t indent="0" pn="section-12-1">
	IANA maintains a registry called the "Uniform Resource Identifier
	(URI) Schemes" registry.
      </t>
      <!-- NOTE: not sure we should do this here, we could also
	   register gnunet:// independent of this RFC already.
	   Might be a good idea! -->
      <section anchor="gnunet-uri" numbered="true" removeInRFC="false" toc="include" pn="section-12.1">
        <name slugifiedName="name-gnunet-uri-scheme-registrat">GNUnet URI Scheme Registration</name>
        <t indent="0" pn="section-12.1-1">
	  IANA maintains the "Uniform Resource Identifier (URI)
	  Schemes" registry. The registry should be updated to include
	  an entry for the 'gnunet' URI scheme.  IANA is requested to
	  update that entry to reference this document when published
	  as an RFC.
        </t>
      </section>
      <section anchor="r5n-uri" numbered="true" removeInRFC="false" toc="include" pn="section-12.2">
        <name slugifiedName="name-r5n-uri-scheme-registration">R5N URI Scheme Registration</name>
        <t indent="0" pn="section-12.2-1">
	  IANA maintains the "Uniform Resource Identifier (URI)
	  Schemes" registry. The registry should be updated to include
	  an entry for the 'r5n+udp+ip' URI scheme.  IANA is requested to
	  update that entry to reference this document when published
	  as an RFC.
        </t>
      </section>
    </section>
    <section anchor="gana" numbered="true" toc="include" removeInRFC="false" pn="section-13">
      <name slugifiedName="name-gana-considerations">GANA Considerations</name>
      <section anchor="gana_block_type" numbered="true" toc="include" removeInRFC="false" pn="section-13.1">
        <name slugifiedName="name-block-type-registry">Block Type Registry</name>
        <t indent="0" pn="section-13.1-1">
        GANA <xref target="GANA" format="default" sectionFormat="of" derivedContent="GANA"/>
        is requested to create a "DHT Block Types" registry.
        The registry shall record for each entry:
        </t>
        <ul bare="false" empty="false" indent="3" spacing="normal" pn="section-13.1-2">
          <li pn="section-13.1-2.1">Name: The name of the block type (case-insensitive ASCII
          string, restricted to alphanumeric characters</li>
          <li pn="section-13.1-2.2">Number: 32-bit</li>
          <li pn="section-13.1-2.3">Comment: Optionally, a brief English text describing the purpose of
          the block type (in UTF-8)</li>
          <li pn="section-13.1-2.4">Contact: Optionally, the contact information of a person to contact for
          further information</li>
          <li pn="section-13.1-2.5">References: Optionally, references describing the record type
          (such as an RFC)</li>
        </ul>
        <t indent="0" pn="section-13.1-3">
        The registration policy for this sub-registry is "First Come First
        Served", as described in <xref target="RFC8126" format="default" sectionFormat="of" derivedContent="RFC8126"/>.
        GANA is requested to populate this registry as follows:
        </t>
        <figure anchor="figure_btypenums" align="left" suppress-title="false" pn="figure-17">
          <name slugifiedName="name-the-block-type-registry">The Block Type Registry.</name>
          <artwork name="" type="" align="left" alt="" pn="section-13.1-4.1">
Number| Name   | Contact | References | Description
------+--------+---------+------------+-------------------------
0       ANY      N/A       [This.I-D]   Reserved
7       HELLO    N/A       [This.I-D]   Type of a block that contains
                                        a HELLO for a peer
11      GNS      N/A       GNS          Block for storing record data
</artwork>
        </figure>
      </section>
      <section anchor="gana_gnunet_url" numbered="true" toc="include" removeInRFC="false" pn="section-13.2">
        <name slugifiedName="name-gnunet-uri-schema-subregist">GNUnet URI schema Subregistry</name>
        <t indent="0" pn="section-13.2-1">
        GANA <xref target="GANA" format="default" sectionFormat="of" derivedContent="GANA"/>
        is requested to create a "gnunet://" sub-registry.
        The registry shall record for each entry:
        </t>
        <ul bare="false" empty="false" indent="3" spacing="normal" pn="section-13.2-2">
          <li pn="section-13.2-2.1">Name: The name of the subsystem (case-insensitive ASCII
          string, restricted to alphanumeric characters</li>
          <li pn="section-13.2-2.2">Comment: Optionally, a brief English text describing the purpose of
          the subsystem (in UTF-8)</li>
          <li pn="section-13.2-2.3">Contact: Optionally, the contact information of a person to contact for
          further information</li>
          <li pn="section-13.2-2.4">References: Optionally, references describing the syntax of the URL
          (such as an RFC or LSD)</li>
        </ul>
        <t indent="0" pn="section-13.2-3">
        <!-- FIXME: See GNS wording for this which is already improved / ISE compliant -->
        The registration policy for this sub-registry is "First Come First
        Served", as described in <xref target="RFC8126" format="default" sectionFormat="of" derivedContent="RFC8126"/>.
        GANA is requested to populate this registry as follows:
        </t>
        <figure anchor="figure_gnunetscheme" align="left" suppress-title="false" pn="figure-18">
          <name slugifiedName="name-gnunet-scheme-subregistry">GNUnet scheme Subregistry.</name>
          <artwork name="" type="" align="left" alt="" pn="section-13.2-4.1">
Name           | Contact | References | Description
---------------+---------+------------+-------------------------
HELLO            N/A       [This.I-D]   How to contact a peer.
ADDRESS          N/A       N/A          Network address.
</artwork>
        </figure>
      </section>
      <section anchor="gana_signature_purpose" numbered="true" toc="include" removeInRFC="false" pn="section-13.3">
        <name slugifiedName="name-gnunet-signature-purpose-re">GNUnet Signature Purpose Registry</name>
        <t indent="0" pn="section-13.3-1">
        GANA is requested to amend the "GNUnet Signature Purpose" registry
        as follows:
        </t>
        <figure anchor="figure_purposenums" align="left" suppress-title="false" pn="figure-19">
          <name slugifiedName="name-the-signature-purpose-regis">The Signature Purpose Registry Entries.</name>
          <artwork name="" type="" align="left" alt="" pn="section-13.3-2.1">
Purpose | Name            | References | Description
--------+-----------------+------------+---------------
6         DHT PATH Element  [This.I-D]   DHT message routing data
7         HELLO Payload     [This.I-D]   Peer contact information

</artwork>
        </figure>
      </section>
      <section anchor="gana_message_type" numbered="true" toc="include" removeInRFC="false" pn="section-13.4">
        <name slugifiedName="name-gnunet-message-type-registr">GNUnet Message Type Registry</name>
        <t indent="0" pn="section-13.4-1">
        GANA is requested to amend the "GNUnet Message Type" registry
        as follows:
        </t>
        <figure anchor="figure_messagetypeenums" align="left" suppress-title="false" pn="figure-20">
          <name slugifiedName="name-the-message-type-registry-e">The Message Type Registry Entries.</name>
          <artwork name="" type="" align="left" alt="" pn="section-13.4-2.1">
Type    | Name            | References | Description
--------+-----------------+------------+---------------
146       DHT PUT          [This.I-D]    Store information in DHT
147       DHT GET          [This.I-D]    Request information from DHT
148       DHT RESULT       [This.I-D]    Return information from DHT
157       HELLO Message    [This.I-D]    Peer contact information

</artwork>
        </figure>
      </section>
    </section>
    <!-- gana -->
    <section anchor="testvectors" numbered="true" removeInRFC="false" toc="include" pn="section-14">
      <name slugifiedName="name-test-vectors">Test Vectors</name>
    </section>
  </middle>
  <back>
    <references pn="section-15">
      <name slugifiedName="name-normative-references">Normative References</name>
      <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml" quoteTitle="true" derivedAnchor="RFC2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author fullname="S. Bradner" initials="S" surname="Bradner"/>
          <date month="March" year="1997"/>
          <abstract>
            <t indent="0">In many standards track documents several words are used to signify the requirements in the specification.  These words are often capitalized.  This document defines these words as they should be interpreted in IETF documents.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
        <seriesInfo name="DOI" value="10.17487/RFC2119"/>
      </reference>
      <reference anchor="RFC3629" target="https://www.rfc-editor.org/info/rfc3629" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3629.xml" quoteTitle="true" derivedAnchor="RFC3629">
        <front>
          <title>UTF-8, a transformation format of ISO 10646</title>
          <author fullname="F. Yergeau" initials="F" surname="Yergeau"/>
          <date month="November" year="2003"/>
          <abstract>
            <t indent="0">ISO/IEC 10646-1 defines a large character set called the Universal Character Set (UCS) which encompasses most of the world's writing systems.  The originally proposed encodings of the UCS, however, were not compatible with many current applications and protocols, and this has led to the development of UTF-8, the object of this memo.  UTF-8 has the characteristic of preserving the full US-ASCII range, providing compatibility with file systems, parsers and other software that rely on US-ASCII values but are transparent to other values.  This memo obsoletes and replaces RFC 2279.</t>
          </abstract>
        </front>
        <seriesInfo name="STD" value="63"/>
        <seriesInfo name="RFC" value="3629"/>
        <seriesInfo name="DOI" value="10.17487/RFC3629"/>
      </reference>
      <reference anchor="RFC3986" target="https://www.rfc-editor.org/info/rfc3986" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml" quoteTitle="true" derivedAnchor="RFC3986">
        <front>
          <title>Uniform Resource Identifier (URI): Generic Syntax</title>
          <author fullname="T. Berners-Lee" initials="T" surname="Berners-Lee"/>
          <author fullname="R. Fielding" initials="R" surname="Fielding"/>
          <author fullname="L. Masinter" initials="L" surname="Masinter"/>
          <date month="January" year="2005"/>
          <abstract>
            <t indent="0">A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource.  This specification defines the generic URI syntax and a process for resolving URI references that might be in relative form, along with guidelines and security considerations for the use of URIs on the Internet.  The URI syntax defines a grammar that is a superset of all valid URIs, allowing an implementation to parse the common components of a URI reference without knowing the scheme-specific requirements of every possible identifier.  This specification does not define a generative grammar for URIs; that task is performed by the individual specifications of each URI scheme. [STANDARDS-TRACK]</t>
          </abstract>
        </front>
        <seriesInfo name="STD" value="66"/>
        <seriesInfo name="RFC" value="3986"/>
        <seriesInfo name="DOI" value="10.17487/RFC3986"/>
      </reference>
      <reference anchor="RFC4634" target="https://www.rfc-editor.org/info/rfc4634" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4634.xml" quoteTitle="true" derivedAnchor="RFC4634">
        <front>
          <title>US Secure Hash Algorithms (SHA and HMAC-SHA)</title>
          <author fullname="D. Eastlake 3rd" initials="D" surname="Eastlake 3rd"/>
          <author fullname="T. Hansen" initials="T" surname="Hansen"/>
          <date month="July" year="2006"/>
          <abstract>
            <t indent="0">The United States of America has adopted a suite of Secure Hash Algorithms (SHAs), including four beyond SHA-1, as part of a Federal Information Processing Standard (FIPS), specifically SHA-224 (RFC 3874), SHA-256, SHA-384, and SHA-512. The purpose of this document is to make source code performing these hash functions conveniently available to the Internet community. The sample code supports input strings of arbitrary bit length. SHA-1's sample code from RFC 3174 has also been updated to handle input strings of arbitrary bit length. Most of the text herein was adapted by the authors from FIPS 180-2.</t>
            <t indent="0">Code to perform SHA-based HMACs, with arbitrary bit length text, is also included. This memo provides information for the Internet community.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="4634"/>
        <seriesInfo name="DOI" value="10.17487/RFC4634"/>
      </reference>
      <reference anchor="RFC5234" target="https://www.rfc-editor.org/info/rfc5234" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5234.xml" quoteTitle="true" derivedAnchor="RFC5234">
        <front>
          <title>Augmented BNF for Syntax Specifications: ABNF</title>
          <author fullname="D. Crocker" initials="D" role="editor" surname="Crocker"/>
          <author fullname="P. Overell" initials="P" surname="Overell"/>
          <date month="January" year="2008"/>
          <abstract>
            <t indent="0">Internet technical specifications often need to define a formal syntax.  Over the years, a modified version of Backus-Naur Form (BNF), called Augmented BNF (ABNF), has been popular among many Internet specifications.  The current specification documents ABNF.  It balances compactness and simplicity with reasonable representational power.  The differences between standard BNF and ABNF involve naming rules, repetition, alternatives, order-independence, and value ranges.  This specification also supplies additional rule definitions and encoding for a core lexical analyzer of the type common to several Internet specifications. [STANDARDS-TRACK]</t>
          </abstract>
        </front>
        <seriesInfo name="STD" value="68"/>
        <seriesInfo name="RFC" value="5234"/>
        <seriesInfo name="DOI" value="10.17487/RFC5234"/>
      </reference>
      <reference anchor="RFC6940" target="https://www.rfc-editor.org/info/rfc6940" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6940.xml" quoteTitle="true" derivedAnchor="RFC6940">
        <front>
          <title>REsource LOcation And Discovery (RELOAD) Base Protocol</title>
          <author fullname="C. Jennings" initials="C" surname="Jennings"/>
          <author fullname="B. Lowekamp" initials="B" role="editor" surname="Lowekamp"/>
          <author fullname="E. Rescorla" initials="E" surname="Rescorla"/>
          <author fullname="S. Baset" initials="S" surname="Baset"/>
          <author fullname="H. Schulzrinne" initials="H" surname="Schulzrinne"/>
          <date month="January" year="2014"/>
          <abstract>
            <t indent="0">This specification defines REsource LOcation And Discovery (RELOAD), a peer-to-peer (P2P) signaling protocol for use on the Internet.  A P2P signaling protocol provides its clients with an abstract storage and messaging service between a set of cooperating peers that form the overlay network.  RELOAD is designed to support a P2P Session Initiation Protocol (P2PSIP) network, but can be utilized by other applications with similar requirements by defining new usages that specify the Kinds of data that need to be stored for a particular application.  RELOAD defines a security model based on a certificate enrollment service that provides unique identities.  NAT traversal is a fundamental service of the protocol.  RELOAD also allows access from "client" nodes that do not need to route traffic or store data for others.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="6940"/>
        <seriesInfo name="DOI" value="10.17487/RFC6940"/>
      </reference>
      <reference anchor="RFC8126" target="https://www.rfc-editor.org/info/rfc8126" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8126.xml" quoteTitle="true" derivedAnchor="RFC8126">
        <front>
          <title>Guidelines for Writing an IANA Considerations Section in RFCs</title>
          <author fullname="M. Cotton" initials="M" surname="Cotton"/>
          <author fullname="B. Leiba" initials="B" surname="Leiba"/>
          <author fullname="T. Narten" initials="T" surname="Narten"/>
          <date month="June" year="2017"/>
          <abstract>
            <t indent="0">Many protocols make use of points of extensibility that use constants to identify various protocol parameters. To ensure that the values in these fields do not have conflicting uses and to promote interoperability, their allocations are often coordinated by a central record keeper. For IETF protocols, that role is filled by the Internet Assigned Numbers Authority (IANA).</t>
            <t indent="0">To make assignments in a given registry prudently, guidance describing the conditions under which new values should be assigned, as well as when and how modifications to existing values can be made, is needed. This document defines a framework for the documentation of these guidelines by specification authors, in order to assure that the provided guidance for the IANA Considerations is clear and addresses the various issues that are likely in the operation of a registry.</t>
            <t indent="0">This is the third edition of this document; it obsoletes RFC 5226.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="26"/>
        <seriesInfo name="RFC" value="8126"/>
        <seriesInfo name="DOI" value="10.17487/RFC8126"/>
      </reference>
      <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml" quoteTitle="true" derivedAnchor="RFC8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author fullname="B. Leiba" initials="B" surname="Leiba"/>
          <date month="May" year="2017"/>
          <abstract>
            <t indent="0">RFC 2119 specifies common key words that may be used in protocol specifications.  This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
        <seriesInfo name="DOI" value="10.17487/RFC8174"/>
      </reference>
      <reference anchor="ed25519" target="http://link.springer.com/chapter/10.1007/978-3-642-23951-9_9" quoteTitle="true" derivedAnchor="ed25519">
        <front>
          <title>High-Speed High-Security Signatures</title>
          <author initials="D." surname="Bernstein" fullname="Daniel Bernstein">
            <organization showOnFrontPage="true">University of Illinois at Chicago</organization>
          </author>
          <author initials="N." surname="Duif" fullname="Niels Duif">
            <organization showOnFrontPage="true">Technische Universiteit Eindhoven</organization>
          </author>
          <author initials="T." surname="Lange" fullname="Tanja Lange">
            <organization showOnFrontPage="true">Technische Universiteit Eindhoven</organization>
          </author>
          <author initials="P." surname="Schwabe" fullname="Peter Schwabe">
            <organization showOnFrontPage="true">National Taiwan University</organization>
          </author>
          <author initials="B." surname="Yang" fullname="Bo-Yin Yang">
            <organization showOnFrontPage="true">Academia Sinica</organization>
          </author>
          <date year="2011"/>
        </front>
      </reference>
      <reference anchor="GANA" target="https://gana.gnunet.org/" quoteTitle="true" derivedAnchor="GANA">
        <front>
          <title>GNUnet Assigned Numbers Authority (GANA)</title>
          <author>
            <organization showOnFrontPage="true">GNUnet e.V.</organization>
          </author>
          <date month="April" year="2020"/>
        </front>
      </reference>
    </references>
    <references pn="section-16">
      <name slugifiedName="name-informative-references">Informative References</name>
      <reference anchor="R5N" target="https://doi.org/10.1109/ICNSS.2011.6060022" quoteTitle="true" derivedAnchor="R5N">
        <front>
          <title>R5N: Randomized recursive routing for restricted-route networks</title>
          <author initials="N. S." surname="Evans" fullname="Nathan S. Evans">
            <organization showOnFrontPage="true">Technische Universität München</organization>
          </author>
          <author initials="C." surname="Grothoff" fullname="Christian Grothoff">
            <organization showOnFrontPage="true">Technische Universität München</organization>
          </author>
          <date year="2011"/>
        </front>
      </reference>
      <reference anchor="Kademlia" target="http://css.csail.mit.edu/6.824/2014/papers/kademlia.pdf" quoteTitle="true" derivedAnchor="Kademlia">
        <front>
          <title>Kademlia: A peer-to-peer information system based on the xor metric.</title>
          <author initials="P." surname="Maymounkov" fullname="Petar Maymounkov">
          </author>
          <author initials="D." surname="Mazieres" fullname="David Mazieres">
          </author>
          <date year="2002"/>
        </front>
      </reference>
      <reference anchor="cadet" target="https://doi.org/10.1109/MedHocNet.2014.6849107" quoteTitle="true" derivedAnchor="cadet">
        <front>
          <title>CADET: Confidential ad-hoc decentralized end-to-end transport</title>
          <author initials="B." surname="Polot" fullname="Bartlomiej Polot">
            <organization showOnFrontPage="true">Technische Universität München</organization>
          </author>
          <author initials="C." surname="Grothoff" fullname="Christian Grothoff">
            <organization showOnFrontPage="true">Technische Universität München</organization>
          </author>
          <date year="2014"/>
        </front>
      </reference>
      <reference anchor="I-D.draft-schanzen-gns" target="https://datatracker.ietf.org/doc/draft-schanzen-gns/" quoteTitle="true" derivedAnchor="I-D.draft-schanzen-gns">
        <front>
          <title>The GNU Name System</title>
          <author initials="M." surname="Schanzenbach" fullname="Martin Schanzenbach">
            <organization showOnFrontPage="true">GNUnet e.V.</organization>
          </author>
          <author initials="C." surname="Grothoff" fullname="Christian Grothoff">
            <organization showOnFrontPage="true">GNUnet e.V.</organization>
          </author>
          <author initials="B." surname="Fix" fullname="Bernd Fix">
            <organization showOnFrontPage="true">GNUnet e.V.</organization>
          </author>
          <date year="2021"/>
        </front>
      </reference>
    </references>
    <!-- Change Log
      v00 2017-07-23  MS   Initial version
    -->
  <section anchor="authors-addresses" numbered="false" removeInRFC="false" toc="include" pn="section-appendix.a">
      <name slugifiedName="name-authors-addresses">Authors' Addresses</name>
      <author fullname="Martin Schanzenbach" initials="M." surname="Schanzenbach">
        <organization showOnFrontPage="true">GNUnet e.V.</organization>
        <address>
          <postal>
            <street>Boltzmannstrasse 3</street>
            <city>Garching</city>
            <code>85748</code>
            <country>DE</country>
          </postal>
          <email>schanzen@gnunet.org</email>
        </address>
      </author>
      <author fullname="Christian Grothoff" initials="C." surname="Grothoff">
        <organization showOnFrontPage="true">Berner Fachhochschule</organization>
        <address>
          <postal>
            <street>Hoeheweg 80</street>
            <city>Biel/Bienne</city>
            <code>2501</code>
            <country>CH</country>
          </postal>
          <email>grothoff@gnunet.org</email>
        </address>
      </author>
      <author fullname="Bernd Fix" initials="B." surname="Fix">
        <organization showOnFrontPage="true">GNUnet e.V.</organization>
        <address>
          <postal>
            <street>Boltzmannstrasse 3</street>
            <city>Garching</city>
            <code>85748</code>
            <country>DE</country>
          </postal>
          <email>fix@gnunet.org</email>
        </address>
      </author>
    </section>
  </back>
</rfc>
