RFC 171

The Data Transfer Protocol

πŸ“… published June 1971, from ietf

THE DATA TRANSFER PROTOCOL πŸ’–

Okay bestie, first the title-block vibe check πŸŽ€ This is RFC 171, filed under NIC 6793 in the Network Working Group, and it's dated 23 June 1971. Its categories are D.4, D.5, and D.7 πŸ—‚οΈ. It updates 114 and obsoletes None, so nothing gets retired here. The squad behind it is Abhay Bhushan (MIT), Bob Braden (UCLA), Will Crowther and Alex McKenzie (BBN), Eric Harslem and John Heafner (Rand), John Melvin and Dick Watson (SRI), Bob Sundberg (HARVARD), and Jim White (UCSB). Main character energy, all of them πŸ‘‘


I. INTRODUCTION ✨

Okay so there's one common protocol that basically everyone needs for moving data around πŸ¦‹ Think about it: remote job entry, file transfer, network mail, graphics, remote program execution, and talking to block data terminals (printers, card, paper tape, and magnetic tape equipment, especially with terminal IMPs). That's a LOT of different vibes.

We could cram every single one of those into one giant all-inclusive file transfer protocol πŸ’… but honestly? Splitting data transfer away from the application stuff gives implementers more flexibility AND keeps things simpler. It also means fewer programs and protocols getting spawned everywhere. Iconic 🧚

So we defined a low-level data transfer protocol (DTP) for moving data in file transfer, remote job entry, and other application protocols 🌸 This paper is ONLY about DTP, no distractions. The companion paper, RFC 172, is the one that describes file transfer protocol, so go check that out too πŸ’œ


II. DISCUSSION πŸ“

The data transfer protocol (DTP) has three basic jobs ✨ First, it neatly chops NCP messages into "logical" blocks (transactions, units, records, groups, and files). Second, it lets you separate data from control information. Third, it includes some error control mechanisms. Not bad for a little protocol πŸ’–

Three modes of separating messages into transactions [1] are allowed by DTP. Mode one is an indefinite bit stream that only ends when the connection is closed, so the whole bit stream is one single transaction for the entire life of the connection 🌊 This would be useful for data transfer between hosts and terminal IMPs (TIPs).

Mode two is the "transparent" block convention, which is kinda like the ASCII DLE (Data Link Escape) πŸ™ˆ In transparent mode, transactions (which MAY be arbitrarily long) end whenever the character sequence DLE ETX shows up (DLE and ETX are 8-bit character codes). To stop a DLE ETX from sneaking into the data stream, every DLE gets replaced with DLE DLE on the way out, and the extra DLE gets stripped on the way in. The plot twist 🫢: a transparent block starts with a transaction type byte instead of DLE STX like ASCII does. This mode will be useful for data transfer between terminal IMPs.

Mode three uses a count mechanism πŸ“ Each transaction begins with a fixed-length descriptor field holding separate binary counts of information bits and filler bits. If a transaction has no filler bits, its filler count is zero. This mode will be useful in most host-to-host data transfer applications.

DTP lets you mix these modes on the same connection, because the mode belongs to the transaction and not the connection πŸ’« (i.e., mode is not associated with connection, but only with transaction). The transfer modes above can carry either data or control information. The protocol also lets you separate data from control at a lower level, using different "type" codes (see SPECIFICATIONS) for data and control transactions. This provision MAY simplify some implementations, periodt ✨

The implementation of a workable [2] subset of the above modes is specifically permitted by DTP, so you're totally allowed to only build some of them πŸ’… To keep hosts with different subsets compatible, an initial "handshake" procedure is REQUIRED by DTP. The handshake swaps information about which modes are available for transmit and receive, so host programs can agree on transfer modes that work for a connection 🀝

How DTP gets used really depends on the applications protocol, because that's the thing that defines the workable subset of transfer modes πŸ‘‘ Like, the file transfer protocol won't work with ONLY the indefinite bit stream modes, bestie. For control information, at least one of the other two modes is REQUIRED. The use of the information separator and abort functions DTP provides (see SPECIFICATIONS) is also decided by the applications protocol. For example, in a remote job entry protocol, aborts MAY be used to stop a job from running, but in another applications protocol they MAY not cause any action at all πŸ™ƒ

It SHOULD also be noted, bestie, that DTP does not define a data transfer service πŸ™… There's no standard server socket and no initial connection protocol defined for DTP. What DTP does define is a mechanism for data transfer that can power block data transfers, file transfers, remote job entry, network mail, and tons of other applications πŸ’–

There are to be no restrictions on how DTP gets implemented at different sites 🧚 For example, DTP MAY be embedded in an applications program (like file transfer), or it MAY be a separate service program or subroutine that several applications programs use. Another implementation MAY employ macros or UUO's (user unimplemented operations on PDP-10's) to achieve the functions specified in DTP. It's also possible that the separation between DTP and the applications protocols only exists at a conceptual level, iykyk 🌈


III. SPECIFICATIONS πŸŽ€

1. Byte Size for Network Connection πŸ’œ

The standard byte size for network connections using DTP is 8-bit. Other byte sizes specified by higher-level applications protocols or applications programs are also allowed by DTP ✨ For this document, bytes are assumed to be 8-bits unless otherwise stated.

2. Transactions πŸ¦‹

At the DTP level, everything sent over a connection is a sequence of transactions. DTP defines the rules for delimiting those transactions [3].

2A. Types 🌸

The first byte of each transaction SHALL define a transaction type, as shown below πŸ’… (Note that code assignments do not conflict with the assignments in TELNET protocol.) The transaction types MAY be referred to by the hexadecimal code assigned to them. They're discussed in more detail in section 2B.

           Code                 Transaction Type
      Hex       Octal

      B0         260        Indefinite bit stream -- data.
      B1         261        Transparent (DLE) block--data.
      B2         262        Descriptor and counts--data.
      B3         263        Modes available (handshake).
      B4         264        Information separators (endcode).
      B5         265        Error codes.
      B6         266        Abort.
      B7         267        No operation (NoOp).
      B8         270        Indefinite bit stream--control.
      B9         271        Transparent (DLE) block--control.
      BA         272        Descriptor and counts--control.
      BB         273        (unassigned but reserved for data transfer)
      BC         274                  "         "         "
      BD         275                  "         "         "
      BE         276                  "         "         "
      BF         277                  "         "         "

2B. Syntax and Semantics 🧁

2B.1 Type B0 and B8 (indefinite bitstream modes) transactions 🌊

These transactions terminate only when the NCP connection is "closed". There's no other escape convention defined in DTP at this level. It SHOULD be noted that closing the connection in bitstream mode represents an implicit file separator (see section 2B.5).

2B.2 Type B1 and B0 (transparent block modes) transactions 🫧

These transactions terminate when the byte sequence DLE ETX is encountered. The sender SHALL replace any occurrence of DLE in the data stream with DLE DLE. The receiver SHALL strip the extra DLE. The transaction is assumed to be byte-oriented. The code for DLE is Hex '90' or Octal '220' (this is different from the ASCII DLE, which is Hex '10' or Octal '020'). ETX is Hex '03' or Octal '03' (the same as ASCII ETX) [4].

2B.3 Type B2 and BA (descriptor and counts modes) transactions πŸ“¦

These transactions have three fields: a 9-byte (72-bits) descriptor field [5], plus variable length (including zero) info and filler fields, as shown below. The total length of a transaction is (72+info+filler) bits.

|<B2 or BA><Info count><NUL><Seq #><NUL><filler count>|<info><filler> |

|  3-bits    24-bits 8-bits 16-bits 8-bits  8-bits    |Variable length|
|<----- 72-bit descriptor field --------------------->|info and filler|

okay so info count is a binary count of how many bits are in the info field πŸ’– It doesn't count the descriptor or filler bits, so don't mix those up bestie 🧚 Since there are 24 bits in the info count field, the number of info bits is capped at (2**24 - 1) ✨

sequence # is a sequential count in a round-robin way for B2 and BA type transactions πŸ” Sequence numbers are lowkey giving debugging and error control energy πŸ•΅οΈ They can be used to check for missing transactions and help track down errors. Hosts who aren't into this mechanism should have all 1's in the field πŸ™ˆ The count shall start from zero and go up sequentially to all 1's, and after that it resets to all zeros. The permitted sequence numbers are one greater than the previous one, and all 1's πŸ’…

filler count is a binary count of the bits used as fillers (aka not actual information) after the end of the meaningful data 🫢 The number of filler bits is capped at 255, since there are 8 bits in the filler count field 🌸

The NUL bytes contain all 0's πŸ“

2B.4. Type B3 (modes available) transactions πŸŽ€

Type B3 transactions are a fixed 3 bytes long, as shown below πŸ¦‹ The first byte is the transaction type (B3), the second byte lists the modes available for send, and the third byte lists the modes available for receive ✨

+------------------+---------------------+---------------------+
|    Type          |     I send          |     I receive       |
|                  | | |  |  |  |  |  |  | | |  |  |  |  |  |  |
|     B3           |0|0|BA|B2|B9|B1|B8|B0|0|0|BA|B2|B9|B1|B8|B0|
+------------------+---------------------+---------------------+

The modes are shown with bit-coding, as you can see above πŸ”₯ If a particular bit (or bits) is set to logical "1", that mode is available. The 2 most significant bits should be set to logical "0" πŸ’œ Type B3 transactions get discussed in section 3B, so peek there later πŸ‘‘

2B.5. Type B4 (information separator) transactions 🌈

Type B4 transactions are a fixed 2 bytes long 🧚 The first byte is the transaction type (B4), and the second byte is the separator ✨

+------------------+------------------+
|    Type          |     End Code     |
|                  |            | |R| |
|                  |            |G|E| |
|     B4           |           F|R|C|U|
|                  |           I|O|O|N|
|                  |           L|U|R|I|
|                  |           E|P|D|T|
+------------------+------------------+

These separator codes are assigned:

        Code                    Meaning
Hex             Octal

01              001             Unit separator
03              003             Record separator
07              007             Group separator
0F              017             File separator

Files, groups, records, and units can be data blocks that a user defines to be that thing πŸŽ€ The only restriction is the hierarchy File>Groups>Records>Units (where '>' means 'contains') πŸ’… So a file separator doesn't just mark the end of a file, it also marks the end of the group, record, and unit, which is so iconic 😭 These separators may give you a handy "logical" split of data at the data transfer level 🌸 How they get used is governed by the applications protocol 🫢

2B.6. Type B5 (error codes) transactions πŸ’€

Type B5 transactions are a fixed 3 bytes long πŸ™ˆ The first byte is the transaction type (B5), the second byte is an error code, and the third byte may indicate the sequence number where the error happened ✨

+------------------+-------------------+-----------------+
|    Type          |     Error Code    |     Sequence #  |
|                  |                   |                 |
|     B5           |                   |                 |
+------------------+-------------------+-----------------+

These error codes are assigned:

    Error Code            Meaning
Hex           Octal

00            000         Undefined error
01            001         Out of sync. (type code other
                          than B0 through BF).
02            002         Broken sequence (the sequence #
                          field contains the first expected
                          but not received sequence number).
03            003         Illegal DLE sequence (other than
                          DLE DLE or DLE ETX).
B0            260
      through       through        The transaction type (indicated by
BF            277         by error code) is not implemented.

The error code transaction is only defined for error control, so no drama πŸ¦‹ DTP does not require the receiver of an error code to take any recovery action, and the receiver may discard the error code transaction πŸ₯Ή DTP also does not require that sequence numbers be remembered or transmitted πŸ’œ

2B.7. Type B6 (abort) transactions 🚫

Type B6 transactions are a fixed 2 bytes long, as shown below ✨ The first byte is the transaction type (B6), and the second byte defines the abort function πŸ’–

+-------------------+--------------------+
|    Type           |    Function        |
|                   |            | | |R| |
|                   |            | |G|E| |
|                   |            |F|R|C|U|
|                   |            |I|O|O|N|
|                   |            |L|U|R|I|
|                   |            |E|P|D|T|
+-------------------+--------------------+

These abort codes are assigned:

    Abort Code                              Meaning
  Hex            Octal

  00             000              Abort preceding transaction
  01             001              Abort preceding unit
  02             002              Abort preceding record
  07             007              Abort preceding group
  0F             017              Abort preceding file

DTP does not require the receiver of an abort to take any specific action, so the sender should not necessarily make any assumptions πŸ™ƒ How abort gets handled is up to the higher-level applications protocols 🌈

2B.8. Type B7 (NoOp) transactions 🧸

Type B7 transactions are one byte long and indicate no operation πŸ’€ These may be useful as fillers when the byte size used for network connections is something other than 8 bits ✨

3. Initial Connection, Handshake and Error Recovery 🀝

3A. DTP doesn't specify the mechanism used to set up connections 🫢 It's up to the applications protocol (for example, a file transfer protocol) to pick the mechanism that fits its needs [6] πŸ’…

3B. The first transaction after a connection is made will be type B3 (modes available) πŸŽ€ On a full-duplex connection, both the server and the user send type B3 transactions to show the modes they have available for send and receive 🌸 On a simplex connection, only the sender sends a type B3 transaction πŸ¦‹ It's the sender's job to choose a mode the receiver can accept πŸ‘‘ If there's no acceptable mode available, or the mode chosen isn't acceptable, the connection may be closed [7] 😭

3C. DTP doesn't specify any error recovery mechanisms πŸ™ˆ The applications protocol may implement error recovery and further error control mechanisms on its own πŸ’–


END NOTES πŸ“

[1] The term transaction is used here to mean a block of data defined by the transfer mode πŸ’œ

[2] What counts as a workable subset is totally governed by the high-level application protocol 🧚

[3] Transactions skip the idea of host-IMP messages, and they can have a logical interpretation similar to flags (and data) defined by Mealy in RFC 91 ✨

[4] This assignment was made to match the TELNET philosophy of keeping the integrity of the 128 Network ASCII characters 🌈

[5] A 72-bit descriptor field gives a handy separation of information bits, since 72 is the least common multiple of 8 and 36, which are the commonly encountered byte sizes on ARPA network host computers πŸ“

[6] It is, however, recommended that the standard initial connection protocol be adopted where feasible 🫢

[7] It is recommended that when more than one mode is available, the sender should choose 'descriptor and count' mode (Type B2 or BA) πŸ’… The 'bitstream' mode (type B0 or B8) should be chosen only when the other two modes cannot be used πŸ”₯

[ This RFC was put into machine readable form for entry ] [ into the online RFC archives by Samuel Etler 08/99 ]

πŸ“¦ where this page comes from