<?xml version="1.0" encoding="utf-8"?>
<!-- This template is for creating an Internet Draft using xml2rfc,
     which is available here: http://xml.resource.org. -->
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
     There has to be one entity for each item to be referenced. 
     An alternate method (rfc include) is described in the references. -->

<!ENTITY RFC2119 SYSTEM
  "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!-- <!ENTITY RFC2629 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2629.xml"> -->
<!ENTITY RFC2616 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2616.xml">
<!ENTITY RFC3552 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3552.xml">
<!ENTITY RFC5226 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5226.xml">
<!ENTITY RFC5378 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5378.xml">
<!ENTITY RFC8126 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8126.xml">
<!ENTITY RFC8174 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8174.xml">
<!ENTITY RFC8569 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8569.xml">
<!ENTITY RFC8609 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8609.xml">
<!ENTITY RFC9344 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.9344.xml">
<!ENTITY RFC9508 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.9508.xml">
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<!-- used by XSLT processors -->
<!-- For a complete list and description of processing instructions (PIs),
    please see http://xml.resource.org/authoring/README.html. -->
<!-- Below are generally applicable Processing Instructions (PIs) that most I-Ds might want to use.
    (Here they are set differently than their defaults in xml2rfc v1.32) -->
<?rfc strict="yes" ?>
<!-- give errors regarding ID-nits and DTD validation -->
<!-- control the table of contents (ToC) -->
<?rfc toc="yes"?>
<!-- generate a ToC -->
<?rfc tocdepth="4"?>
<!-- the number of levels of subsections in ToC. default: 3 -->
<!-- control references -->
<?rfc symrefs="yes"?>
<!-- use symbolic references tags, i.e, [RFC2119] instead of [1] -->
<?rfc sortrefs="yes" ?>
<!-- sort the reference entries alphabetically -->
<!-- control vertical white space
    (using these PIs as follows is recommended by the RFC Editor) -->
<?rfc compact="no" ?>
<!-- do not start each main section on a new page -->
<?rfc subcompact="no" ?>
<!-- keep one blank line between list items -->
<!-- end of list of popular I-D processing instructions -->

<?rfc private="" ?>

<rfc category="exp" docName="draft-irtf-icnrg-ccnxchunking-01" ipr="trust200902"
	updates="8569, 8609">
  <!-- category values: std, bcp, info, exp, and historic
    ipr values: trust200902, noModificationTrust200902, noDerivativesTrust200902,
       or pre5378Trust200902
    you can add the attributes updates="NNNN" and obsoletes="NNNN"
    they will automatically be output with "(if approved)" -->

  <!-- ***** FRONT MATTER ***** -->

  <front>
    <!-- The abbreviated title is used in the page header - it is only necessary if the
        full title is longer than 39 characters -->

    <title abbrev="CCNx chunking">CCNx Content Object Chunking</title>

    <!-- add 'role="editor"' below for the editors if appropriate -->

    <!-- Another author who claims to be an editor -->

    <author fullname="Marc Mosko" initials="M.E." surname="Mosko">

      <address>
       <postal>
         <street/>

         <!-- Reorder these if your country does things differently -->

         <city>Kensington</city>

         <region>California</region>

         <code>94707</code>

         <country>USA</country>
       </postal>
       <email>marc@mosko.org</email>

       <!-- uri and facsimile elements may also be added -->
     </address>
    </author>

    <author initials="H" surname="Asaeda" fullname="Hitoshi Asaeda">
      <organization abbrev="NICT">National Institute of Information and Communications Technology</organization>
      <address>
        <postal>
          <street>4-2-1 Nukui-Kitamachi</street>
	        <city>Koganei</city>
          <region>Tokyo</region>
          <code>184-8795</code>
          <country>Japan</country>
        </postal>
        <email>asaeda@nict.go.jp</email>
      </address>
    </author>

    <date year="2025"/>

    <!-- If the month and year are both specified and are the current ones, xml2rfc will fill
        in the current day for you. If only the current year is specified, xml2rfc will fill
	 in the current day and month for you. If the year is not the current one, it is
	 necessary to specify at least a month (xml2rfc assumes day="1" if not specified for the
	 purpose of calculating the expiry date).  With drafts it is normally sufficient to
	 specify just the year. -->

    <!-- Meta-data Declarations -->

    <area>General</area>

    <workgroup>ICNRG</workgroup>

    <!-- WG name at the upperleft corner of the doc,
        IETF is fine for individual submissions.
	 If this element is not present, the default is "Network Working Group",
        which is used by the RFC Editor as a nod to the history of the IETF. -->

    <keyword>Content Centric Networking</keyword>

    <!-- Keywords will be incorporated into HTML output
        files in a meta tag but they have no effect on text or nroff
        output. If you submit your draft to the RFC Editor, the
        keywords will be used for the search engine. -->

    <abstract>
      <t>This document specifies a chunking protocol for dividing a user payload
      into CCNx Content Objects. It defines a name segment type to identify each
      sequential chunk number and a Content Object field to identify the last 
      available chunk number.
      This includes specification for the naming convention to use for
      the chunked payload and a field added to a Content Object to represent the last chunk of an object.  
      This document updates RFC8569 and RFC8609.</t>
    </abstract>
  </front>

  <middle>
     <section title="Introduction">
       <t>CCNx Content Objects <xref target="RFC8569"></xref> are sized to amortize cryptographic operations over
       user data while simultaneously staying a reasonable size for transport over today's networks.
       This means a Content Object is usually within common UDP or jumbo Ethernet size.
       If a publisher has a larger amount of data to associate with a single Name, the data should be
       chunked with this chunking protocol.  This protocol uses state in
       the Name and in an optional field within the Content Object.  A chunked object may also have
       an external metadata content object that describes the original pre-chunked object.</t>
       
       <t>For example, a video file may be several gigabytes of data.  To publish the
       video, one would divide it up into transport-sized Content Objects.  Each
       Content Object would have a common name prefix plus a chunk number.</t>
       
      <t>CCNx uses two types of messages: Interests and Content Objects <xref target="RFC8569"></xref>.
        An Interest carries the
        hierarchically structured variable-length identifier (HSVLI), or Name, of a
        Content Object and serves as a request for that object. If a network element sees multiple
        Interests for the same name, it may aggregate those Interests. A network element along the
        path of the Interest with a matching Content Object may return that object, satisfying the
        Interest. The Content Object follows the reverse path of the Interest to the origin(s) of
        the Interest. A Content Object contains the Name, the object's Payload, and the cryptographic
        information used to bind the Name to the payload. </t>

      <t>This document adds a ChunkNumber to the CCNx Name Segment Type for conveying the 
      chunk number and an EndChunkNumber to the CCNx Message Type for conveying the last 
      chunk number of the content. It adds a ChunkSize CCNx Message Type to specify
      that a constant payload size is used to enable a consumer to seek to specific byte locations.
      It updates <xref target="RFC8609"></xref>. It also 
      provides guidelines for the usage of the Key Locator in chunked objects.</t>

      <t>Packets are represented as 32-bit wide words using ASCII art.  Because
      of the TLV encoding and optional fields or sizes, there is no concise
      way to represent all possibilities.  We use the convention that ASCII art
      fields enclosed by vertical bars "|" represent exact bit widths.  Fields
      with a forward slash "/" are variable bitwidths, which we typically pad
      out to word alignment for picture readability.</t>

      <section title="Requirements Language">
        <t>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">RFC2119</xref> and <xref target="RFC8174">RFC8174</xref>)
         when, and only when, they appear in all capitals, as shown here.</t>
      </section>
    </section>

    <section anchor="protocol" title="Chunking">
      <t>Chunking, as used in this specification, means serializing user data
        into one or more chunks, each encapsulated in a CCNx Content Object.
        A chunk is a contiguous byte range within the user data.
        One segment in the Name of each Content Object represents the chunk number.
        A field in the Content Object - only mandatory in the final chunk - represents the end of
      the stream.  Chunks are denoted
      by a serial counter, beginning at 0 and incrementing by 1 for each
      contiguous chunk.  The chunking ends at the final chunk.  No valid
      user data exists beyond the final chunk, and reading beyond the final
      chunk MUST NOT return any user data.</t>

      <t>Chunking MAY use a fixed block size, where only the final chunk MAY
        use a smaller block size.  This is required to allow a reader to seek
        to a specific byte offset once it knows the block size.
        If the first (Chunk 0) object has the field ChunkSize, then the
        series of chunked objects uses a fixed payload size.
        ChunkSize MUST only appear in Chunk 0, if it is used.
        The first chunk of user data (a chunk with a Payload TLV) may not be chunk 0.</t>

      <t>Because of the possible use of a fixed block size, the inclusion of certain cryptographic
      fields in the same content objects as user data would throw off the ability to seek.
      Therefore, it is RECOMMENDED that all required cryptographic data, such as public keys
      or key name links, be included in the leading chunks before the first byte of user data.
      User data SHOULD then run continuously.  If the publisher included ChunkSize in 
      Chunk 0, then all Payload sizes must be of ChunkSize except the last, which may be smaller.</t>

      <t>An advantage of using a Manifest (e.g. <xref target="FLIC">FLIC</xref>) 
      is that all cryptographic data is
      in the manifest, which then links to each chunk via a full hash name.  This means
      that the chunked user data can devote all available Content Object bytes after
      the name to the user data.</t>

      <t>This draft introduces a new CCNx Name Segment TLV type, called the ChunkNumber.
      The ChunkNumber is the serial order of the chunks. It MUST begin at 0 and MUST be incremented by 1.
      The ChunkNumber is appended to the base name of the user data, and is usually the last name segment.</t>

		<t>The value of the ChunkNumber TLV is a network byte order compact encoding of the
		chunk number.</t>
      
      <t>A name MAY have more than one ChunkNumber name segments.  This may happen, for 
      example, if one chunked object is related to another chunked object.  Only the
      last ChunkNumber name segment is significant.</t>

      <t>EndChunkNumber is a new Content Object message type.
      It MUST be included in the Content Object which is the last chunk of user data,
      where the ChunkNumber TLV value and the EndChunkNumber TLV value MUST be the same.
      The value of the EndChunkNumber value is the same format as the ChunkNumber name segment.
      For example, if 3000 bytes of user data is split with a 1200 byte block size,
      there will be 3 chunks: 0, 1, and 2.  The EndChunkNumber is 2.</t>
      
       
      <t>The EndChunkNumber field MAY be present earlier, such as to assist in pipelining Interests.  It
      MAY be increased by subsequent EndChunkNumber fields.</t>
      
      <t>The last chunk is when the EndChunkNumber equals the right-most ChunkNumber name segment.</t>

      <t>When a received Content Object contains both ChunkNumber TLV and EndChunkNumber TLV, 
      and both values are the same, the consumer application will terminate reception of the content.</t>
      
      <t>The EndChunkNumber SHOULD NOT decrease.  If a publisher wishes to close
      a stream before reaching the End Chunk, it should publish empty Content
      Objects to fill out to the maximum EndChunkNumber ever published.
      These padding chunks MUST contain the true EndChunkNumber and have 
      no payload.  This mechanism for early termination is to accomodate
      circumstances where a stream ended before expected and the publisher needs to
      close early.</t>
      
      <t>It may occur that a publisher never includes an EndChunkNumber, and thus
      has never published the last chunk.  This may happen due to an error or
      network conditions that do not allow finding the last chunk.  If a consumer
      times out trying to retrieve chunks, it SHOULD report an error to the user
      and terminate.  This is similar to a TCP client not hearing a FIN.</t>

	  <t>If the user data fits within one Content Object and the publisher uses the
	  Chunking protocol, the publisher names the content with "Chunk=0" and includes
	  "EndChunkNumber=0" (assuming the Payload is in the first chunk).</t>
	  
	  <t>To summarize:</t>
	  	<ol>
	  		<li>Every chunk MUST have a ChunkNumber name segment, beginning at 0 and
	  		incrementing by 1.</li>
	  		<li>The leading chunks MAY have missing or empty Payload TLVs
	  		and convey only cryptographic or other information.</li>
        <li>An optional ChunkSize TLV MAY be in, and only in, Chunk 0.  If it is present,
          it indicates that all Payloads are the same number of bytes, except the last which
          may be smaller.</li>
	  		<li>The last chunk MUST have an EndChunkNumber TLV and the value
	  		MUST be equal to the ChunkNumber TLV value.</li>
	  		<li>Content Objects before the last chunk MAY have an EndChunkNumber
	  		TLV with the expected last chunk number.  These hints MAY be
	  		updated in subsequent Content Objects but SHOULD NOT decrease.</li>
	  		<li>If the final chunk has a ChunkNumber less than a previously
	  		published EndChunkNumber, the publisher SHOULD pad out the chunks
	  		with empty Content Objects that have the true EndChunkNumber.</li>
	  	</ol>
	  
      
      <section anchor="crypto" title="Cryptographic material">
        <t>Chunk 0 SHOULD include the public key or key name link used to verify the chunked data.
          It is RECOMMENDED to use the same key for the whole set of chunked data.
          If a publisher uses multiple keys, then the public key or key name link for all
          keys SHOULD be in the leading chunks before any user data.
          Each subsequent chunk only needs to include the KeyId and signature.</t>

        <t>The rationel for putting all cryptographic data up front is because the
        protocol requires using a fixed block size for all user data to enable seeking in the chunked stream.</t>
        
        <t>As noted above, using a Manifest eliminates the need for cryptographic
        material in the user-data Content Objects.</t>
      </section>

      <section anchor="examples" title="Examples">
      <t>Here are some examples of chunked Names using the Labeled Content
      Identifier URI scheme in human readable form (ccnx:).  </t>

      <t>In this example,
      the content producer publishes a JPG that takes 4 Chunks.
      The  EndChunkNumber is missing in the first content object (Chunk 0),
      but is known and included when Chunk 1 is published.
      It is omitted in Chunk 2, then appears in Chunk 3, where it is mandatory.</t>
      <figure>
        <artwork align="left"><![CDATA[
ccnx:/Name=example.com/Name=picture.jpg/Chunk=0  --
ccnx:/Name=example.com/Name=picture.jpg/Chunk=1  EndChunkNumber=3
ccnx:/Name=example.com/Name=picture.jpg/Chunk=2  --
ccnx:/Name=example.com/Name=picture.jpg/Chunk=3  EndChunkNumber=3
]]></artwork>
      </figure>

      <t>In this example, the publisher is writing an audio stream that
      ends before expected so the publisher fills empty Content Objects
      out to the maximum
      ChunkNumber, stating the correct EndChunkNumber.  Chunks 4, 5, and
      6 do not contain any new user data.</t>
      <figure>
        <artwork align="left"><![CDATA[
ccnx:/Name=example.com/Name=talk.wav/Chunk=0  --
ccnx:/Name=example.com/Name=talk.wav/Chunk=1  EndChunkNumber=6
ccnx:/Name=example.com/Name=talk.wav/Chunk=2  --
ccnx:/Name=example.com/Name=talk.wav/Chunk=3  EndChunkNumber=3
ccnx:/Name=example.com/Name=talk.wav/Chunk=4  EndChunkNumber=3
ccnx:/Name=example.com/Name=talk.wav/Chunk=5  EndChunkNumber=3
ccnx:/Name=example.com/Name=talk.wav/Chunk=6  EndChunkNumber=3
]]></artwork>
      </figure>
      </section>
    </section>

    <section anchor="types" title="TLV Types">
      <t>This section specifies the TLV types used by CCNx chunking.</t>

      <section anchor="names" title="ChunkNumber">
        <t>CCNx chunking defines one new CCNx Name Segment type: ChunkNumber.</t>

        <texttable anchor="name_tlvs" title="ChunkNumber">
          <ttcol align="center">Type</ttcol>
          <ttcol align="center">Abbrev</ttcol>
          <ttcol align="center">Name</ttcol>
          <ttcol align="left">Description</ttcol>
          <c>%x0004</c>
          <c>T_CHUNK</c>
          <c><xref target="names">Chunk Number</xref></c>
          <c>The current Chunk Number, is an unsigned integer
          in network byte order without leading zeros.  The value
          of zero is represented as the single byte %x00.</c>
         </texttable>

        <t>The current chunk number, as an unsigned integer
            in network byte order without leading zeros.    The value
            of zero is represented as the single byte %x00.</t>
        <t>In ccnx: URI form, it is denoted as "Chunk".</t>

        <figure>
          <artwork align="left"><![CDATA[
                     1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+--------------+
|           T_CHUNK             |             Length           |
+---------------+---------------+---------------+--------------+
|     variable length integer   /
+---------------+---------------+
]]></artwork>
        </figure>

        <figure anchor='Segment_Type' title="CCNx Name Segment Type Namespace">
          <artwork align="center">
     Code          Type name
==============     ===============================
    %x0000         Reserved [RFC8609]
    %x0001         T_NAMESEGMENT [RFC8609]
    %x0002         T_IPID [RFC8609]
    %x0003         T_NONCE [RFC9508]
    %x0004         T_CHUNK
%x0005-%x000F      Unassigned 	
%x0010-%x0013      Reserved [RFC8609]
%x0014-0x0FFE      Unassigned 	
%x0FFF             T_ORG [RFC8609]
%x1000-0x1FFF      T_APP:00 - T_APP:4096 [RFC8609]
%x2000-0xFFFF      Unassigned
          </artwork>
        </figure>

      </section>

      <section anchor="signed_info" title="Message TLVs">
        <t>CCNx chunking defines two new CCNx Message type: EndChunkNumber and ChunkSize.</t>

        <texttable anchor="si_tlvs" title="EndChunkNumber">
          <ttcol align="center">Type</ttcol>
          <ttcol align="center">Abbrev</ttcol>
          <ttcol align="center">Name</ttcol>
          <ttcol align="left">Description</ttcol>
          <c>%x0007</c>
          <c>T_ENDCHUNK</c>
          <c><xref target="signed_info">EndChunkNumber</xref></c>
          <c>The last Chunk number, as an unsigned integer
            in network byte order without leading zeros.  The value
            of zero is represented as the single byte %x00.</c>

          <c>%x000F</c>
          <c>T_CHUNK_SIZE</c>
          <c><xref target="signed_info">ChunkSize</xref></c>
          <c>The fixed payload size of user data upto the last chunk.
            It must be a positive integer.</c>
        </texttable>

        <t>The ending chunk number, as an unsigned integer
            in network byte order without leading zeros.    The value
            of zero is represented as the single byte %x00.</t>

        <figure>
          <artwork align="left"><![CDATA[
                     1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+--------------+
|         T_ENDCHUNK            |             Length           |
+---------------+---------------+---------------+--------------+
|     variable length integer   /
+---------------+---------------+
]]></artwork>
        </figure>


        <t>The chunk size number is the same as the end chunk number, except it
          must be a positive integer.</t>

       	<figure anchor='CCNx_Type' title="CCNx Message Type Namespace">
      	  <artwork align="center">
     Code          Type name
==============     ===================
    %x0000         T_NAME [RFC8609]
    %x0001         T_PAYLOAD [RFC8609]
    %x0002         T_KEYIDRESTR [RFC8609]
    %x0003         T_OBJHASHRESTR [RFC8609]
    %x0005         T_PAYLDTYPE [RFC8609]
    %x0006         T_EXPIRY [RFC8609]
    %x0007         T_ENDCHUNK
%x0008-%x000C      Reserved [RFC8609]
    %x000D         T_DISC_REQ [RFC9344]
    %x000E         T_DISC_REPLY [RFC9344]
    %x000F         T_CHUNK_SIZE
    %x0FFE         T_PAD [RFC8609]
    %x0FFF         T_ORG [RFC8609]
%x1000-%x1FFF      Reserved [RFC8609]
      	  </artwork>
      	</figure>
      </section>

    </section>


    <!-- This PI places the pagebreak correctly (before the section title) in the text output. -->

    <?rfc needLines="8" ?>


    <section anchor="Acknowledgements" title="Acknowledgements"> </section>

    <!-- Possibly a 'Contributors' section ... -->

    <section anchor="IANA" title="IANA Considerations">

      <t>As per <xref target="RFC8126" />, this section makes an assignment in one existing registry in the "Content-Centric Networking (CCNx)" registry group. The registration procedure is "RFC Required", which requires only that this document be published as an RFC.</t>

    	<section anchor="sec.iana1" title="CCNx Name Segment Type Registry">
      	<t>This document defines one message type, T_CHUNK, whose suggested value is %x0004.</t>
    	</section>

     	<section anchor="sec.iana2" title="CCNx Message Type Registry">
      	<t>This document defines two message types, T_ENDCHUNK, whose suggested value is %x0007, and
          T_CHUNK_SIZE, whose value is %0x000F.</t>
    	</section>

    </section>

    <section anchor="Security" title="Security Considerations">
      <t>This draft does not put any requirements on how chunked data is signed or validated.</t>
    </section>
  </middle>

  <!--  *****BACK MATTER ***** -->

  <back>
    <!-- References split into informative and normative -->

    <!-- There are 2 ways to insert reference entries from the citation libraries:
    1. define an ENTITY at the top, and use "ampersand character"RFC2629; here (as shown)
    2. simply use a PI "less than character"?rfc include="reference.RFC.2119.xml"?> here
       (for I-Ds: include="reference.I-D.narten-iana-considerations-rfc2434bis.xml")

    Both are cited textually in the same manner: by using xref elements.
    If you use the PI option, xml2rfc will, by default, try to find included files in the same
    directory as the including file. You can also define the XML_LIBRARY environment variable
    with a value containing a set of directories to search.  These can be either in the local
    filing system or remote ones accessed by http (http://domain/dir/... ).-->

    <references title="Normative References">
      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml"?-->
      &RFC2119; 
      &RFC8126;
      &RFC8174;
      &RFC8569;
      &RFC8609;
    </references>

    <references title="Informative References">
      <!-- Here we use entities that we defined at the beginning. -->




      <!-- A reference written by by an organization not a person. -->

<reference anchor="FLIC" target="https://datatracker.ietf.org/doc/html/draft-irtf-icnrg-flic-05">
<front>
<title>File-Like ICN Collections (FLIC)</title>
<author initials="C." surname="Tschudin" fullname="Christian Tschudin">
<organization>University of Basel</organization>
</author>
<author initials="C. A." surname="Wood" fullname="Christopher A. Wood">
<organization>Cloudflare</organization>
</author>
<author initials="M." surname="Mosko" fullname="Marc Mosko">
<organization></organization>
</author>
<author initials="D. R." surname="Oran" fullname="David R. Oran">
<organization>Network Systems Research &amp; Design</organization>
</author>
<date month="October" day="22" year="2023"/>
</front>
<seriesInfo name="Internet-Draft" value="draft-irtf-icnrg-flic-05"/>
</reference>
      
    </references>

  </back>
</rfc>
