RFC 1235 EXPERIMENTAL PROTOCOLS · FILE TRANSFER · BROADCASTING

CFDP: Coherent File Distribution Protocol

Broadcast file distribution to reduce load when sending one file to many clients.

On rfc-editor.org ↗
PUBLISHED
June 1991
AUTHORS
J. Ioannidis, G. Maguire
STREAM
Legacy
TRANSPORT PROTOCOL
UDP (or any broadcast datagram protocol)
RECOMMENDED BLOCK SIZE
512 or 1024 bytes
MAXIMUM FILE SIZE
32 MB (with 512-byte blocks), 64 MB (with 1024-byte blocks)
TYPICAL PACKET SIZE
552 bytes (under IP MTU minimum of 576 bytes)
DOI
10.17487/RFC1235

RFC text

Contents
Original text · RFC Editor View on rfc-editor.org ↗
Network Working Group                                       J. Ioannidis
Request for Comments:  1235                              G. Maguire, Jr.
                                                     Columbia University
                                          Department of Computer Science
                                                               June 1991


                The Coherent File Distribution Protocol

Status of this Memo

   This memo describes the Coherent File Distribution Protocol (CFDP).
   This is an Experimental Protocol for the Internet community.
   Discussion and suggestions for improvement are requested.  Please
   refer to the current edition of the "IAB Official Protocol Standards"
   for the standardization state and status of this protocol.
   Distribution of this memo is unlimited.

Introduction

   The Coherent File Distribution Protocol (CFDP) has been designed to
   speed up one-to-many file transfer operations that exhibit traffic
   coherence on media with broadcast capability.  Examples of such
   coherent file transfers are identical diskless workstations booting
   simultaneously, software upgrades being distributed to more than one
   machines at a site, a certain "object" (bitmap, graph, plain text,
   etc.) that is being discussed in a real-time electronic conference or
   class being sent to all participants, and so on.

   In all these cases, we have a limited number of servers, usually only
   one, and <n> clients (where <n> can be large) that are being sent the
   same file.  If these files are sent via multiple one-to-one
   transfers, the load on both the server and the network is greatly
   increased, as the same data are sent <n> times.

   We propose a file distribution protocol that takes advantage of the
   broadcast nature of the communications medium (e.g., fiber, ethernet,
   packet radio) to drastically reduce the time needed for file transfer
   and the impact on the file server and the network.  While this
   protocol was developed to allow the simultaneous booting of diskless
   workstations over our experimental packet-radio network, it can be
   used in any situation where coherent transfers take place.

   CFDP was originally designed as a back-end protocol; a front-end
   interface (to convert file names and requests for them to file
   handles) is still needed, but a number of existing protocols can be
   adapted to use with CFDP.  Two such reference applications have been
   developed; one is for diskless booting of workstations, a simplified
   BOOTP [3] daemon (which we call sbootpd) and a simple, TFTP-like
   front end (which we call vtftp).  In addition, our CFDP server has
   been extended to provide this front-end interface.  We do not
   consider this front-end part of the CFDP protocol, however, we
   present it in this document to provide a complete example.

   The two clients and the CFDP server are available as reference
   implementations for anonymous ftp from the site CS.COLUMBIA.EDU
   (128.59.16.20) in directory pub/cfdp/.  Also, a companion document
   ("BOOTP extensions to support CFDP") lists the "vendor extensions"
   for BOOTP (a-la RFC-1084 [4]) that apply here.

Overview

   CFDP is implemented as a protocol on top of UDP [5], but it can be
   implemented on top of any protocol that supports broadcast datagrams.
   Moreover, when IP multicast [6] implementations become more
   widespread, it would make more sense to use a multicast address to
   distribute CFDP packets, in order to reduce the overhead of non-
   participating machines.

   A CFDP client that wants to receive a file first contacts a server to
   acquire a "ticket" for the file in question.  This server could be a
   suitably modified BOOTP server, the equivalent of the tftpd daemon,
   etc. The server responds with a 32-bit ticket that will be used in
   the actual file transfers, the block size sent with each packet
   (which we shall call "BLKSZ" from now on), and the size (in bytes) of
   the file being transferred ("FILSZ").  BLKSZ should be a power of
   two.  A good value for BLKSZ is 512. This way the total packet size
   (IPheader+UDPheader+CFDPheader+data=20+8+12+512=552), is kept well
   under the magic number 576, the minimum MTU for IP networks [7].
   Note that this choice of BLKSZ supports transfers of files that are
   up to 32 Mbytes in size.  At this point, the client should allocate
   enough buffer space (in memory, or on disk) so that received packets
   can be placed directly where they belong, in a way similar to the
   NetBLT protocol [8].

   It is assumed that the CFDP server will also be informed about the
   ticket so that it can respond to requests.  This can be done, for
   example, by having the CFDP server and the ticket server keep the
   table of ticket-to-filename mappings in shared memory, or having the
   CFDP server listening on a socket for this information.  To reduce
   overhead, it is recommended that the CFDP server be the same process
   as the front-end (ticket) server.

   After the client has received the ticket for the file, it starts
   listening for (broadcast) packets with the same ticket, that may
   exist due to an in-progress transfer of the same file.  If it cannot
   detect any traffic, it sends to the CFDP server a request to start
   transmitting the whole file.  The server then sends the entire file
   in small, equal-sized packets consisting of the ticket, the packet
   sequence number, the actual length of data in this packet (equal to
   BLKSZ, except for the last packet in the transfer), a 32-bit
   checksum, and the BLKSZ bytes of data.  Upon receipt of each packet,
   the client checksums it, marks the corresponding block as received
   and places its contents in the appropriate place in the local file.
   If the client does not receive any packets within a timeout period,
   it sends to the CFDP server a request indicating which packets it has
   not yet received, and then goes back to the receiving mode.  This
   process is repeated until the client has received all blocks of the
   file.

   The CFDP server accepts requests for an entire file ("full" file
   requests, "FULREQ"s), or requests for a set of BLKSZ blocks
   ("partial" file requests, "PARREQ"s).  In the first case, the server
   subsequently broadcasts the entire file, whereas in the second it
   only broadcasts the blocks requested.  If a FULREQ or a PARREQ
   arrives while a transfer (of the same file) is in progress, the
   requests are ignored.  When the server has sent all the requested
   packets, it returns to its idle state.

   The CFDP server listens for requests on UDP/IP port "cfdpsrv". The
   clients accept packets on UDP/IP port "cfdpcln" (both to be defined
   by the site administrator), and this is the destination of the
   server's broadcasts.  Those two port numbers are sent to the client
   with the initial handshake packet, along with the ticket.  If the
   minimal ticket server is implemented as described later in this
   document, it is recommended (for interoperability reasons) that it
   listens for requests on UDP/IP port 120 ("cfdptkt").

   Let us now examine the protocol in more detail.

Protocol Specification

 Initial Handshake (not strictly part of the protocol):

   The client must acquire a ticket for the file it wishes to transfer,
   and the CFDP server should be informed of the ticket/filename
   mapping.  Again, this can be done inside a BOOTP server, a modified
   TFTP server, etc., or it can be part of the CFDP server itself.  We
   present here a suggested protocol for this phase.

   The client sends a "Request Ticket" (REQTKT) request to the CFDP
   Ticket server, using UDP port "cfdptkt".  If the address of the
   server is unknown, the packet can be sent to the local broadcast
   address.  Figure 1 shows the format of this packet.

       0                   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
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |      'R'      |      'Q'      |      'T'      |      'K'      |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      /                                                               /
      \     Filename, null-terminated, up to 512 octets               \
      /                                                               /
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                       Fig. 1: "ReQuest TicKet" packet.

   The filename is limited to 512 octets.  This should not cause a
   problem in most, if not all, cases.

   The ticket server replies with a "This is Your Ticket" (TIYT) packet
   containing the ticket.  Figure 2 shows the format of this packet.

       0                   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'      |      'I'      |      'Y'      |      'T'      |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           "ticket"                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                       BLKSZ (by default 512)                  |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                             FILSZ                             |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |            IP address of CFDP server (network order)          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |   client UDP port# (cfdpcln)  |   server UDP port# (cfdpsrv)  |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                    Fig. 2: "This Is Your Ticket" packet.

   The reply is sent to the UDP port that the RQTK request came from.
   The IP address of the CFDP server is provided because the original
   handshake server is not necessarily on the same machine as the ticket
   server, let alone the same process.  Similarly, the cfdpcln and
   cfdpsrv port numbers (in network order) are communicated to the
   client.  If the client does not use this ticket server, but rather
   uses BOOTP or something else, that other server should be responsible
   for providing the values of cfdpcln and cfdpsrv.  The ticket server
   also communicates this ticket/filename/filesize to the real CFDP
   server.  It is recommended that the ticket requests be handled by the
   regular CFDP server, in which case informing the CFDP server of the
   ticket/filename binding is trivial (as it is internal to the
   process).

   Once the client has received the ticket for the filename it has
   requested, the file distribution can proceed.

 Client Protocol:

   Once the ticket has been established, the client starts listening for
   broadcast packets on the cfdpcln/udp port that have the same "ticket"
   as the one it is interested in.  In the state diagram below, the
   client is in the CLSTART state.  If the client can detect no packets
   with that ticket within a specified timeout period, "TOUT-1", it
   assumes that no transfer is in progress.  It then sends a FULREQ
   packet (see discussion above) to the CFDP server, asking it to start
   transmitting the file, and goes back to the CLSTART state (so that it
   can time out again if the FULREQ packet is lost).  Figure 3 shows the
   format of the FULREQ packet.

       0                   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
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           "ticket"                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           checksum                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |      'F'      |       0       |         length == 0           |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                  Fig. 3: FULREQ (FULl file REQuest) packet.

   When the first packet arrives, the client moves to the RXING state
   and starts processing packets.  Figure 4 shows the format of a data
   packet.

       0                   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
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           "ticket"                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           checksum                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |          block number         |          data length          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      /                                                               /
      \      up to BLKSZ octets of data                               \
      /                                                               /
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                             Fig. 4: Data Packet

   The format is self-explanatory.  "Block number" the offset (in
   multiples of BLKSZ) from the beginning of the file, data length is
   always BLKSZ except for the very last packet, where it can be less
   than that, and the rest is data.

   As each packet arrives, the client verifies the checksum and places
   the data in the appropriate position in the file.  While the file is
   incomplete and packets keep arriving, the client stays in the RXING
   state, processing them.  If the client does not receive any packets
   within a specified period of time, "TOUT-2", it times out and moves
   to the INCMPLT state.  There, it determines which packets have not
   yet been received and transmits a PARREQ request to the server.  This
   request consists of as many block numbers as will fit in the data
   area of a data packet.  If one such request is not enough to request
   all missing packets, more will be requested when the server has
   finished sending this batch and the client times out.  Also, if the
   client has sent a PARREQ and has not received any data packets within
   a timeout period, "TOUT-3", it retransmits the same PARREQ.  Figure 5
   shows the format of the PARtial REQuest packet.

       0                   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
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           "ticket"                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           checksum                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |      'P'      |       0       |      data length (2*N)        |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |           Block #0            |           Block #1            |
      |           Block #2            |           Block #3            |
      /                                                               /
      \      data  (block numbers requested)                          \
      /                                                               /
      |           Block #N-2          |           Block #N-1          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                Fig. 5: PARREQ (PARtial file REQuest) packet.

   When all packets have been received the client enters the CLEND state
   and stops listening.

   Figure 6 summarizes the client's operations in a state diagram.

                           +-----------+
                           |  CLSTART  |
                           |           | <---.
                           |   send    |     | timeout TOUT-1
                           |  FULREQ   | ----'
                           |           |
                           +-----------+
                                 |
             received packet     | received packet
      .-----------------------.  |
      |                       V  V
     +---------+             +---------+
     | INCMPLT |             |  RXING  |
     |         |   timeout   |         | <---.
     |  send   |<------------| process |     | received packet
     | PARREQ  |    TOUT-2   | packet  | ----'
     |         |             |         |
     +---------+             +---------+
        ^   |                     |
        |   |                     |finished
        `---'                     |
       timeout                    V
        TOUT-3               +---------+
                             |  CLEND  |
                             +---------+

                Fig. 6: Client State Transition Diagram

 Server Protocol:

   As described above, the CFDP server accepts two kinds of requests: a
   request for a full file transfer, "FULREQ", and a request for a
   partial (some blocks only) file transfer, "PARREQ".  For the first,
   it is instructed to start sending out the contents of a file.  For
   the second, it will only send out the requested blocks.  The server
   should know at all times which files correspond to which "tickets",
   and handle them appropriately.  Note that this may run into
   implementation limits on some Unix systems (e.g., on older systems, a
   process could only have 20 files open at any one time), but that
   should not normally pose a problem.

   The server is initially in the SIDLE state, idling (see diagram
   below).  When it receives a FULREQ packet, it goes to the FULSND
   state, whence it broadcasts the entire contents of the file whose
   ticket was specified in the FULREQ packet.  When it is done, it goes
   back to the SIDLE state. When it receives a PARREQ packet, it goes to
   the PARSND state and broadcasts the blocks specified in the PARREQ
   packet. When it has finished processing the block request, it goes
   once again back to the SIDLE state.

                     receive    +-------+    receive
                .---------------| SIDLE |---------------.
                |    FULREQ     +-------+     PARREQ    |
                |                 ^   ^                 |
                |                 |   |                 |
                V                 |   |                 V
            +--------+            |   |            +--------+
            | FULSND |            |   |            | PARSND |
            |        |    done    |   |    done    |        |
            |  send  |------------'   `------------|  send  |
            | entire |                             | req'ed |
            |  file  |                             | blocks |
            +--------+                             +--------+

                Fig. 7: Server State Transition Diagram

Packet Formats

   The structure of the packets has been already described.  In all
   packet formats, numbers are assumed to be in network order ("big-
   endian"), including the ticket and the checksum.

   The checksum is the two's complement of the unsigned 32-bit sum with
   no end-around-carry (to facilitate implementation) of the rest of the
   packet.  Thus, to compute the checksum, the sender sets that field to
   zero and adds the contents of the packet including the header.  The
   it takes the two's complement of that sum and uses it as the
   checksum.  Similarly, the receiver just adds the entire contents of
   the packet, ignoring overflows, and the result should be zero.

Tuneable Parameters: Packet Size, Delays and Timeouts

   It is recommended that the packet size be less than the minimum MTU
   on the connected network where the file transfers are taking place.
   We want this so that there be no fragmentation; one UDP packet should
   correspond to one hardware packet.  It is further recommended that
   the packet size be a power of two, so that offsets into the file can
   be computed from the block number by a simple logical shift
   operation.  Also, it is usually the case that page-aligned transfers
   are faster on machines with a paged address space.  Small packet
   sizes are inefficient, since the header will be a larger fraction of
   the packet, and packets larger than the MTU will be fragmented.  A
   good selection for BLKSZ is 512 or 1024. Using that BLKSZ, one can
   transfer files up to 32MB or 64MB respectively (since the limit is
   the 16-bit packet sequence number).  This is adequate for all but
   copying complete disks, and it allows twice as many packets to be
   requested in a PARREQ request than if the sequence number were 32
   bits.  If larger files must be transferred, they could be treated as
   multiple logical files, each with a size of 32MB (or 64MB).

   Since most UDP/IP implementations do not buffer enough UDP datagrams,
   the server should not transmit packets faster than its clients can
   consume them.  Since this is a one-to-many transfer, it is not
   desirable to use flow-control to ensure that the server does not
   overrun the clients.  Rather, we insert a small delay between packets
   transmitted.  A good estimate of the proper delay between two
   successive packets is twice the amount of time it takes for the
   interface to transmit a packet.  On Unix implementations, the ping
   program can be used to provide an estimate of this, by specifying the
   same packet length on the command line as the expected CFDP packet
   length (usually 524 bytes).

   The timeouts for the client are harder to compute. While there is a
   provision for the three timeouts (TOUT-1, TOUT-2 and TOUT-3) to be
   different, there is no compelling reason not to make them the same.
   Experimentally, we have determined that a timeout of 6-8 times the
   transfer time for a packet works best.  A timeout of less than that
   runs the risk of mistaking a transient network problem for a timeout,
   and more than that delays the transfer too much.

Summary

   To summarize, here is the timeline of a sample file distribution
   using CFDP to three clients.  Here we request a file with eight
   blocks.  States are capitalized, requests are preceded with a '<'
   sign, replies are followed by a '>' sign, block numbers are preceded
   with a '#' sign, and actions are in parentheses:

SERVER       CLIENT1     CLIENT-2      CLIENT-3      comments

IDLE                                                everybody idle
             CLSTART                                CL1 wants a file
             <TKRQ                                  requests ticket
TIYT>                                               server replies
             (timeout)                              listens for traffic
             <FULREQ                                full request
#0           RXING                                  CL1 starts receiving
             (rx 0)
#1           (rx 1)      CLSTART                    CL2 decides to join
                         <TKRQ
#2           (rx 2)                                 SRV still sending
TIYT>                                               responds to TKRQ
#3           (rx 3)      (listens)                  CL2 listens
                         RXING                      found traffic

#4           (rx 4)      (rx 4)        CLSTART      CL3 joins in
                                       <TKRQ
#5           (missed)    (rx 5)                     CL1 missed a packet
TIYT>                                  (listens)
#6           (rx 6)      (rx 6)        RXING        CL3 found traffic

#7           (rx 7)      (rx 7)        (rx 7)       Server finished
IDLE
             (wait)      (wait)        (wait)       CL1 managed to
             (timeout)   (wait)        (wait)       timeout
             <PARREQ[5]  (timeout)     (timeout)    CL1 blockrequests...
#5           (rx 5)      <PARREQ[0123] <PARREQ[0123456] ignored by SRV
             CLEND                                  CL1 has all packets
IDLE                     (wait)        (wait)       CL2+3 missed #5
                         (timeout)     (timeout)
                         <PARREQ[0123] <PARREQ[0123456] CL2's req gets
#0                       (rx 0)        (rx 0)       through, CL3 ignored
#1                       (rx 1)        (rx 1)       moving along
#2                       (rx 2)        (rx 2)
#3                       (rx 3)        (rx 3)
IDLE                     CLEND         (wait)       CL2 finished
                                       (timeout)
                                       <PARREQ[456]
#4                                     (rx 4)
#5                                     (rx 5)
#5                                     (rx 6)
IDLE                                   CLEND        CL3 finished

References

   [1] Sollins, K., "The TFTP Protocol (Revision 2)", RFC 783, MIT, June
       1981.

   [2] Finlayson, R., "Bootstrap Loading Using TFTP", RFC 906, Stanford,
       June 1984.

   [3] Croft, W., and J. Gilmore, "Bootstrap Protocol", RFC 951,
       Stanford and SUN Microsystems, September 1985.

   [4] Reynolds, J., "BOOTP Vendor Information Extensions", RFC 1084,
       USC/Information Sciences Institute, December 1988.

   [5] Postel, J., "User Datagram Protocol", RFC 768, USC/Information
       Sciences Institute, August 1980.

   [6] Deering, S., "Host Extensions for IP Multicasting", RFC 1112,
       Stanford University, August 1989.

   [7] Postel, J., "Internet Protocol - DARPA Internet Program Protocol
       Specification", RFC 791, DARPA, September 1981.

   [8] Clark, D., Lambert, M., and L. Zhang, "NETBLT: A Bulk Data
       Transfer Protocol", RFC 998, MIT, March 1987.

Security Considerations

   Security issues are not discussed in this memo.

Authors' Addresses

   John Ioannidis
   Columbia University
   Department of Computer Science
   450 Computer Science
   New York, NY 10027

   EMail:  ji@cs.columbia.edu


   Gerald Q. Maguire, Jr.
   Columbia University
   Department of Computer Science
   450 Computer Science
   New York, NY 10027

   Phone:  (212) 854-2736

   EMail:  maguire@cs.columbia.edu

AI ELI5

On this page
PROBLEMSending the same file to many clients one-to-one wastes server and network resources, and takes a long time. Examples include booting diskless workstations, distributing software updates, or sharing media in real-time conferences.
MECHANISMCFDP runs on top of UDP and broadcasts file blocks to all interested clients at once. Clients listen for packets matching their ticket, checksum each block, and request any missing blocks from the server.
WHY IT MATTERSMultiple clients can receive a file in parallel over a single broadcast stream, reducing server load and transfer time compared to individual unicast transfers.

§1The Problem of One-to-Many File Distribution

CFDP addresses a common networking challenge: efficiently distributing identical files to multiple recipients. When a server sends the same file to many clients using traditional one-to-one transfers, the server must open a separate connection and send the entire file n times, consuming server resources and network capacity proportionally to the number of clients.

The RFC describes practical scenarios where this becomes a bottleneck: diskless workstations booting simultaneously, software upgrades deployed to multiple machines at a site, or shared objects (documents, graphics, media) being sent to all participants in a real-time conference or classroom.

CFDP leverages broadcast networks (Ethernet, fiber, packet radio) to solve this problem, sending each block of data once over the broadcast medium where all interested clients can receive it together.

Normally, to send a file to ten people, you send it ten separate times. CFDP is like announcing the file on a loudspeaker so everyone can listen in at the same time.

§2How CFDP Works

CFDP is a protocol layer on top of UDP that manages file distribution over broadcast networks. When a client wants a file, it first contacts a ticket server (a separate protocol not strictly part of CFDP) to acquire a 32-bit ticket that uniquely identifies the file transfer, along with the block size (BLKSZ) and total file size (FILSZ). The ticket server also provides the addresses and UDP port numbers for the CFDP server and clients.

The client then listens on the client broadcast port for packets carrying its ticket. If no traffic appears within a timeout period (TOUT-1), it sends a full file request (FULREQ) to the server. The server responds by broadcasting the entire file in equal-sized blocks, each containing the ticket, block number, data length, a 32-bit checksum, and up to BLKSZ bytes of data. When the client receives a packet, it verifies the checksum, stores the block in the correct position in the file, and continues listening.

If the client detects missing blocks after a receive timeout (TOUT-2), it sends a partial file request (PARREQ) listing only the missing block numbers. The server then broadcasts just those blocks. This process repeats until all blocks arrive.

A client asks for a ticket for the file it wants, then listens to the broadcast. The server shouts the file blocks one by one. If the client missed any, it asks the server to shout just those blocks again.

§3Message Formats and Checksums

CFDP defines several message types. A FULREQ packet contains a 32-bit ticket, a 32-bit checksum, a function byte ('F'), a reserved byte, and a two-byte length field (zero for a full request). A PARREQ packet has the same header with function byte 'P' and contains a variable-length list of 16-bit block numbers to request. Data packets carry the ticket, checksum, 16-bit block number, 16-bit data length, and up to BLKSZ bytes of payload.

All numbers are in network byte order. The checksum is computed as the two's complement of the unsigned 32-bit sum (with no end-around-carry) of the rest of the packet. To verify, the receiver sums the entire packet including the checksum field, and the result should be zero. This simple checksum allows receivers to detect corruption without requiring a reliable transport protocol.

The RFC recommends BLKSZ of 512 or 1024 bytes. A 512-byte BLKSZ keeps the total packet size (IP header + UDP header + CFDP header + data = 20 + 8 + 12 + 512 = 552 bytes) well below the minimum IP MTU of 576 bytes, avoiding fragmentation. The 16-bit block number field limits files to 32 MB (with 512-byte blocks) or 64 MB (with 1024-byte blocks).

Each packet has a label (ticket) so the client knows which file it is, a block number so the client knows where in the file it goes, and a check number so the client can tell if the data got scrambled.

CFDP Data Packet Format
Data packet layout
FieldNameSizeValueDescription
TICKETTicket4 bytes32-bit identifier assigned by the ticket server.
CHECKSUMChecksum4 bytesTwo's complement checksum of the packet.
BLOCK-NUMBlock Number2 bytesOffset in multiples of BLKSZ from the start of the file.
DATA-LENData Length2 bytesOctets in this packet; BLKSZ except for the last block.

§4Client and Server State Machines

The client operates in four states: CLSTART (waiting for the first packet), RXING (receiving data), INCMPLT (incomplete; timed out during receive), and CLEND (transfer finished). From CLSTART, if no packet arrives within TOUT-1, the client sends a FULREQ and remains in CLSTART. When the first data packet arrives, the client moves to RXING. If no packets arrive during RXING within TOUT-2, it sends a PARREQ with missing block numbers and moves to INCMPLT. From INCMPLT, if another timeout occurs (TOUT-3), it retransmits the same PARREQ. When all blocks are received, the client enters CLEND and stops.

The server has two request-handling states: FULSND (sending the entire file in response to a FULREQ) and PARSND (sending only the blocks listed in a PARREQ). The server is otherwise in SIDLE (idle). When a FULREQ arrives, the server moves to FULSND and broadcasts all file blocks. When done, it returns to SIDLE. Similarly, PARREQ triggers PARSND. If multiple requests for the same file arrive during an active transfer, they are ignored; only one transfer of a given file proceeds at a time.

The client waits, listens, and if nothing arrives in time, it yells for what it needs. The server either sends the whole file or just the missing pieces, then goes back to waiting.

§5Packet Timing and Timeouts

CFDP performance depends on careful tuning of block size and timeout values. The RFC recommends keeping BLKSZ as a power of two for efficient offset computation, and smaller than the network MTU to avoid fragmentation. A good default is 512 bytes.

The server should insert a small delay between transmitted packets to avoid overwhelming clients' UDP buffers. The RFC suggests twice the transmission time of a single packet (estimated using ping) as a reasonable guideline.

Client timeouts are harder to predict. TOUT-1, TOUT-2, and TOUT-3 (the three timeout periods) should ideally be the same value. Experimental testing by the authors showed that 6 to 8 times the packet transmission time works well. Shorter timeouts risk mistaking transient network problems for loss, while longer timeouts delay the overall transfer. These parameters are implementation-dependent and may need adjustment for different network conditions and switch controllers.

The server should not shout blocks too fast or the client will miss them. The client should wait long enough to be sure a block is really lost before asking again, but not so long that the whole transfer takes forever.

§6References