DIRECTORY Arpa USING [Address], ArpaBuf USING [maxBodyBytes], ArpaIP USING [Buffers, Handle], ArpaTCP USING [DByte, Port, Reason, TCPInfo], BasicTime USING [GetClockPulses, Pulses], PrincOps USING [zEXCH]; ArpaTCPOps: CEDAR DEFINITIONS IMPORTS BasicTime ~ BEGIN sendBufferLength: INT ~ 4000; -- 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 ~ ArpaBuf.maxBodyBytes - tcpHdrByteLength; sillyWindowLimit: INT ~ 40; -- try not to send when window is smaller than this ourLocalAddress: Arpa.Address; tcpIPHandle: ArpaIP.Handle; defaultReceiveWindow: INT; repacketizing: BOOL; -- TRUE if data to be repacketized when retransmitted 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 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 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 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..sendBufferLength) _ 0, -- for repacketizing sendSlot: INT [0..sendBufferLength) _ 0, -- for repacketizing sendBuffer: ARRAY INT [0..sendBufferLength) OF BYTE, -- for repacketizing nBytesToSend: INT [0..sendBufferLength] _ 0, -- number of filled slots in sendBuffer 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 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 rtt: INT, rexmits: INT _ 0, duplicates: INT _ 0 ]; defaultProbeTimeout: INT; -- time (ms) to wait on zero window before sending a probe defaultRTT: INT; -- initial round-trip time minRTT, maxRTT: INT; defaultInitialTimeout: INT; -- how long to retransmit SYN before declaring connection dead tcpSegmentLife: INT; -- value for time to live beta: INT; -- retransmission timeout = beta * rtt rexmitLimit: INT; -- max time rexmitting before closing connection, in rtt's RexmitIntervalFromHandle: PROC [h: TCPHandle] RETURNS [INT] ~ INLINE { RETURN[beta*h.rtt] }; RexmitTimeoutFromHandle: PROC [h: TCPHandle] RETURNS [INT] ~ INLINE { RETURN[rexmitLimit*h.rtt] }; InitialTimeoutFromHandle: PROC [h: TCPHandle] RETURNS [INT] ~ INLINE { RETURN[defaultInitialTimeout] }; ProbeTimeoutFromHandle: PROC [h: TCPHandle] RETURNS [INT] ~ INLINE { RETURN[defaultProbeTimeout] }; TimeWaitTimeoutFromHandle: PROC [h: TCPHandle] RETURNS [INT] ~ INLINE { RETURN[tcpSegmentLife*1000*2] }; -- tcpSegmentLife is in seconds; SetTimeout takes milliseconds; *2 is for round-trip 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 TCPSendBuffer: TYPE ~ RECORD [ dataByteCount: INT, -- count of data sent (not control) xmitTime: BasicTime.Pulses, -- when first sent, or 0 if resent rexmitTime: BasicTime.Pulses, -- time for next retransmission 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]; pktsSent: INT; pktsRcvd: INT; pktsRexmitted: INT; pktsDuplicate: INT; pktsWithNoConnection: INT; pktsFromFuture: INT; pktsFromPast: INT; pktsWithBadChecksum: INT; Open: PROC [tcpInfo: ArpaTCP.TCPInfo] RETURNS [handle: TCPHandle]; Close: PROC [handle: TCPHandle]; Abort: PROC [handle: TCPHandle]; GetDataTimeout: PROC [handle: TCPHandle] RETURNS [timeout: INT]; SetDataTimeout: PROC [handle: TCPHandle, timeout: INT]; WaitForListenerOpen: PROC [handle: TCPHandle, timeout: INT]; SendCurrentDatagram: PROC [handle: TCPHandle, push: BOOL]; GetNextDatagram: PROC [handle: TCPHandle]; SetUrgent: PROC [handle: TCPHandle]; WaitForUrgentData: PROC [handle: TCPHandle] RETURNS [urgentIndex: INT]; Flip: PROC [Pair] RETURNS [INT] = TRUSTED MACHINE CODE BEGIN PrincOps.zEXCH; END; Flop: PROC [INT] RETURNS [Pair] = TRUSTED MACHINE CODE BEGIN PrincOps.zEXCH; END; TCPChecksum: PROC [data: ArpaIP.Buffers] RETURNS [checksum: ArpaTCP.DByte]; ChecksumsMatch: PROC [c1, c2: ArpaTCP.DByte] RETURNS [BOOL]; SetTimeout: PROC [delta: INT, base: BasicTime.Pulses _ BasicTime.GetClockPulses[]] RETURNS [BasicTime.Pulses]; TimedOut: PROC [timeoutTime: BasicTime.Pulses] RETURNS [BOOL]; END. –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 Demers, September 7, 1988 1:54:50 pm PDT Doug Terry, March 22, 1988 6:37:27 pm PST Hal Murray July 16, 1985 4:39:19 pm PDT John Larson, April 14, 1986 11:18:30 pm PST Constants and types The layout of the TCP header in a datagram. One gets a TCPHeaderP by saying LOOPHOLE[@datagram.data]. The information about a TCP connection. Send state: Receive state: Random: Rount Trip Time estimate: Statistics: Timeouts These describe packets that have been received from the net. And these describe packets that have been sent once, but may need to be retransmitted. Statistics Routines used by TCPMain Attempts to open a new TCP connection. Returns a TCPHandle to use or raises ArpaTCP.Error. Shut down the connection normally. Shut down the connection abnormally. Get the timeout associated with handle. Reset the timeout associated with handle. Wait until the listening connection on this socket is open. The current datagram in the handle is ready to send. Push is true if the TCP push option should be used. Empty datagrams are ignored unless push is true. We are through with the current input datagram and would like another. Only returns when new datagram has usable data. The urgent pointer is set to the current position in the output stream. Wait asynchronously for urgent data indication. Routines internal to the TCP stuff The following two procedures swap the halves of a long int for the encapsulation. Stolen from the pup software. Find the checksum to be used in the TCP header. Call when data.dataLength is the correct length of the packet. True if c1 and c2 are the same checksum, i.e. they are equal or are both one's complement representations of zero. Returns a timeout time computed by adding delta milliseconds to the specified base time. If delta is negative, meaning "never time out", returns zero, which is specifically defined (in TimedOut) to mean "never time out" and is never otherwise returned. Returns true if the specified time has been reached. Ê 7– "cedar" style˜head™Icode2šœ¯™¯Icodešœ2™2Jšœ-™-Jšœ3™3M™(M™)Jšœ'™'M™+šÏk ˜ Lšœœ ˜Lšœœ˜Lšœœ˜Lšœœ ˜-Lšœ œ˜)Lšœ œ ˜——šÏn œœ ˜Lšœ ˜Lšœ˜—™Lšœœ ÏcP˜nLšœœ ˜Lšœœ˜Lšœœ˜+Lšœœ+˜@LšœœŸ3˜PLšœ˜Lšœ˜Lšœœ˜LšœœŸ5˜JLšœœ˜Lšœœo˜„Lš œœœ œœœŸ˜MIbodyšœMœ™fLš œ œœœœ ˜.š œ œœ œœ˜,LšœŸ˜4LšœŸ˜7LšœŸ˜(LšœŸ˜/Lšœœ Ÿ"˜ILšœœ ˜"LšœœœŸ˜8LšœœœŸ˜2LšœœœŸ˜'LšœœœŸ ˜(LšœœœŸ$˜CLšœœœŸ#˜BLšœŸ˜8LšœŸ ˜=Lšœ"Ÿ%˜GLš œœœ œœŸ ˜5—N™'Lšœ œœ˜#šœœ œœ˜'LšœŸ ˜%LšœŸ˜7LšœŸ ˜'LšœœŸ˜4LšœœŸ˜4LšœŸ˜/LšœŸ ˜8LšœœŸ˜'Lšœ œŸ-˜FLšœœŸ&˜;™ LšœœŸ˜.LšœœŸ˜,LšœœŸ˜ LšœœŸ'˜8LšœœŸ'˜8LšœœŸ˜)Lšœ œœŸ%˜>LšœœŸ˜,Lšœ œŸ˜>Lšœ œŸ˜>Lš œ œœœœŸ˜JLšœœŸ'˜T—™LšœœŸ˜/LšœœŸ˜LšœœŸ˜*Lšœ œœŸ*˜ELšœœŸ#˜1Lšœ œœŸ*˜D—™Lšœ œŸ˜5Lšœ œŸ2˜DLšœ Ÿ,˜LLš œœœœœŸ5˜TLš œœœœœŸ@˜cLšœœŸ˜DLšœ œŸ˜8Lš œ œœœœŸ+˜HLš œ œœœœŸ0˜NLšœ'Ÿ˜DLšœœŸ,˜CLšœœŸ/˜HLšœ œŸ#˜?Lšœ œŸ˜8—™Lšœ˜ —™ Mšœ œ˜Mšœ œ˜Lšœ˜—™LšœœŸ:˜ULšœ œŸ˜+Lšœœ˜LšœœŸ>˜ZLšœœŸ˜.LšœœŸ&˜1Lšœ œŸ:˜LL˜šžœœœœ˜;Lšœœœ˜ L˜—šžœœœœ˜:Lšœœœ˜'L˜—šžœœœœ˜;Lšœœœ˜+L˜—šžœœœœ˜9Lšœœœ˜)L˜—šžœœœœ˜LšœŸ ˜>LšœŸ1˜PLšœŸ˜3—šœœœ˜Lšœœœ˜,——™ Lšœ œ˜Lšœ œ˜Lšœœ˜Lšœœ˜Lšœœ˜Lšœœ˜Lšœœ˜Lšœœ˜J˜—™šžœœœ˜BLšœ[™[—šžœœ˜ L™"—šžœœ˜ L™$—šžœœœ œ˜@L™'—šžœœœ˜7L™)—šžœœœ˜L™4—Lšœ˜——…—®0{