ArpaTCPOps.mesa
Copyright (C) 1983, 1985 by Xerox Corporation. All rights reserved. The following program was created in 1983 but has not been published within the meaning of the copyright law, is furnished under license, and may not be used, copied and/or disclosed except in accordance with the terms of said license.
Last Edited by: Nichols, September 1, 1983 4:27 pm
Last Edited by: Taft, January 3, 1984 9:45 am
Last Edited by: HGM, March 23, 1984 10:01:40 am PST
Doug Terry, November 20, 1987 11:43:19 am PST
Hal Murray July 16, 1985 4:39:19 pm PDT
John Larson, April 14, 1986 11:18:30 pm PST
DIRECTORY
Arpa USING [Address],
ArpaBuf USING [maxBodyBytes],
ArpaIP USING [Buffers, Handle],
ArpaTCP USING [DByte, Port, Reason, TCPInfo],
BasicTime USING [GetClockPulses, Pulses],
PrincOps USING [zEXCH];
Constants and types
maxSendBufferLength: INT ~ 4000; -- max bytes of unacked data to queue for transmission or retransmission to net
sendBufferLength: INT; -- max bytes of unacked data to queue for transmission or retransmission to net
recvBufferLength: INT ~ 4000;
tcpHdrWordLength: INT ~ 5;
tcpHdrByteLength: INT ~ tcpHdrWordLength*4;
maxTCPDataLength: INT; -- TCP Maximum Segment Size
sillyWindowLimit: INT ~ 40; -- try not to send when window is smaller than this
probeTimeout: INT; -- time (ms) to wait on zero window before sending a probe
defaultProbeTimeout: INT ~ 120000; -- 2 min. suggested by RFC793
ourLocalAddress: Arpa.Address;
tcpIPHandle: ArpaIP.Handle;
defaultReceiveWindow: INT;
repacketizing: BOOL; -- TRUE if data to be repacketized when retransmitted
tcpSegmentLife: INT ~ 60; -- value for time to live
Buffer: TYPE = ArpaIP.Buffers;
ConnectionState: TYPE = {closed, listen, synSent, synRcvd, established, finWait1, finWait2, closeWait, closing, lastAck, timeWait};
Pair: TYPE = MACHINE DEPENDENT RECORD [a, b: CARDINAL]; -- used for word swap
The layout of the TCP header in a datagram. One gets a TCPHeaderP by saying LOOPHOLE[@datagram.data].
TCPHeaderP: TYPE = LONG POINTER TO TCPHeader;
TCPHeader:
TYPE =
MACHINE
DEPENDENT
RECORD [
sourcePort (0): ArpaTCP.Port, -- source port number
dstnPort (1): ArpaTCP.Port, -- destination port number
seqNumber (2): Pair, -- sequence number
ackNumber (4): Pair, -- acknowledgement number
dataWordOffset (6: 0..3): INT [0..15], -- size of header in 32-bit words
unused (6: 4..9): INT [0..63] ← 0,
urg (6: 10..10): BOOL ← FALSE, -- control flags, urgent
ack (6: 11..11): BOOL ← FALSE, -- acknowledgement
psh (6: 12..12): BOOL ← FALSE, -- push
rst (6: 13..13): BOOL ← FALSE, -- reset
syn (6: 14..14): BOOL ← FALSE, -- syn (first packet on connection)
fin (6: 15..15): BOOL ← FALSE, -- fin (last packet on connection)
window (7): ArpaTCP.DByte, -- window of packets to send
checksum (8): ArpaTCP.DByte, -- for header and pseudo header
urgentPtr (9): ArpaTCP.DByte ← 0, -- ptr to byte following urgent data
options (10): ARRAY INT [1..40] OF BYTE]; -- options
The information about a TCP connection.
TCPHandle: TYPE ~ REF TCPHandleRec;
TCPHandleRec:
TYPE ~
MONITORED
RECORD [
localPort: ArpaTCP.Port, -- TCP port
foreignAddr: Arpa.Address, -- internet foreign address
foreignPort: ArpaTCP.Port, -- TCP port
matchForeignAddr: BOOL, -- true to use foreign addr
matchForeignPort: BOOL, -- true to use foreign port
state: ConnectionState, -- state of connection
reason: ArpaTCP.Reason, -- why we closed this connection
active: BOOL, -- active or passive open
notListening: CONDITION, -- used to wait for connection when listening
maxSegmentSize: INT, -- max bytes we can send in a datagram
Send state:
sndUna: INT ← 0, -- oldest unacked seq number
sndNxt: INT ← 0, -- next seq number to send
sndWnd: INT ← 0, -- send window
sndWL1: INT ← 0, -- pkt seq used for last window update
sndWL2: INT ← 0, -- pkt ack used for last window update
iss: INT ← 0, -- initial send seq number
sndUrgent: BOOL ← FALSE, -- true if trying to send urgent data
sndUp: INT ← 0, -- where it is in the stream
fillSlot: INT [0..maxSendBufferLength) ← 0, -- for repacketizing
sendSlot: INT [0..maxSendBufferLength) ← 0, -- for repacketizing
sendBuffer: ARRAY INT [0..maxSendBufferLength) OF BYTE, -- for repacketizing
nBytesToSend: INT [0..maxSendBufferLength] ← 0, -- number of filled slots in sendBuffer
Receive state:
rcvNxt: INT ← 0, -- next seq number to receive
rcvWnd: INT, -- receive window
rcvUp: INT ← 0, -- receive urgent pointer
zeroRcvWnd: BOOL ← FALSE, -- last advertised receive window was zero
irs: INT ← 0, -- initial receive sequence number
urgentMode: BOOL ← FALSE, -- rcvd urgent data and not passed to user
Random:
finSequence: INT ← 0, -- sequence number of fin sent
dataTimeout: INT, -- in msecs, time to wait before signalling client
timeWaitTime: BasicTime.Pulses, -- when to delete a handle in timeWait state
fromNetQueue: LIST OF REF ANY, -- packets received from net (actually TCPRcvBuffers)
readyToReadQueue: LIST OF REF ANY, -- packets processed and ready to hand to client (TCPRcvBuffers)
currentInputBuffer: REF TCPRcvBuffer, -- buffer for doling out input
dataAvailable: CONDITION, -- wait here for incoming data
toNetQueue: LIST OF REF ANY, -- packets to send to net (ArpaIP.Bufferss)
rexmitQueue: LIST OF REF ANY, -- packets to retransmit to net (TCPSendBuffers)
currentOutputDatagram: ArpaIP.Buffers, -- next block of data to send
currentOutputPtr: INT, -- index into currentOutputDatagram for data
currentOutputLimit: INT, -- max size of datagram based on maxSegmentSize
windowAvailable: CONDITION, -- wait here for quota on other end
urgentAvailable: CONDITION]; -- wait here for urgent data
These describe packets that have been received from the net.
TCPRcvBuffer:
TYPE ~
RECORD [
offsetSeqNo: INT, -- for use by TCP
datagramPtr: ArpaIP.Buffers, -- datagram received from net
dataOffset: INT, -- Byte offset of data from dataPtr^
dataByteCount: INT, -- number of data bytes
tcpHdrPtr: TCPHeaderP, -- pointer to TCP header (?)
urg: BOOL, -- value of TCP URG field
endUrgentData: INT]; -- index of byte following urgent data
And these describe packets that have been sent once, but may need to be retransmitted.
TCPSendBuffer:
TYPE ~
RECORD [
dataByteCount: INT, -- count of data sent (not control)
rexmitTime: BasicTime.Pulses, -- time to retransmit segment
timeoutTime: BasicTime.Pulses, -- time to abort connection if segment not acked
datagram: ArpaIP.Buffers]; -- datagram sent to net
TCPControlSet:
TYPE ~
RECORD [
urg, ack, psh, rst, syn, fin: BOOL ← FALSE];