Next Previous Contents

12. UUCP `i' Protocol

UUCP `i' Protocol

The `i' protocol was written by Ian Lance Taylor (who also wrote this FAQ). It was first used by Taylor UUCP version 1.04.

It is a sliding window packet protocol, like the `g' protocol, but it supports bidirectional transfers (i.e., file transfers in both directions simultaneously). It requires an eight bit clear connection. Several ideas for the protocol were taken from the paper `A High-Throughput Message Transport System' by P. Lauder. I don't know where the paper was published, but the author's e-mail address is `piers@cs.su.oz.au'. The `i' protocol does not adopt his main idea, which is to dispense with windows entirely. This is because some links still do require flow control and, more importantly, because using windows sets a limit to the amount of data which the protocol must be able to resend upon request. To reduce the costs of window acknowledgements, the protocol uses a large window and only requires an ack at the halfway point.

Each packet starts with a six byte header, optionally followed by data bytes with a four byte checksum. There are currently five defined packet types (`DATA', `SYNC', `ACK', `NAK', `SPOS', `CLOSE') which are described below. Although any packet type may include data, any data provided with an `ACK', `NAK' or `CLOSE' packet is ignored.

Every `DATA', `SPOS' and `CLOSE' packet has a sequence number. The sequence numbers are independent for each side. The first packet sent by each side is always number 1. Each packet is numbered one greater than the previous packet, modulo 32.

Every packet has a local channel number and a remote channel number. For all packets at least one channel number is zero. When a UUCP command is sent to the remote system, it is assigned a non-zero local channel number. All packets associated with that UUCP command sent by the local system are given the selected local channel number. All associated packets sent by the remote system are given the selected number as the remote channel number. This permits each UUCP command to be uniquely identified by the channel number on the originating system, and therefore each UUCP package can associate all file data and UUCP command responses with the appropriate command. This is a requirement for bidirectional UUCP transfers.

The protocol maintains a single global file position, which starts at 0. For each incoming packet, any associated data is considered to occur at the current file position, and the file position is incremented by the amount of data contained. The exception is a packet of type `SPOS', which is used to change the file position. The reason for keeping track of the file position is described below.

The header is as follows:

`\007' Every packet begins with `^G'.

`(PACKET << 3) + LOCCHAN' The five bit packet number combined with the three bit local channel number. `DATA', `SPOS' and `CLOSE' packets use the packet sequence number for the PACKET field. `NAK' packet types use the PACKET field for the sequence number to be resent. `ACK' and `SYNC' do not use the PACKET field, and generally leave it set to 0. Packets which are not associated with a UUCP command from the local system use a local channel number of 0.

`(ACK << 3) + REMCHAN' The five bit packet acknowledgement combined with the three bit remote channel number. The packet acknowledgement is the number of the last packet successfully received; it is used by all packet types. Packets which are not sent in response to a UUCP command from the remote system use a remote channel number of 0.

`(TYPE << 5) + (CALLER << 4) + LEN1' The three bit packet type combined with the one bit packet direction combined with the upper four bits of the data length. The packet direction bit is always 1 for packets sent by the calling UUCP, and 0 for packets sent by the called UUCP. This prevents confusion caused by echoed packets.

LEN2 The lower eight bits of the data length. The twelve bits of data length permit packets ranging in size from 0 to 4095 bytes.

CHECK The exclusive or of the second through fifth bytes of the header. This provides an additional check that the header is valid.

If the data length is non-zero, the packet is immediately followed by the specified number of data bytes. The data bytes are followed by a four byte CRC 32 checksum, with the most significant byte first. The CRC is calculated over the contents of the data field.

The defined packet types are as follows:

0 `DATA' This is a plain data packet.

1 `SYNC' `SYNC' packets are exchanged when the protocol is initialized, and are described further below. `SYNC' packets do not carry sequence numbers (that is, the PACKET field is ignored).

2 `ACK' This is an acknowledgement packet. Since `DATA' packets also carry packet acknowledgements, `ACK' packets are only used when one side has no data to send. `ACK' packets do not carry sequence numbers.

3 `NAK' This is a negative acknowledgement. This is sent when a packet is received incorrectly, and means that the packet number appearing in the PACKET field must be resent. `NAK' packets do not carry sequence numbers (the PACKET field is already used).

4 `SPOS' This packet changes the file position. The packet contains four bytes of data holding the file position, most significant byte first. The next packet received will be considered to be at the named file position.

5 `CLOSE' When the protocol is shut down, each side sends a `CLOSE' packet. This packet does have a sequence number, which could be used to ensure that all packets were correctly received (this is not needed by UUCP, however, which uses the higher level `H' command with an `HY' response).

When the protocol starts up, both systems send a `SYNC' packet. The `SYNC' packet includes at least three bytes of data. The first two bytes are the maximum packet size the remote system should send, most significant byte first. The third byte is the window size the remote system should use. The remote system may send packets of any size up to the maximum. If there is a fourth byte, it is the number of channels the remote system may use (this must be between 1 and 7, inclusive). Additional data bytes may be defined in the future.

The window size is the number of packets that may be sent before a packet is acknowledged. There is no requirement that every packet be acknowledged; any acknowledgement is considered to acknowledge all packets through the number given. In the current implementation, if one side has no data to send, it sends an `ACK' when half the window is received.

Note that the `NAK' packet corresponds to the unused `g' protocol `SRJ' packet type, rather than to the `RJ' packet type. When a `NAK' is received, only the named packet should be resent, not any subsequent packets.

Note that if both sides have data to send, but a packet is lost, it is perfectly reasonable for one side to continue sending packets, all of which will acknowledge the last packet correctly received, while the system whose packet was lost will be unable to send a new packet because the send window will be full. In this circumstance, neither side will time out and one side of the communication will be effectively shut down for a while. Therefore, any system with outstanding unacknowledged packets should arrange to time out and resend a packet even if data is being received.

Commands are sent as a sequence of data packets with a non-zero local channel number. The last data packet for a command includes a trailing null byte (normally a command will fit in a single data packet). Files are sent as a sequence of data packets ending with one of length zero.

The channel numbers permit a more efficient implementation of the UUCP file send command. Rather than send the command and then wait for the `SY' response before sending the file, the file data is sent beginning immediately after the `S' command is sent. If an `SN' response is received, the file send is aborted, and a final data packet of length zero is sent to indicate that the channel number may be reused. If an `SY' reponse with a file position indicator is received, the file send adjusts to the file position; this is why the protocol maintains a global file position.

Note that the use of channel numbers means that each UUCP system may send commands and file data simultaneously. Moreover, each UUCP system may send multiple files at the same time, using the channel number to disambiguate the data. Sending a file before receiving an acknowledgement for the previous file helps to eliminate the round trip delays inherent in other UUCP protocols.


Next Previous Contents