RFC 88

NETRJS: A third level protocol for Remote Job Entry

๐Ÿ“… published January 1971, from ietf

NETRJS - A THIRD LEVEL PROTOCOL FOR REMOTE JOB ENTRY โœจ

Network Working Group ๐ŸŽ€ Request for Comments: 88 ๐Ÿ’œ

Okay bestie, the title block is giving very "classic 1971" energy ๐Ÿงš. This RFC was written by R. Braden and S. Wolfe from UCLA/CCN, with the NIC number 5668, and it's dated 13 January 1971. The original doesn't list any RFCs it obsoletes or updates, so there's nothing to report there ๐Ÿ™ˆ.


A. Introduction ๐ŸŒธ

okay so NETRJS is the name for a message protocol plus a set of control conventions that let users at remote Hosts reach the RJS ("Remote Job Service") remote batch subsystem of CCN ๐Ÿ’…. RJS[1] was written at CCN to support remote batch terminals (the car reader and line printer kind) over communications lines ๐Ÿ–จ๏ธ.

RJS makes a remote batch terminal's unit record devices behave as if they were sitting at the central site, so it's giving "I'm physically far away but I'm still in the room" ๐Ÿฆ‹. A remote user sends OS/360 jobs, complete with JCL, into the remote reader. The jobs get spooled into the operating system and run when it's their turn โณ. Then the printed and/or punched output gets sent back to the remote terminal the jobs came from, unless the user or operator re-routes it โœจ. The remote terminal can also have a console typewriter, which the remote operator uses to receive and send messages and to control their terminal [2] ๐Ÿ’ฌ.

When RJS is used over the ARPA Network, the "remote terminal" is expected to be a multiprogrammed user process in a remote Host ๐Ÿง . We'll use the RJS term "remote site" for that user process, which presumably pretends to be unit record devices using file I/O ๐ŸŽญ. Several users at the same remote Host can use NETRJS at the same time, each acting as an independent "remote site" ๐Ÿ‘ฏโ€โ™€๏ธ. They're told apart by 8-character names called terminal-ids, because each remote site looks to RJS like a separate physical terminal ๐Ÿ’–. Valid terminal-ids get assigned to individual users or user groups at remote Hosts who want to use NETRJS ๐Ÿซถ.

Under NETRJS, each remote site opens a separate ARPA network connection to CCN for each simulated unit record device ๐Ÿ”Œ. Each one of these connections is called a channel, and it's labelled input or output from CCN's point of view ๐Ÿ”. A standard remote site in NETRJS has these five channels (See Figure 1) ๐ŸŒˆ:

  1. Operator Input Channel - Commands and messages entered by remote "operator" console.
  2. Operator Output Channel - Message stream which would normally be directed to remote operator.
  3. Input Stream - One simulated Hollerith card reader for job submission.
  4. Printer Stream - One simulated line printer to record printed output (system messages and SYSOUT data sets) from jobs.
  5. Punch Stream - One simulated card punch, capable of recording arbitrary (i.e., transparent) binary text.

RJS actually supports more than one reader, printer, and punch at each remote terminal ๐Ÿคฏ. That means the NETRJS protocol could easily be expanded to allow multiple simultaneous I/O streams for each Network user ๐Ÿ“ˆ. Right now it doesn't seem that useful, though, because the ARPA Network bandwidth will normally be the thing limiting the transmission speed under NETRJS ๐Ÿข.

Under NETRJS, the text of a single network message is called a block ๐Ÿ“ฆ. A block is variable length, up to 900 bytes. The exception is operator input and output blocks, which may not go over 130 bytes ๐Ÿ™…โ€โ™€๏ธ. In this document, byte means the set of 8 bits representing one character ๐Ÿ”ข. Each byte has to be aligned on an 8-bit boundary within the message (and block) ๐Ÿ“. So we can think of a block as a string of bytes ๐Ÿงต. The detailed format of a block gets defined in Sections E, F, and G, using basically the formalism Bobrow and Sutherland suggested in RFC #31 ๐Ÿค“.

Since the central site Host (CCN) is an IBM 360, NETRJS uses the IBM EBCDIC character code ๐Ÿ–ฅ๏ธ. That avoids redundant code conversion at both hosts when the remote host also uses EBCDIC internally ๐Ÿ™Œ. The message formats don't assume any particular code, though. In fact, "object decks" sent to the (simulated) card punch will normally contain arbitrary binary text ๐Ÿงฉ.

To get the most out of the available Network bandwidth, we strongly recommend sending input blocks as large as possible ๐Ÿš€. CCN will always fully block NETRJS output ๐Ÿ’ฏ. Also, to avoid excessive overhead, we urge all NETRJS users to make their marking a multiple of 8 bits, so that the messages received at CCN arrive on a byte boundary ๐ŸŽฏ.


B. Starting a Session[3] ๐Ÿฆ‹

The initial connection protocol for NETRJS is basically Crocker's from RFC #66 (as restated by Harslem and Heafner in RFC #80), with some extensions ๐Ÿช„. Here's the vibe: user U at a remote Host presumably asks their outgoing logger to make a NETRJS connection to CCN ๐Ÿ™‹โ€โ™€๏ธ. That logger starts by sending an initial RFC to connect socket (user,aen) = (U,s) to CCN socket (0,5) ๐Ÿ“จ. User 0 at CCN is the incoming logger, and aen = 5 means NETRJS ๐ŸŽ€.

The CCN incoming logger allocates a set of (six) consecutive aen numbers A, A+1,......A+5 for user U ๐Ÿง. It then returns a message containing the socket number (U,A), as specified in RFC #66, and closes the initial connection ๐Ÿ”’. After that, the remote and central sites open an input channel between CCN socket (U,A) (socket f in Figure 1) and remote socket (U, s+1) โœจ. This is the remote operator input channel ๐ŸŽฎ. The other devices get fixed aen's at CCN, assigned relative to A. Here they are:

                             CCN Socket
     Channel                 (User,aen)

     Operator Input          (U,A)
     Operator Output         (U,A+1)
     Card Reader (No. 1)     (U,A+2)
     Printer (No. 1)         (U,A+3)
     Punch (No. 1)           (U,A+5)

Once the operator input channel is open, the remote site has to send a valid RJS signon message [2] ๐Ÿชช. This message is free-format and consists of the command verb SIGNON followed by the user's terminal-id ๐Ÿ’Œ. If RJS doesn't recognize the terminal-id, or has no available Line Handler for the Network, it refuses by closing the operator input channel ๐Ÿ™…โ€โ™€๏ธ. Central site issues subsequent RFC's for the other channels listed above only in response to corresponding RFC's from the remote site ๐Ÿ”.

To end the session, the remote site may close the console input channel (socket "a" in figure 1) ๐Ÿ‘‹. Or the user can enter a SIGNOFF command through the operator input channel. In that case, RJS waits until the current job output streams are complete, and then it ends the session ๐Ÿงน. RJS ends the session by closing the console output channel (socket g) ๐ŸŒ™. If RJS abends, socket g closes too ๐Ÿ’€. If either site ends the session, all other connections for this remote site should be closed ๐Ÿ”. Also, a user can submit a number of jobs, sign off, and then get their output when they sign on again later ๐Ÿ“.


C. Channel Control ๐Ÿ’…

Flow control in NETRJS is handled by the Network protocol ALL mechanism ๐Ÿšฆ. Before a stream of records can start on a particular channel, the remote site has to send an RFC, and Central has to reply ๐Ÿค. This lets the central site figure out the remote configuration dynamically ๐Ÿง . A particular card reader, printer, or punch channel is only open while it's active, so the receiver doesn't have to tie up buffer space for nothing ๐Ÿซง. Each of these channels, when open, assumes a buffer allocation of at least 900 bytes at the receiver ๐Ÿ“ฆ.

The operator input and output channels, on the other hand, stay open the whole session ๐Ÿ”“. On these channels, the receiver has to provide an allocation of at least 130 bytes ๐ŸŽ€.

After sending the SIGNON command over the operator input channel, the remote site should send RFC's for all output channels that are ready to receive data ๐Ÿ“ฌ. When output is available for that site, Central returns an RFC and starts transmitting ๐Ÿšš. Central closes an output channel (socket i and j) at the end of the output for each complete batch job [4] โœ…. Then the remote site has to send a new RFC, and Central has to reply with an RFC to start output for another job to that device ๐Ÿ”„. This gives the remote site a chance to allocate a new file for each job without breaking the output within a job ๐Ÿ“. If the user at the remote site wants to cancel (or backspace or defer) the output of a particular job, they enter the appropriate RJS commands [2] on the operator input channel ๐Ÿ™‹โ€โ™€๏ธ.

When the remote site is ready to submit a job (or a stack of consecutive jobs), it issues an RFC for the card reader input channel ๐Ÿƒ. The remote site is not required to close the channel (socket c) after each job in a "stack" of jobs. But they must close it after the last job in the stack to start its processing ๐Ÿ.

Sometimes the receiver site needs to abort a particular channel, maybe because of a transmission error (see Section D below on checking) or a disk I/O error ๐Ÿ’ฅ. The receiver can abort a channel (other than console output) by closing it (sockets d, e, f, and h) ๐Ÿšช. This action tells the transmitter to re-transmit the information after the channel is reopened (initiated by the remote site, as always) ๐Ÿ”. The transmitter, on the other hand, aborts a channel by sending a block with a particular bit combination (e = 2 in BCBYTE; see Section E) ๐ŸŽฏ.

If either site aborts the card reader (input) channel, RJS discards the text of the last partially-spooled job. The remote site should re-transmit this job ๐Ÿ”. Note that repeating an entire stack puts duplicate jobs into the system. But the second copy of a job will "flush" because of its duplicate job name ๐Ÿซ .

If a printer or punch (output) channel is aborted, Central re-transmits from the beginning of the current SYSOUT data set. The effect is the same as a RESTART command [2] ๐Ÿช„. If the operator input channel is aborted, the remote site must re-transmit the last block ๐Ÿ“จ. Finally, the operator output channel has no abort condition defined ๐Ÿ™…โ€โ™€๏ธ. Central never sends a Channel Abort message on this channel. If the remote site closes its socket (socket b), Central won't re-transmit. It just stops sending messages until the channel is reopened ๐Ÿคซ. So a remote site can operate without an operator output channel, but we do not recommend this, because the user will then miss operator advisory messages, such as a warning of an impending IPL ๐Ÿ˜ญ๐Ÿ’œ.

D. Checking โœจ

okay bestie, so remote job entry is SO sensitive ๐Ÿ˜ญ an undetected error rate has to stay super low, no cap ๐Ÿ’…. The IMPs use CRCs and sequence numbers over the communication lines, so the IMP-IMP error rate should be negligible ๐Ÿซถ. There's no checking on the IMP-Host interface, but it seems likely those interfaces will either be reliable or fail catastrophically ๐Ÿ’€. Random drop-outs or other weird failures seem unlikely, so the only checks provided are these simple ones:

  1. Every block will (at least initially) carry a fixed bit check pattern that uses both the on and off states of each bit path in the 16 bit PDA interface at CCN.

It's giving checkout energy ๐Ÿ” this crude check on IMP-Host transmission is expected to be useful during the initial hardware and software checkout, and later too if the interface gets marginal ๐ŸŒธ. However, either site can skip the check pattern by setting a bit in the Block Control Byte (BCBYTE), see Section F.

  1. Each block contains a sequence number ๐Ÿฆ‹. This is also meant for initial checkout, and to signal catastrophic hardware or software problems. If the receiver spots an incorrect check pattern or block sequence number, the receiver aborts the channel by closing the corresponding network connection. The remote site then issues an RFC to re-establish the network connection. The sequence number of the first block after an RFC is 0. The numbers are never reset while the connection is open ๐Ÿ”ฅ.

E. Block Format

Okay this section is the blueprint for how a block is built, and it's honestly so pretty ๐ŸŽ€ Here's the overall shape:

      BLOCK <---- BLOCKHEAD + (RECORD = r) + ENDOFBLOCK

                  Here r > 0
                         =
   BLOCKHEAD <--  BCBYTE + [e=0=>CHECK] + DEVBYTE

                  The Blockhead field consists of a Block Control Byte,
                  a 32-bit check field CHECK, and a Device Byte.

   BCBYTE <----   '1'BIT + e:ERRORCONTROL + b:BLKSEQ

                  Here BLKSEQ contains a 5-bit modulo 32 block sequence
                  number b.  ERRORCONTROL is a 2 bit field with the
                  following meanings:

                  e=0 :  Normal block.  Contains a (presumably valid)
                         check field CHECK.

                  e=1 :  Block contains no check field CHECK.

                  e=2 :  Abort channel, initiated by transmitter.
                         Channels is not closed, transmission restarts
                         on job-related boundary.

   DEVBYTE <----  '1'BIT + n:DEVNO + t:DEVTYPE

                  This byte identifies a particular remote device, i.e.,
                  it identifies a stream.  DEVTYPE specifies the type of
                  device, as follows:

                  t=1:  Output to remote operator console.
                    2:  Input from remote operator console.
                    3:  Input from card reader.
                    4:  Output to printer.
                    5:  Output to card punch.
                  6,7:  Unused.

                  DEVNO is a 3-bit integer which identifies the
                  particular device type of type t at this remote site.

   CHECK <---     '10101111'BYTE + 01010000'BYTE + '11111010'BYTE +
                                                   '00000101'BYTE
   ENDOFBLOCK<----'0'BYTE

So the Blockhead is the sassy trio: a Block Control Byte, a 32-bit check field CHECK, and a Device Byte ๐Ÿ’…. The BCBYTE carries a leading '1' bit, the ERRORCONTROL field, and a 5-bit modulo 32 block sequence number b (that's BLKSEQ) ๐Ÿงš.

ERRORCONTROL is a 2 bit field, and it can mean three things:

  • e=0 : Normal block. Contains a (presumably valid) check field CHECK.
  • e=1 : Block contains no check field CHECK.
  • e=2 : Abort channel, initiated by transmitter. The channel is not closed, and transmission restarts on a job-related boundary.

The DEVBYTE identifies a particular remote device, which means it identifies a stream ๐ŸŒˆ. DEVTYPE tells you what kind of device it is:

   t=1:  Output to remote operator console.
     2:  Input from remote operator console.
     3:  Input from card reader.
     4:  Output to printer.
     5:  Output to card punch.
   6,7:  Unused.

DEVNO is a 3-bit integer that picks out the particular device of type t at this remote site ๐Ÿ“.

Last but definitely not least, the CHECK value is the fixed pattern '10101111'BYTE + 01010000'BYTE + '11111010'BYTE + '00000101'BYTE, and every block ends with ENDOFBLOCK, which is a '0'BYTE ๐Ÿ™ˆ.

Record Format

Records are the stuff inside the block, and there are two flavours: a data record or a jobname record ๐Ÿฆ‹.

      RECORD <------ DATA RECORD | JOBNAMERECORD

The very first record sent on a printer or punch output channel is always a JOBNAMERECORD. It tells you the OS/360 jobname of the job that made the output that follows ๐Ÿ‘‘.

   DATARECORD <---   '10'BIT2 + DEVCNTRL + (STRING=p) + ENDOFRECORD

   JOBNAMERECORD <-- '11000000'BYTE + '11001000'BYTE + JOBNAME +
                     ENDOFRECORD

   JOBNAME <----     (TEXTBYTE = 8)

                     This is the 8-character OS/360 jobname for the
                     following job.

DEVCNTRL handles carriage control for a printer. If the device isn't a printer, DEVCNTRL should be '000000'. For printers, here's the vibe:

   DEVCNTRL <-----    d:BIT2 + k:BIT4

                     DEVCNTRL specifies carriage control for a printer,
                     so if the device is not a printer then DEVCNTRL
                     should be '000000'.  For a printer:

                     d=0     : Space k lines after printing; 0 < k < 3
                                                               =   =
                               is allowed

                     d=2     : Immediately space k lines.

                     d=1, k=1: Skip to top of new page after printing.

                     d=3, k=1: Immediately skip to top of new page.

And the STRING options are where the compression magic happens โœจ:

   STRING <---         ('100' + i:DUPCOUNT)| This is a string of i
                     consecutive blanks.

                     ('101' + i:DUPCOUNT + TEXTBYTE)|

                     This is a string of i consecutive duplicates of
                     TEXTBYTE.

                     ('11' + j:LENGTH + (TEXTBYTE=j)| This is an
                     uncompressed string of j characters.

   ENDOFRECORD <----   '0'BYTE

G. Field Definitions

Here's the cheat sheet for every field name ๐Ÿ“‹:

   Name*           Meaning                 Length (bits)
   _____           _______                 _____________

   BIT             1-bit field                  1

   BIT2            2-bit field                  2

   BIT4            4-bit field                  4

   BLKSEQ          Block sequence number        5

   BYTE            8-bit field aligned on 8-bit 8
                   boundary

   CHECK           Block check number          32

   DEVNO           Device number of a given     3
                   type

   DEVTYPE         Device type                  4

   DUPCOUNT        Number of replications of    5
                   duplicated character in
                   compressed text.

   ERRORCONTROL    Block transmission error     2
                   control.

   LENGTH          Length in bytes of the       6
                   following string of text.

   TEXTBYTE        An 8-bit byte of text        8

Note: all non-terminal fields whose names end in "...BYTE" represent bytes in both length and alignment ๐ŸŒธ.

H. NOTES AND REFERENCES

  1. Martin, V.A. and Springer, T.W., "Implementation of A Remote Job Service", Technical Report TR2, Campus Computing Network, UCLA, Los Angeles, (undated).
  2. The RJS operator commands and messages are described in detail in Reference 1.
  3. We say "starting a session" instead of "logging on" because RJS has its own log on procedure, which is, we suppose, a fourth-level protocol ๐Ÿงšโ€โ™€๏ธ.
  4. Note that NETRJS uses closing of connections as end-of-file signals ๐Ÿ’œ.
           REMOTE SITE             CENTRAL SITE (CCN)
      +---------------------+    +--------------------+
      |                 a   |    |                    |
      | Console Input  o----------->o f               |
      |                 b   |    |                    |
      | Console Output o<-----------o g               |
      |                 c   |    |                    |
      | Card Reader    o------------o h               |
      |                 d   |    |                    |
      | Printer        o<-----------o i               |
      |                 e   |    |                    |
      | Card Punch     o<-----------o j               |
      |                     |    |                    |
      +---------------------+    +--------------------+

                           FIGURE 1
                ARPA Network Connections (Channels)
              For a Standard Remote Site Under NETRJS

R.T. Braden/rb. S.M. Wolfe

[This RFC was put into machine readable form for entry] [into the online RFC archives by Lorrie Shiota, 10/01]

๐Ÿ“ฆ where this page comes from