Janus (protocol)

Janus is a file transfer protocol for use on bulletin board systems (BBSs). It has the relatively rare feature that it is fully bidirectional, allowing the protocol to upload and download files at the same time. It was written by Rick Huebner in 1987; Huebner had previously written a ZMODEM module for the Opus-CBBS system.

Using Janus, Opus BBS systems could save time exchanging files like FidoNet message packets in both directions at the same time, which Huebner described as sending the shorter file for free. In most cases, a given system in the Fido network would download more messages than it sent back, so in practice, the result was that the reply stream was costless.

Janus was useful in settings where the upstream and downstream links were both of similar performance, which was true in the mid-1980s when most high-speed modems operated at 2,400 bit/s bidirectionally. However, the protocol was introduced almost at the same time as the rapid popularization of the USRobotics HST standard with a 9,600 bit/s download and only 300 bit/s upload, where Janus offered little or no advantage. When higher-speed bidirectional modems appeared, like v.32bis, Janus had already largely disappeared.

Details
Janus is a packet-oriented protocol like XMODEM and similar systems. In these protocols, the file is transferred in "packets" or "blocks", small portions of the file as a whole. As each packet is received it is examined for errors, and if an error is found, an error message is sent back to the sender. The sender then sends the packet again until it either succeeds or the transfer is cancelled after a certain number of errors.

Janus is typical of late 1980s protocols that attempt to make better use of increasing modem speeds. XMODEM transferred only 128 bytes of data per packet, and then waited for a response from the receiver before sending the next packet. Due to the latency of the phone network, the minimum possible time to receive this acknowledgement represented a significant percentage of the time it needed to send the next packet, leading to relatively low channel usage on faster modems.

The solution to this problem used in Janus was to allow the packet size to vary, from 0 to 2052 bytes per packet. With larger packets, the latency of the network represents a much smaller fraction of the time needed to send a packet. Additionally, Janus did not stop and wait for the receiver to acknowledge the reception of the packet, it simply assumed it was received correctly and immediately began sending the next packet. If there was an error, the receiver would signal this back to the sender, and the bad packet would then be re-sent as soon as the current packet was complete.

The basic Janus packet structure consisted of the following pattern:

PKTSTRT, data, PKTYPE, PKTEND, CRC

The PKTSTRT and PKTEND were unique character sequences that allowed the protocol to identify the start and end of the data section. The data section contained 0 to 2052 bytes of data, depending on the PKTYPE. The CRC was a 16-bit cyclic redundancy check, the same applied to XMODEM-CRC (and its variations). There were several different PKTYPEs that represented data packets, acks, naks and other transfer details, as well as the FNAMEPKT which sent file metadata (name, size, etc.) that other protocols handled in "packet zero". In contrast to most other protocols, Janus used a 32-bit offset within the file to identify packets, as opposed to XMODEM-derived protocols which used an internal packet number which was typically a monotonically increasing integer.

An error in Janus would cause the receiver to send a BADPKT packet with the file offset to be sent back, allowing the system to send any packet out-of-order at any time. A large number of errors could be addressed by sending the RPOSPKT packet, which "rewound" the transfer to a given 32-bit address. Unlike other protocols, Janus did not have pre-defined limits on the number of failures that would cause a transfer to fail, transfers only ended when one side or the other explicitly sent a HALTPKT.

The packet size in Janus was selected dynamically based on the number of transmission errors and the time to send a packet. This was the same algorithm Huebner had developed for his version of ZMODEM used in the Opus BBS system. This algorithm was later back-ported into the ZMODEM standard by Chuck Foresberg.