RFC 1008
Implementation guide for the ISO Transport Protocol
RFC 1008: Implementation Guide for the ISO Transport Protocol ๐
Network Working Group ๐ธ Author: Wayne McCoy ๐ Date: June 1987 โจ Request for Comments: 1008
Okay bestie, the header tells us who wrote it (Wayne McCoy), when (June 1987), and the RFC number (1008). It doesn't list a category, an "obsoletes" line, or an "updates" line, so I'm not going to invent any ๐ The Status section below says it's being shared with the Internet community to get comments on the Implementors Guide. ๐ฆ
Status of this Memo ๐
This RFC is being distributed to members of the Internet community in order to solicit comments on the Implementors Guide. While this document may not be directly relevant to the research problems of the Internet, it may be of some interest to a number of researchers and implementors. Distribution of this memo is unlimited. ๐ซถ
IMPLEMENTATION GUIDE FOR THE ISO TRANSPORT PROTOCOL ๐ง
1. Interpretation of formal description. โจ
It's assumed that you already know two things: the formal description technique Estelle [ISO85a], and the transport protocol as written up in IS 8073 [ISO84a] and N3756 [ISO85b]. No cap, this guide is for people who already know their stuff ๐
1.1. General interpretation guide. ๐
The formal description of the ISO Transport Protocol was built around three assumptions. Let's go! ๐ฅ
1. A generality principle
The formal description is meant to express all of the behavior that any implementation is supposed to show, but it doesn't force any one implementation to do things the way it would in its own operating context. Giving every implementation room to breathe, iconic ๐ซถ
2. Preservation of the deliberate nondeterminism of IS 8073
The text of IS 8073 deliberately includes nondeterminism and indeterminism in how the transport protocol behaves, so that it stays flexible for different applications. ๐ฆ (Quick vocab check: nondeterminism means the order in which a set of possible actions gets carried out isn't specified. Indeterminism means you can't predict whether a particular action will happen based on the system's state or on other actions.)
3. Discipline in the usage of Estelle
A feature of Estelle should only be used when the nature of the mechanism being described strongly calls for it, or when it's needed to honor the generality principle, or to keep the nondeterminism of IS 8073. ๐
Efficiency wasn't the main goal, and nobody tried to map Estelle mechanisms and features directly onto implementation mechanisms and features. So the description doesn't show optimal behavior for the protocol being implemented ๐
These assumptions mean the formal description sits at a higher level of abstraction than you'd expect from a description written for one particular operating environment. That abstraction is essential, because networks and network elements are so diverse, and implementation and design decisions get shaped by all of that. Even when two operating environments are basically identical, designers still need freedom and originality in solving a technical problem. The same behavior can be written in lots of different ways, and the goal of the transport formal description was to capture that equivalence. Some transport mechanisms aren't fully described, or look overly complicated, because of the commitment to the generality principle. Sorting those out may take real effort from the implementor ๐ญ
Since the description doesn't show optimal behavior, implementors should keep those three assumptions in mind when they use the description to build the protocol. It may be a good idea to adapt the standard description so that:
- a. abstractions (such as modules, channels, spontaneous transitions and binding comments) get interpreted and realized as mechanisms that fit the operating environment and the service requirements;
- b. modules, transitions, functions and procedures that hold material irrelevant to the classes or options being supported get reduced or eliminated as needed; and
- c. the desired real-time behavior gets accounted for.
Using an Estelle feature in the formal description (for instance, "process") doesn't mean an implementation has to realize that feature with a matching feature in its operating context. So a module declared as a "process" in an Estelle description doesn't need to be a real process as a host operating system sees it. In Estelle, "process" refers to the synchronization properties of a set of procedures (transitions). โจ
How Estelle features get realized depends in a basic way on the performance and service the implementation is supposed to provide. Operational implementations have much stricter requirements for optimal behavior and robustness than implementations used for simulated operation (like correctness or conformance testing). So it's really important that an operational implementation realizes the abstract features and mechanisms of the formal description in an efficient and effective way. ๐
For operational use, there are two useful criteria for interpreting the formal mechanisms:
- [1] minimizing the delays the mechanism itself causes; for example:
- transit delay for a medium that realizes a channel
- access delay or latency for a channel medium
- scheduling delay for timed transitions (spontaneous transitions with a delay clause)
- execution scheduling for modules using exported variables (delay in accessing a variable)
- [2] minimizing the "handling" each invocation of the mechanism requires; for example:
- module execution scheduling and context switching
- synchronization or protocols for a realized channel
- predicate evaluation for spontaneous transitions
Spontaneous transitions represent nondeterminism and indeterminism, so using a uniform way of realizing them in an implementation should be questioned as a strategy. You can't specify the time at which the action described by a spontaneous transition will actually happen, for one or more of these reasons:
- a. it isn't known when, relative to any specific event defining the protocol (for example, input from the network, input from the user, or timer expirations), the conditions enabling the transition will actually occur;
- b. even if the enabling conditions are ultimately deterministic, it isn't practical to describe all the possible ways that could happen, given how differently implementations will check those conditions; and
- c. a particular implementation may not care about the enabling conditions, or may account for them in some other way. In other words, it's irrelevant when the action happens, if it happens at all.
For an example of a), think about splitting over the network connection in Class 4, where every network connection the transport connection was assigned to has disconnected, but the transport connection is still in the OPEN state. There's no way to predict when this will happen, and no specific event signals it. When it does happen, the transport protocol machine may want to try to get a new network connection. ๐ธ
For an example of b), timers can be written succinctly in Estelle with transitions like this one:
from A to B
provided predicate delay( timer_interval )
begin
(* action driven by timeout *)
end;
But some operations need the timer period to be very accurate (close to real time), while others can tolerate some delay in executing the action. The implementor has to figure out the optimal behavior wanted for each instance and use an appropriate mechanism to realize it, instead of using one uniform approach for every spontaneous transition. ๐ง
For an example of c), think about closing an unused network connection. If the network is set up so that keeping the connection open costs very little compared to opening it, an implementation might not want to think about closing it until, say, the weekend. ๐ Another implementation might decide to close the network connection within 30 msec after finding that the connection isn't busy. For yet another implementation, this could be meaningless because it runs over a connectionless network service. ๐
If a description has only a few spontaneous transitions, it may be fairly easy to implement them literally (that is, to schedule and execute them the way Estelle abstractly does) without taking on the overhead of checking all the variables that appear in the enabling conditions. But the number and complexity of the enabling conditions for spontaneous transitions in the transport description strongly suggest that an implementation which realizes spontaneous transitions literally will really suffer from that overhead. ๐ญ
1.2. Guide to the formal description. ๐
So implementors can get a feel for how to interpret the mechanisms and features of the formal description of transport, the following paragraphs explain what those mechanisms and features were meant to do, as the editors of the formal description intended. ๐ซถ
1.2.1. Transport Protocol Entity. ๐ฆ
1.2.1.1. Structure. ๐
The diagram below shows the general structure of the Transport Protocol Entity (TPE) module, as given in the formal description. From an abstract operational viewpoint, the transport protocol Machines (TPMs) and the Slaves operate as child processes of the TPE process. Each TPM represents the endpoint actions of the protocol on a single transport connection. The Slave represents control of data output to the network. The internal operations of the TPMs and the Slave are discussed below, in separate sections. ๐
This structure allows for describing multiple connections, multiplexing and splitting on network connections, dynamic existence of endpoints, and class negotiation. In the diagram, interaction points are shown with the symbol "O", while the (Estelle) channels joining those interaction points are shown as:
*
*
*
The symbol "X" stands for a logical association through variables. The following denotations:
<<<<<<<
>>>>>>>
V
V
V
show the passage of data, in the direction of the symbol vertices, by way of these associations. The acronyms TSAP and NSAP stand for Transport Service Access Point and Network Service Access Point, respectively. The structure of the TSAPs and NSAPs shown here is discussed further in Parts 1.2.2.1 and 1.2.2.2. โจ
To be continued... ๐ธ (Part 2 of 17 is coming, bestie. Stay tuned! ๐ )
|<-----------------TSAP---------------->|
----------O---------O---------O---------O---------O---------
| TPE * * * |
| * * * |
| ____O____ ____O____ ____O____ |
| | | | | | | |
| | TPM | | TPM | | TPM | |
| | | | | | | |
| |___X___| |__X_X__| |___X___| |
| V V V V |
| V multiplex V V V |
| >>>>>>>> <<<<<<<<<<< V V |
| V V split V V |
| V V V V |
| ---X---- ---X---- ---X---- |
| |Slave | |Slave | |Slave | |
| |__O___| |__O___| |__O___| |
| V V V |
| V V V |
|-----------------O------------O--------O------------------|
NSAP |<------>|
NSAP
okay so the structuring principles of Estelle give us a formal way to express and enforce certain synchronization properties between communicating processes ๐งโจ and bestie, it MUST be stressed that the scheduling implied by Estelle descriptions need not and in some cases should not be implemented ๐ the whole point of the structure in the transport formal description is to state formally the synchronization of access to variables shared by the transport entity and the transport connection endpoints, and to permit expression of dynamic objects within the entity ๐ outside of those things, it may be more efficient in some implementation environments to let the TPE and the TPMs run in parallel (the Estelle scheduling specifically excludes that parallel operation of the TPE and the TPMs) ๐ฆ this is especially true of internal management ("housekeeping") actions and anything not directly about communication between the TPE and the TPMs or instantiating TPMs ๐ญ typical actions of that latter sort are receipt of NSDUs from the network, integrity checking and decoding of TPDUs, and network connection management ๐ธ those could have been collected into other modules for scheduling closer to an implementation, but surely at the risk of further complicating the description ๐ so the formal description structure should be understood as expressing relationships among actions and objects, and NOT explicit implementation behavior ๐
1.2.1.2 Transport protocol entity operation.
okay so the details of the TPE's operation from a conceptual point of view are in the SYS section of the formal description ๐ but there are a few more comments about the design of the TPE that are giving main character energy ๐ the Estelle body for the TPE module has no state variable, which means any transition of the TPE may be enabled and executed at any time ๐ choice of transition is determined primarily by priority, so the semantics of TPE transitions is lowkey that of interrupt traps ๐ฅ
the TPE handles ONLY the T-CONNECT-request from the user, and the TPM handle all other user input ๐ซถ all network events are handled by the TPE, in addition to resource management to the extent defined in the description ๐ the TPE also manages all aspects of connection references, including reference freezing ๐ฆ the TPE does not explicitly manage the CPU resource for the TPMs, since that is implied by the Estelle scheduling across the module hierarchy โจ instantiation of TPMs is also the TPE's job, as is TPM release when the transport connection is to be closed ๐ once a TPM is created, the TPE does not in general interfere with the TPM's activities, with the following exceptions: the TPE may reduce credit to a Class 4 TPM without notice, and the TPE may dissociate a Class 4 TPM from a network connection when splitting is being used ๐ communication between the TPE and the TPMs goes through a set of exported variables owned by the TPMs, and through a channel which passes TPDUs to be transmitted to the remote peer ๐ธ this channel is not directly connected to any network connection, so each interaction on it carries a reference number indicating which network connection is to be used ๐ since the reference is only a reference, this permits usage of this mechanism when the network service is connectionless, as well โจ the mechanism gives flexibility for both splitting and multiplexing on network connections ๐ฅ
one major function the TPE performs for ALL its TPMs is initial processing of received TPDUs ๐ first, a set of integrity checks is made to determine whether each TPDU in an NSDU is decodable:
a. PDU length indicators and their sums are checked against the
NSDU length for consistency;
b. TPDU types versus minimum header lengths for the types are
checked, so that if the TPDU can be decoded, then proper
association to TPMs can be made without any problem;
c. TPDUs are searched for checksums and the local checksum is
computed for any checksum found; and
d. parameter codes in variable part of headers are checked where
applicable.
these integrity checks GUARANTEE that an NSDU passing the check can be separated as necessary into TPDUs, these TPDUs can be associated to the transport connections or to the Slave as appropriate, and they can be further decoded without error ๐ง
the TPE next decodes the fixed part of the TPDU headers to figure out the disposition of the TPDU ๐ the Slave gets TPDUs that cannot be assigned to a TPM (spurious TPDUs) ๐ญ new TPMs are created in response to CR TPDUs that correspond to a TSAP for this TPE ๐ฆ
all management of NSAPs is done by the TPE ๐ซถ this consists of keeping track of all network connections, their service quality characteristics and their availability, and informing the TPMs associated with those network connections ๐
the TPE has no timer module as such ๐ timing is handled by using the DELAY feature of Estelle, since this feature captures the essence of timing without specifying how the actual timing is to be achieved within the operating environment โฐ see Part 1.2.5 for more details ๐
1.2.2 Service Access Points.
okay so the service access points (SAP) of the transport entity are modeled using the Estelle channel/interaction point formalism ๐ (quick note: in Estelle, "channel" is a keyword that denotes a set of interactions which may be exchanged at interaction points [LIN85] ๐ธ but it's useful conceptually to think of "channel" as a communication path that carries the interactions between modules ๐ฆ) the abstract service primitives for a SAP are interactions on channels entering and leaving the TPE โจ the transport user is considered to be at the end of the channel connected to the transport SAP (TSAP), and the network service provider is considered to be at the end of the channel connected to the network SAP (NSAP) ๐ an interaction put into a channel by some module can be considered to move instantaneously over the channel onto a queue at the other end ๐ฅ the sender no longer has access to the interaction once it has been put into the channel ๐ the operation of the modeled system was designed with THIS semantics in mind, rather than the equivalent but much more abstract Estelle semantics ๐ง (in the Estelle semantics, each interaction point has an unbounded queue associated with it; the "attach" and "connect" primitives bind two interaction points, so an action, implied by the keyword "out", at one interaction point causes a specified interaction to be placed onto the queue associated with the other interaction point ๐) the sections that follow discuss the TSAP and the NSAP and the way these SAPs are described in the formal description ๐
1.2.2.1 Transport Service Access Point.
okay so the international transport standard allows for more than one TSAP to be associated with a transport entity, and multiple users may be associated with a given TSAP ๐ซถ this is useful when you want a certain quality of service correlated with a given TSAP ๐ for example, one TSAP could be reserved for applications requiring high throughput, such as file transfer, and the operation of transport connections on that TSAP could be designed to favor throughput ๐ฅ another TSAP might serve users who need short response time, such as terminals ๐ฆ and still another TSAP could be reserved for encryption reasons ๐
to give a way of referencing users associated with TSAPs, the user access to transport in the formal description goes through an array of Estelle interaction points ๐ this array is indexed by a TSAP address (T_address) and a Transport Connection Endpoint Identifier (TCEP_id) ๐ note that this dimensional object (TSAP) is considered simply to be a uniform set of abstract interfaces ๐ธ the indices MUST be of (Pascal) ordinal type in Estelle ๐ญ however, the actual address structure of TSAPs may not conform easily to such typing in an implementation ๐ so the indices as they appear in the formal description should be viewed as an organizational mechanism, NOT as an explicit way of associating objects in an operational setting โจ for example, actual TSAP addresses might be kept in some kind of table, with the table index being used to reference objects associated with the TSAP ๐
one particular issue with realizing TSAPs is making known to the users the means of referencing the transport interface, i.e., somehow providing the T_addresses and TCEP_ids to the users ๐ง this issue is not considered in any detail by either IS 7498 [ISO84b] or IS 8073 ๐ญ abstractly, the required reference is the T_address/TCEP_id pair ๐ however, this gives no insight into how the mechanism could work ๐ธ some approaches to this problem are discussed in Part 5 ๐ฆ
another issue is flow control on the TSAP channels ๐ซถ flow control is not part of the semantics for the Estelle channel, so the problem must be dealt with in another way ๐ the formal description gives an abstract definition of interface flow control using Pascal and Estelle mechanisms ๐ฅ this abstraction resembles many actual flow control schemes, but the realization of flow control will still depend on how the interface is implemented ๐ Part 3.2 discusses this in more detail โจ
1.2.2.2 Network Service Access Point.
okay so an NSAP may also have more than one network connection associated with it ๐ for example, the virtual circuits of X.25 correspond with this notion ๐ง on the other hand, an NSAP may have NO network connection associated with it, for example when the service at the NSAP is connectionless ๐ this MUST be the case when transport operates on a LAN or over IP ๐ so although the syntactical appearance of the NSAP in the formal description is similar to that for the TSAP, the semantics are essentially distinct [NTI85] ๐ฆ
Okay so distinct NSAPs don't have to mean separate physical networks ๐ฆ. One NSAP could be hooked up to X.25 service, another could be an IEEE 802.3 LAN, and a third could be a satellite link ๐ฐ๏ธ. But two NSAPs can also just be different addresses on the same network ๐, with no real reason except that it's easier to manage that way.
There are performance and system design issues to think about when deciding how NSAPs should be managed in these situations ๐ง . Like, if each NSAP is its own network, a transport entity that has to handle all the resource management for the transport connections and run those connections might struggle to keep up with data pouring in from two LANs and a satellite link at once ๐ญ. The better move might be to split up managing the transport connection resources from managing the NSAP resources and inputs ๐ , or even to have separate transport entities handling different network services, depending on what service quality needs to be kept up. It helps to picture the (total) transport service as not necessarily one giant monolithic entity ๐ง. Several distinct entities can live at the transport layer on the same end-system.
NSAP management drama mostly comes from connection-oriented network services ๐, because a connectionless service is either available to every transport connection or to none, which is basically infinite multiplexing and splitting. In the connection-oriented case it gets messy because of multiplexing, splitting, service quality stuff, and the particular character of the network service ๐. We get into this more in Part 3.4.1. In the formal description, network connection management runs on two things: a record for each possible connection, plus an array tied to each TPM where every array member matches one possible network connection ๐. And since some network services have a huge number of possible network connections, in an implementation these data structures may need to be dynamic instead of static ๐ (it's pretty clear, honestly). The connection record is indexed by NSAP and NCEP_id and holds a Slave module reference, virtual data connections to the TPMs tied to the network connection, a data connection (out) to the NSAP, and a data connection to the Slave ๐งฉ. There's also a "state" variable tracking whether the connection is available ๐, variables for managing the Slave, and an internal reference number that identifies the connection to TPMs. A member of the network connection array tied to a TPM gives that TPM status info on the network connection, plus input data (network) events and TPDUs). The formal description actually handles a lot of network connection management for you ๐: splitting, multiplexing, service quality (when defined), interface flow control, and concatenation of TPDUs. All of that is handled solely by the transport entity, so the TPMs are free to focus only on the explicit transport connection issues ๐ซถ. The scheme is also flexible enough to be simplified and adapted for handling the NSAP of a connectionless service โจ.
For connectionless NSAPs, the big issue is buffering ๐ซ , especially when data rates are high or there are tons of transport connections being served. It might also be a good idea for the transport entity to keep an eye on the service it's getting from the network ๐. That could mean, for example, periodically computing mean transmission delays to adjust timers, or exerting backpressure on the transport connections when network access delay goes up, which signals loading ๐. (Side quest: in the formal description, the Slave processor does a simple version of output buffer management ๐ง. When its queue goes past a threshold, it shuts off data from the TPMs associated with it. Through primitive functions, that threshold is loosely correlated with network behavior. but this mechanism is not meant to be a solution to this difficult performance problem ๐.)
1.2.3. Transport Protocol Machine โจ
In the formal description there are six classes of Transport Protocol Machines (TPM) ๐: General, Class 0, Class 1, Class 2, Class 3 and Class 4. Only General, Class 2 and Class 4 get covered here. The reason for all the variety is to make class negotiations easier to describe and to show clearly what each class does in the data transfer phase ๐. The General TPM gets spun up when a connection request comes in from a transport user, or when a CR TPDU arrives from a remote peer entity ๐. Then it gets swapped out for a class-specific TPM once the connect response comes back from the responding user, or once the CC TPDU comes in from the responding peer entity.
We'll dig into General, Class 2 and Class 4 below ๐. In an implementation, it's probably smart to merge the Class 2 and Class 4 operations into the General TPM, with new variables picking the class-specific operation whenever it's needed. (Check Part 9.4 too if you want to get Class 2 operation out of a Class 4 implementation.) Honestly this could simplify things and make the implemented protocol behave better overall ๐ธ.
1.2.3.1. General Transport Protocol Machine
Connection negotiation and establishment for all classes can be handled by the General Transport Protocol Machine ๐ค. Some parts of its description are so class-dependent that you can safely drop them if that class isn't implemented. Other parts are general and must be retained for the TPM to run properly. The General TPM only deals with connection establishment and negotiation, so the only TPDUs it sends or receives are CR, CC, DR and DC (the TPE blocks every other kind of TPDU from ever reaching the General TPM ๐ซ).
The General TPM doesn't get instantiated until a T-CONNECT-request or a CR TPDU shows up, so the TPE sets up a special internal connection to the module's TSAP interaction point ๐ to pass the T-CONNECT-request event along to the TPM. This keeps the automaton complete according to the specfication of the protocol ๐งฉ. When the TPM is about to be replaced by a class-specific one, the CC that was sent or received gets copied over to the new TPM, so no negotiation info gets lost ๐พ.
In the IS 8073 state tables for the different classes, most of the behavioral info for the automaton lives in the connection establishment phase ๐. The editors of the formal description kept most of the state table info from IS 8073 inside the General TPM description.
1.2.3.2. Class 2 Transport Protocol Machine
The Class 2 TPM description looks a lot like Class 4 in lots of ways ๐ฏโโ๏ธ, and that's on purpose!! The conformance statement in IS 8073 links Class 2 with Class 4, and the editors built the Class 2 TPM by copying the Class 4 one and stripping out the stuff on timers, checksums, and the like that isn't part of Class 2 operation โ๏ธ. The idea of getting Class 2 operation from a Class 4 implementation (Part 9.4) is literally based on this adaptation ๐ .
One Class 2 feature that Class 4 doesn't have ๐ is the option to skip end-to-end flow control. In that mode, Class 2 is basically Class 0 with multiplexing. Actually, the Class 0 TPM was derived from Class 2 (in IS 8073 these two classes have pretty much identical state tables ๐). So Class 0 operation could be gotten from Class 2 by not multiplexing, not sending DC TPDUs, choosing not to use flow control, and ending the network connection when a DR TPDU comes in. (Expedited data can't be used if flow control isn't used โ ๏ธ.) When Class 2 runs in this mode, it handles data flow inside the TPM a bit differently than it does when end-to-end flow control is on.
1.2.3.3. Class 4 Transport Protocol Machine
Dynamic queues model TPDU buffering in both the Class 4 and Class 2 TPMs ๐ฆ. It's a more general picture of implementations than a fixed array, and it's way easier to describe. Plus, the fixed array has semantics that would bring inefficiency along if you carried them into an implementation ๐. So the TPDU storage description uses linked lists with queue management functions, even though pointers feel super implementation-y ๐ค. One of those queue functions lets you pull several TPDUs off the head of the send queue at once, to model acknowledging several TPDUs together, the way IS 8073 specifies. Every TPDU record in the queue holds how many retransmissions were tried, for timer control (Class 2 TPDU records don't have this) โฑ๏ธ.
The Class 4 TPM has two states that aren't in IS 8073 ๐ซฃ. One was added only to make it easier to get credit when no credit was granted for the CR or CC TPDU. The other was added to clarify things when there's unacknowledged expedited data outstanding (Class 2 doesn't have this state). We'll cover the Class 4 TPM timers below, plus the end-to-end flow control description โฐ.
To keep things simple, the editors assumed no queueing of expedited data happens at the receiving entity's user interface ๐ง. The user can block the up-flow of expedited data until it's ready. That assumption has a couple of consequences. First, an ED TPDU can't be acknowledged until the user is ready to accept it, because receiving an EA TPDU would tell the sending peer that the receiver is ready for the next ED TPDU, which wouldn't be true. Second, since sending an ED TPDU blocks normal data flow, normal data flow stops until the receiving user is ready for that ED TPDU ๐.
This suggests the user interface should use separate, noninterfering mechanisms for passing normal and expedited data to the user ๐ค๏ธ. Also, the mechanism for expedited data passage should be blocked only in dire operational conditions ๐จ, so receiving expedited data at the user should be a procedure (transition) running at nearly the highest priority in the user process. The other option would be properly synchronizing the queued ED TPDUs with the DT TPDUs received, which needs some intricate handling of DT and ED sequence numbers ๐. That alternative might be attractive for implementations, but for clarity in the formal description it's only unnecessary complication ๐.
okay bestie, so the whole normal data TSDU processing bit is built on the idea that the data a T-DATA-request points at could be potentially arbitrarily long ๐โจ The TSDU is basically a file pointer ๐ง. Any file pointer is just a reference to a finite but arbitrarily large set of octet-strings. Making TPDUs out of that string is like reading a file in fixed-length segments (records or blocks, for example) ๐. Putting TPDUs back together is like appending each one to the tail of a file, and the file gets handed over once the end-of-TSDU (end-of-file) shows up ๐. This means the receiver can conceptually buffer the entire TSDU and never has to wonder whether received data can go up to the user before the EOT arrives ๐. (And if the file pointer points at a file the user already owns, then that question is just moot, iykyk ๐
)
The encoding of TPDUs is fully described using Pascal functions plus some special data manipulation functions from Estelle (these aren't normally part of Pascal ๐ค). There's one encoding function for each TPDU type, instead of one parameterised function doing all of them ๐. That was on purpose, so the separate structures of each type are easy to spot, since these functions are meant to be descriptive and not necessarily computational ๐.
The output of TPDUs from the TPM is guarded by an internal flow control flag ๐ฆ. The first time a TPDU goes out, the flag gets ignored, because if it doesn't get through, a retransmission can take care of it ๐. But when a retransmission is tried, the flag is heeded: the TPDU isn't sent, but the retransmission count goes up โฌ๏ธ. That guarantees the TPDU will eventually be sent or the connection will time out ๐ (even though the peer will never have received any TPDU to acknowledge, ngl that's kinda wild ๐ญ). Checksum computations happen in the TPM rather than the TPE, since the TPE has to handle all classes ๐งฎ. And if the TPMs can really run in parallel, performance may be greatly enhanced ๐.
The decoding of received TPDUs is only partly described in the Class 4 TPM description ๐. Only CR and CC TPDUs cause any trouble when decoding, and that's mostly because of the nondeterministic order of parameters in the variable part of the TPDU headers, plus the locality- and class-dependent content of that variable part ๐. Since the contents of the variable part (except the TSAP-IDs) don't affect which transport connection a TPDU is associated with, the decoding of the variable part isn't described in detail ๐ซถ. A description would be super lengthy because of all the possibilities, and it wouldn't really add to the reader's understanding ๐ .
1.2.4. Network Slave โจ
The primary functions of the Network Slave are to provide downward flow control in the TPE, to concatenate TPDUs into a single NSDU, and to respond to the receipt of spurious TPDUs ๐ง. The Slave has an internal queue where it keeps TPDUs until the network is ready to accept them for transmission ๐ฌ. The TPE is kept informed of the length of that queue, and the output of the TPMs is throttled if the length exceeds some threshold ๐ฐ. That threshold can be adjusted to meet current operating conditions ๐๏ธ. The Slave will concatenate the TPDUs in its queue if the option to concatenate is exercised and the conditions for concatenating are met ๐. Concatenation is a TPE option, which may be exercised or not at any time ๐.
1.2.5. Timers โฐ
In the formal description, timers are all modeled using a spontaneous transition with delay, where the delay parameter is the timer period ๐ฐ๏ธ. To activate a timer, a timer identifier gets placed into a set, which satisfies a predicate of the form
provided timer_x in active_timers
However, the transition code doesn't run until the elapsed time from the moment the identifier went into the set is at least equal to the delay parameter โณ. The editors of the formal description chose to model timers this way because it gave a simply expressed description of timer behavior. It also meant they didn't have to think about how timing works in a real system, or build special timer modules and communication to them ๐คทโโ๏ธ. So it's recommended that implementors don't follow the timer model closely in implementations, and instead consider the simplest and most efficient means of timing that the implementation environment permits ๐ธ. Implementors should also note that the delay parameter is typed integer in the formal description ๐ข. No scale conversion from actual time is expressed in the timer transition, so that scale conversion has to be considered when timers are realised โ๏ธ.
1.2.5.1. Transport Protocol Entity timers ๐
There's only one timer given in the formal description of the TPE, and that's the reference timer ๐ฏ. The reference timer was placed here so that all classes and all connections can use it as needed ๐ซ. There's actually little justification for having a reference timer within the TPM ๐ โโ๏ธ. It wastes resources by holding the transport endpoint, even though the TPM is incapable of responding to any input ๐ค. So the TPE is responsible for all aspects of reference management, including the timeouts ๐.
1.2.5.2. Transport Protocol Machine timers ๐ฆ
Class 2 transport doesn't have any timers that are required by IS 8073 ๐. However, the standard does recommend that an optional timer be used by Class 2 in certain cases to avoid deadlock ๐. The formal description provides this timer, with comments to justify its usage ๐. It is recommended that such a timer be provided for Class 2 operation ๐ . Class 4 transport has several timers for connection control, flow control and retransmissions of unacknowledged data ๐. Each of these timers is discussed briefly below, in terms of how they were related to the Class 4 operations in the formal description ๐. Further discussion of these timers is given in Part 8 ๐.
1.2.5.2.1. Window timer ๐ช
The window timer is used for transport connection control, as well as providing timely updates of flow control credit information ๐ณ. One of these timers is provided in each TPM ๐. It is reset each time an AK TPDU is sent, except during fast retransmission of AKs for flow control confirmation, when it is disabled ๐ .
1.2.5.2.2. Inactivity timer ๐ด
The primary usage of the inactivity timer is to detect when the remote peer has ceased to send anything (including AK TPDUs) ๐. This timer is mandatory when operating over a connectionless network service, since there's no other way to tell whether the remote peer is still functioning ๐จ. On a connection-oriented network service it has an additional usage, since to some extent the continued existence of the network connection indicates that the peer host hasn't crashed ๐ป.
Because of splitting, it's useful to provide an inactivity timer on each network connection that a TPM is assigned to โ๏ธ. That way, if a network connection is unused for some time, it can be released, even though a TPM assigned to it keeps operating over other network connections ๐งฉ. The formal description provides this capability in each TPM ๐ซถ.
1.2.5.2.3. Network connection timer ๐
This timer is an optional timer used to make sure every network connection a TPM is assigned to gets used periodically ๐. That prevents the expiration of the peer entity's inactivity timer for a network connection ๐. There's one timer for each network connection the TPM is assigned to ๐ข. If there's a DT or ED TPDU waiting to be sent, then it's chosen to be sent on the network connection ๐. If no such TPDU is waiting, an AK TPDU is sent instead โ๏ธ. So the NC timer serves somewhat the same purpose as the window timer, but it's broader in scope ๐.
1.2.5.2.4. Give-up timer ๐ณ๏ธ
There's one give-up timer for a TPM, which is set whenever the retransmission limit for any CR, CC, DT, ED or DR TPDU is reached ๐ฌ. When it expires, the transport connection is closed ๐.
1.2.5.2.5. Retransmission timers ๐
Retransmission timers are provided for CR, CC, DT, ED and DR TPDUs ๐ซ. The formal description provides distinct timers for each of these TPDU types, for each TPM ๐. However, this is just for clarity in the description, and Part 8.2.5 presents arguments for other strategies to be used in implementations ๐. Also, DT TPDUs with distinct sequence numbers are each provided with timers, as well ๐ง. There's a primitive function that determines the range within the send window for which timers will be set ๐ช. This has been done to express flexibility in the retransmission scheme ๐ฆ.
The flow control confirmation scheme specified in IS 8073 also provides for a "fast" retransmission timer ๐๏ธ. Its job is to make sure an AK TPDU carrying window resynchronization gets through after credit reduction, or when opening a window that was previously closed ๐ช. The formal description permits one such timer for a TPM ๐ซถ. It is disabled after the peer entity has confirmed the window information โ .
1.2.5.2.6. Error transport protocol data unit timer ๐จ
IS 8073 has a provision for an optional timeout to limit the wait for a response by the peer entity to an ER TPDU โณ. When this timer expires, the transport connection is terminated ๐ฅ. Each Class 2 or Class 4 TPM is provided with one of these timers in N3756 ๐.
1.2.6. End-to-end Flow Control ๐
Flow control in the formal description has been written in a way that permits flexibility in credit control schemes and acknowledgement strategies ๐ง.
1.2.6.1. Credit control ๐ณ
The credit mechanism in the formal description provides for actual management of credit by the TPE ๐ฆ. This is done through variables exported by the TPMs, which indicate to the TPE when credit is needed, and for the TPE to indicate when credit has been granted ๐ค. That way, the TPE has control over the credit a TPM has ๐. The mechanism allows for reduction in credit (Class 4 only) and the possibility of precipitous window closure ๐ฑ. It does not preclude the use of credit granted by the user or other sources, since credit need is expressed as current credit being less than some threshold ๐. Setting the threshold to zero permits these other schemes 0๏ธโฃ. An AK TPDU is sent each time credit is updated ๐.
The end-to-end flow control is also coupled to the interface flow control to the user ๐. If the user has blocked the interface up-flow, then the TPM is prohibited from requesting more credit when the current window is used up ๐ซ.
1.2.6.2. Acknowledgement โ
The mechanism for acknowledging normal data gives enough flexibility to send an AK TPDU in response to every Nth DT TPDU received, where N > 0 and N may be constant or dynamically determined ๐ข. Each TPM is provided with this independently of all other TPMs, so that the acknowledgement strategy can be determined separately for each transport connection ๐ง. Being able to alter the acknowledgement strategy is useful when operating over networks with varying error rates ๐ง๏ธ.
1.2.6.3. Sequencing of received data ๐ฌ
okay so IS 8073 doesn't spell out what must be done with DT TPDUs that arrive out of sequence but still inside the window ๐ค The only thing it asks for is sending an AK TPDU with the current window and sequence information. There are performance reasons to hold (cache) those DT TPDUs, mainly to avoid retransmissions โจ But buffering is complicated to implement, and describing it formally without basically describing an implementation is even harder ๐ So for simplicity, the formal description just discards those DT TPDUs and relies on retransmission to fill the gaps in the window sequence ๐ง
1.2.7. Expedited data โจ
okay this one is a whole plot ๐ญ As IS 8073 describes it, expedited data means normal data transmission has to be blocked until the acknowledgement comes back. The formal description handles that with a special state where normal data just can't be sent ๐ BUT recent experiments by the NBS and COMSAT Laboratories ran Class 4 transport over network services with high bandwidth, high transit delay and high error rates, and the protocol's performance dropped hard in those conditions ๐ That got presented to ISO, and the result is that the protocol will be modified to let the sender keep transmitting normal data the transport entity already accepted from the user before the expedited data request but hasn't put onto the network yet ๐ Once that change is incorporated into IS 8073, the formal description will be appropriately aligned ๐
2. Environment of implementation ๐ธ
the next sections walk through some general approaches to implementing the transport protocol, plus the advantages and disadvantages of each ๐ Certain commercial products get named along the way. Naming them does not mean the Department of Defense recommends or endorses them, and it doesn't mean they're the best available for the purpose described ๐ โโ๏ธ It's only there to show that an idea or approach can be implemented. UNIX is a trademark of AT&T Bell Laboratories. ๐ซถ
most of the discussion in the rest of the document is about Class 4 exclusively, since there are way more implementation issues with Class 4 than Class 2 ๐ฉ And since Class 2 is logically a special case of Class 4, you can implement Class 4 alone and just add special provisions to behave like Class 2 when necessary ๐ง
2.1. Host operating system program ๐ฅ๏ธ
a super common move is integrating the OSI transport service right into the host OS. How you do it usually depends on the OS's structure and facilities. For example, the transport software might live in the operating system kernel and be reached through a standard set of system calls. This is the usual route for UNIX. Class 4 transport has been done this way for System V by AT&T and for BSD 4.2 by several organizations ๐ Another option is structuring the transport service as a device driver. DEC does this for the VAX/VMS implementation of classes 0, 2, and 4 of the OSI transport protocol, and the Intel iRMX-86 implementation of Class 4 transport is another example. Intel makes the transport software a first level job within the operating system, which means it can be linked to the OS and loaded with every boot of the system ๐
integrating transport into the OS gives the communications user a few perks ๐ First, the interface to data communications services is well known to the application programmer, since the same principles are followed as for other OS services. That means you can build communications applications fast without retraining programmers ๐โโ๏ธ Second, the OS can support several different protocol suites without changing application programs. (This only works with careful engineering and control of the user-system call interface to the transport services ๐ง) Third, the transport software can take advantage of normally available OS services like scheduling, flow control, memory management, and interprocess communication, which saves time in developing and maintaining it ๐
the disadvantages depend mostly on the specific OS ๐ฌ But the major one, degradation of host application performance, is always there ๐ Since the communications software needs the processor's attention to handle interrupts and process protocol events, host applications will take some performance hit. How much depends largely on the hardware architecture and the processing resources the protocol requires. Other disadvantages can come from limited performance on the part of the communications service. That's usually a function of the particular OS, and it's most directly tied to the interprocess communication method the OS provides. In general, the more times a message gets copied from one area of memory to another, the worse the communications software performs ๐ซ The copying method and number of copies are often a function of the specific OS. For example, copying could be optimized if true shared memory is supported, since a significant amount of copying can be reduced to pointer-passing ๐งท
2.2. User program ๐งช
the OSI transport service can be implemented as a user job within any operating system, provided a means of multi-task communications is available or can be implemented. BUT this approach is almost always a bad one ๐ โโ๏ธ Performance problems will usually show up because the communication task is competing for resources like any other application program. The only justification is the need to quickly develop a simple implementation of the transport service. The NBS implemented the transport protocol this way as the basis for a transport protocol correctness testing system. Since performance wasn't a goal of the NBS implementation, the ease of development and maintenance made this approach attractive ๐งช
2.3. Independent processing element attached to a system bus ๐
putting the transport service on an independent processor that attaches to the system bus may give you substantial performance improvements over other approaches ๐ As computing power and memory have gotten cheaper, this approach has become realistic. Examples include Intel's implementation of iNA-961 on a variety of multibus boards like the iSBC 186/51 and the iSXM 554. Similar products have been developed by Motorola and by several independent vendors of IBM PC add-ons ๐งฉ This approach requires the transport software to run on an independent hardware set under operating system code developed to support the communications software environment. Communication with application programs takes place across the system bus using some simple, proprietary vendor protocol. With careful engineering, the application programmer can get a standard interface to the communications processor that's similar to the input/output subsystem interface ๐
the advantages are mainly about enhanced performance, both for the host applications and the communications service ๐ Depending on factors like the speed of the communications processor and the system bus, data communications throughput may improve by one or two orders of magnitude over what's available from host operating system integrated implementations. Throughput for host applications should also improve, since the communications processing and interrupt handling for timers and data links have been removed from the host processor. The communications mechanism between the host and communication processors is usually simple enough that no real burden is added to either processor ๐ซถ
the disadvantages come from complexity in developing the communications software ๐ตโ๐ซ Standard operating system tools can't be used to support software development for the communications board. A method of downloading the processor board and debugging the communications software may be required. A trade-off could be to put the code into firmware or microcode. The communications software must include at least a hardware monitor and, more typically, a small operating system to support functions like interprocess communication, buffer management, flow control, and task synchronization. Debugging the user to communication subsystem interface may involve several levels of system software and hardware ๐ชฒ
the design of the processing element can follow conventional lines, with a single processor handling almost all of the operation of the protocol ๐ง But with inexpensive processor and memory chips now available, a multiprocessor design is economically viable. The diagram below shows one such design, which almost directly corresponds to the structure of the formal description ๐ There are several advantages to this design:
- management of CPU and memory resources is at a minimum;
- essentially no resource contention;
- transport connection operation can be written in microcode, separate from network service handling;
- transport connections can run with true parallelism;
- throughput is not limited by contention of connections for CPU and network access; and
- lower software complexity, due to functional separation.
possible disadvantages are greater inflexibility and hardware complexity ๐ฌ But these might be offset by lower development costs for microcode, since the code separation should provide overall lower code complexity in the TPE and the TPM implementations ๐
in this system, the TPE instantiates a TPM by enabling its clock. Incoming Outgoing are passed to the TPMs along the memory bus. TPDUs TPDUs from a TPM are sent on the output data bus. The user interface controller accepts connect requests from the user and directs them to the TPE. The TPE assigns a connection reference and informs the interface controller to direct further inputs for this connection to the designated TPM. The shared TPM memory is analogous to the exported variables of the TPM modules in the formal description, and is used by the TPE to input TPDUs and other information to the TPM ๐ง
in summary, offloading communications protocols onto independent processing systems attached to a host processor across a system bus is quite common โจ As processing power and memory get cheaper, the amount of software offloaded keeps growing ๐ it is now typical to fine transport service available for several system buses, with interfaces to operating systems such as UNIX, XENIX, iRMX, MS-DOS, and VERSADOS ๐
Legend: **** data channel
.... control channel
==== interface i/o bus
O channel or bus connection point
user
input
*
*
__________V_________
| user interface | input bus
| controller |=================O==============O=======
|__________________| * *
* * *
* * _______*_______
* * | data buffers|
* * ...| TPM1 |
* * : |_____________|
* * : *
* * : *
_________ _____*__________ ________ __*____:______ *
| TPE | | TPE processor| |shared| | TPM1 | *
|buffers|***| | | TPM1 |***| processor | *
|_______| |______________| | mem. | |____________| *
* : : * |______| : *
* : : * * : *
* : : ***********O***********:********************
* : : memory bus : *
* : : : *
* : :...........................O...........*........
____*_________:___ clock enable *
| network | *
| interface |=========================================O========
| controller | output data bus
|________________|
*
*
V
to network
interface
2.4 Front end processor โจ
okay so, the more traditional way to offload communications protocols is a free-standing front end processor ๐ฅ๏ธ which is basically a cousin of putting the transport service on a board hanging off the system bus ๐ง. The vibe is very similar, the difference is just scale ๐ . Typical front end p interface locally as desirable, as long as such additions are strictly local (i.e., the invoking of such services does not result in the exchange of TPDUs with the peer entity) ๐ซถ.
The interface between the user and transport is asynchronous by nature ๐ธ (although some hypothetical implementation that is wholly synchronous could be conjectured, iykyk). This is because of two things: 1) the interprocess communications (IPC) mechanism between the user and transport decouples the two, and to avoid blocking the user process while it waits for a response, you need an asynchronous response mechanism ๐, and 2) there are some asynchronously-generated transport indications that have to be handled, like the arrival of user data or the abrupt termination of the transport connection due to network errors ๐ญ.
If we assume the user interface to transport is asynchronous, a few other aspects get predetermined too ๐ฆ. The big one is that transport service requests are confirmed twice โจ. The first confirmation happens when the transport service request is initiated, and interface routines can use it to catch invalid sequences of requests, like trying to send data on a connection that isn't open yet ๐. The second confirmation happens when the service request crosses the interface into the transport entity. The entity may accept or reject the request, depending on its resources and its assessment of connection (transport and network) status, priority, service quality ๐.
If the interface is going to be asynchronous, some mechanism has to handle the asynchronous (and sometimes unexpected) events ๐ฅ. Two common ways to do this are: 1) polling, and 2) a software interrupt mechanism. Polling can be wasteful of host resources in a multiprogramming environment, while the software interrupt can be complicated to implement ๐. However, if the interface is a combination of hardware and software, as in the cases discussed in Parts 2.3 and 2.4, then hardware interrupts may be available ๐.
One way to implement the abstract services is to associate each service primitive with an actual function that gets invoked ๐. These functions could live in a special interface library alongside the other functions and procedures that realize the interface. Each service primitive function would access the interprocess communication (IPC) mechanism as necessary to pass parameters to and from the transport entity ๐.
The description of the abstract service in IS 8073 and N3756 implies that the interface must handle TSDUs of arbitrary length ๐. So it may be useful to implement a TSDU as an object like a file-pointer, instead of as the message itself ๐ง. That way, in the sending entity, TPDUs can be formed by reading segments of TPDU-size from the file designated, no matter how long the file actually is ๐. In the receiving entity, each new TPDU could be buffered in a file designated by a file-pointer, which then gets passed to the user when the EOT arrives ๐ท. The formal description of transport actually describes this procedure, even though explicit file-pointers and files aren't used there ๐ง . This method isn't essentially different from keeping a linked list of buffers. (A disk file is arranged in precisely this fashion, although the file user is usually not aware of the structure ๐คซ.)
The abstract service definition describes the set of parameters that must be passed in each of the service primitives so transport can act properly on behalf of the user ๐ซถ. These parameters are required for the transport protocol to operate correctly (e.g., a called address must be passed with the connect request, and the connect response must contain a responding address) ๐ฎ. The abstract service definition doesn't rule out local parameters, though ๐ . Local parameters may be included in the implementation of the service interface for use by the local entity. One example is a buffer management parameter passed from the user in connect requests and confirms, which gives the transport entity expected buffer usage estimates ๐ฏ. The local entity could use this to implement a more efficient buffer management strategy than would otherwise be possible ๐.
One issue that really matters when designing and implementing a transport entity is providing a registration mechanism for transport users ๐๏ธ. This facility lets you identify to the transport entity those users who are willing to take part in communications with remote users ๐. An example is a data base management system, which usually responds to connection requests rather than initiating them ๐๏ธ. This procedure of user identification is sometimes called a "passive open" ๐. There are several ways to implement registration. One is to install the set of users that provide services in a table at system generation time. This may be inflexible, though, which is kind of a bummer ๐ฅฒ. A more flexible approach is to implement a local transport service primitive, "listen", to indicate a waiting user. The user then registers its transport suffix with the transport entity via the listen primitive ๐ซ. Another possibility is a combination of a predefined table and the listen primitive ๐งฉ. Other parameters may also be included, such as a partially or fully qualified transport address from which the user is willing to receive connections ๐ฌ. A variant on this approach is to provide an ACTIVE/PASSIVE local parameter on the connect request service primitive ๐. Part 5 discusses this issue in more detail ๐.
3.2 Flow control ๐
Interface flow control is generally considered a local implementation issue ๐ . However, to completely specify the behavior of the transport entity, the formal description had to include a model of how data flow is controlled across the service boundaries of transport ๐งญ. The international standards for transport and the OSI reference model only state that interface flow control shall be provided, and they give no guidance on its features ๐คทโโ๏ธ.
The actual mechanisms used for flow control don't need to explicitly follow the model in the formal description ๐ญ. They depend on how the interface itself is realized, meaning what TSDUs and service primitives really are, and how the transport entity actually communicates with its user, its environment, and the network service ๐. For example, if the transport entity talks to its user through named (UNIX) pipes, flow control can be realized using a special interface library routine, which the receiving process invokes to control the pipe ๐ช. This approach also has to consider the capacity of the pipe and the blocking of the sending process when the pipe is full (discussed further in Part 3.3) ๐ง. The close correspondence of this interpretation to the model is clear ๐. However, this interpretation apparently isn't workable if the user process and the transport entity are on physically separate processors ๐ฌ. In that situation, an explicit protocol between the receiving process and the sending process must be provided, which could have the complexity of the data transfer portion of the Class 0 transport protocol (Class 2 if flow controlled) ๐ ๏ธ. Note that the formal model, under proper interpretation, also describes this mechanism ๐.
3.3 Interprocess communication ๐งต
One of the most important elements of a data communication system is the approach to interprocess communication (IPC) ๐ซง. This is true because suites of protocols are often implemented as groups of cooperating tasks ๐ฏโโ๏ธ. Even if the protocol suites aren't implemented as task groups, the communication system is a funnel for service requests from multiple user processes ๐ช๏ธ. The services are normally communicated through some interprocess pathway ๐ค๏ธ. Usually, the implementation environment places some restrictions on the interprocess communications method that can be used ๐. This section describes the desired traits of IPC for use in data communications protocol implementations, outlines some possible uses for IPC, and discusses three common and generic approaches to IPC ๐ญ.
To support the implementation of data communications protocols, IPC should possess several desirable traits. ๐ First, IPC should be transaction based. That means you can send a message without the overhead of setting up and maintaining a connection โจ. The transactions should be confirmed, so a sender can detect and respond to non-delivery ๐ซถ. Second, IPC should support both the synchronous and the asynchronous modes of message exchange ๐ฆ. An IPC receiver should be able to ask for delivery of any pending messages, and it shouldn't be blocked from continuing if no messages are there. Optionally, the receiver can be allowed to wait if no messages are present, or to keep going if the path to the destination is congested ๐ธ. Third, IPC should preserve the order of messages sent to the same destination. This means you can use the IPC without modification to support protocols that preserve user data sequence ๐. Fourth, IPC should provide a flow control mechanism so the sender's transmission speed can be paced to match the receiver ๐.
The uses of IPC in data communication systems are honestly so many and so varied ๐ญ. A common and expected use is passing user messages among the protocol tasks that work together to perform the data communication functions ๐ . The user messages may contain the actual data or, more efficiently, references to the location of the user data ๐ง. Another common use is implementing and enforcing local interface flow control. By limiting the number of IPC messages queued on a particular address, senders can be slowed to a rate that suits the IPC consumer ๐. A third typical use is synchronizing processes. Two cooperating tasks can coordinate their activities, or their access to shared resources, by passing IPC messages at particular events in their processing ๐ฅ.
More creative uses of IPC include buffer, timer, and scheduling management ๐. If you set up buffers as a list of messages available at a known address at system initialization time, you can manage buffers simply and efficiently โจ. A process that needs a buffer just reads an IPC message from that known address. If no messages (i.e., buffers) are available, the process could block, or continue (as an option) ๐. A process that owned a buffer and wanted to release it would simply write a message to the known address, which unblocks any processes waiting for a buffer ๐.
For timers, messages can be sent to a known address that represents the timer module ๐ฆ. The timer module can then keep the list of timer messages with respect to a hardware clock โฐ. When a timer expires, the associated message can be returned to the originator via IPC. This is a super convenient way to process the set of countdown timers the transport protocol needs ๐.
Scheduling management can be done by using separate IPC addresses for message classes ๐. A receiving process can enforce a scheduling discipline based on the order in which the message queues are read ๐. For example, a transport process might have three queues: 1) normal data from the user, 2) expedited data from the user, and 3) messages from the network. If the transport process wants to give top priority to network messages, middle priority to expedited user messages, and the lowest priority to normal user messages, all it needs is to receive IPC messages on the highest priority queue until no more are available. Then the receiver moves to the next lower priority, and so on ๐ . You can get more sophisticated by setting limits on the number of consecutive messages received from each queue, and/or by varying the order in which each queue is examined ๐ฅ.
It is easy to see how a round-robin scheduling discipline could be implemented using this form of IPC ๐ธ.
Approaches to IPC can be placed into one of three classes: 1) shared memory, 2) memory-memory copying, and 3) input/output channel copying ๐. Shared memory is the most desirable of the three, because the amount of data movement is kept to a minimum ๐ซถ. To pass IPC messages using shared memory, the sender builds a small message that references a potentially large amount of user data. The small message is then either copied from the sender's process space to the receiver's process space, or mapped from one process space to another using techniques specific to the operating system and hardware involved โจ. These approaches to shared memory are equivalent, since the amount of data movement is kept to a minimum. The price you pay for this approach is the synchronization of access to the shared memory ๐ . This type of sharing is well understood, and several efficient and simple techniques exist to manage it ๐.
Memory-memory copying is an approach that has been commonly used for IPC in UNIX operating system implementations ๐ง. To pass an IPC message under UNIX, data is copied from the sender's buffer to a kernel buffer, and then from the kernel buffer to the receiver's buffer. So two copy operations are required for each IPC message. Other methods might only involve a single copy operation ๐ฆ. Also note that if one of the processes involved is the transport protocol implemented in the kernel, the IPC message only has to be copied once ๐. The main disadvantage of this approach is inefficiency. The major advantage is simplicity ๐.
When the processes that must exchange messages reside on physically separate computer systems (e.g., a host and front end), an input/output channel of some type must be used to support the IPC ๐ฅ. In that case, the problem is similar to the general problem of a transport protocol ๐. The sender must provide the IPC message to a standard operating system output mechanism, from where it will be transmitted over some physical medium to the receiver's operating system. The receiver's operating system then passes the message on to the receiving process through a standard operating system input mechanism ๐ . This set of procedures can vary greatly in efficiency and complexity, depending on the operating systems and hardware involved. Usually this approach to IPC is only used when the circumstances require it ๐ธ.
3.4. Interface to real networks โจ
Implementations of the class 4 transport protocol have been operated over a wide variety of networks, including: 1) ARPANET, 2) X.25 networks, 3) satellite channels, 4) CSMA/CD local area networks, 5) token bus local area networks, and 6) token ring local area networks ๐. This section briefly describes known instances of each use of class 4 transport, and provides some quantitative evaluation of the performance expectations for transport over each network type ๐.
3.4.1. Issues ๐
The interface of the transport entity to the network service will, in general, be realized in a different way from the user interface ๐ง. The network service processor is often separate from the host CPU, connected to it by a bus, direct memory access (DMA), or some other link ๐. A typical way to access the network service is by means of a device driver. The transfer of data across the interface in this case would be by buffer-copying ๐ซถ. Using double-buffering reduces some of the complexity of flow control, which is usually accomplished by examining the capacity of the target buffer ๐ฆ. If the transport processor and the network processor are distinct and connected by a bus or external link, network access may be more complicated, since copying will take place across the bus or link rather than across the memory board ๐ฌ. In any case, the network service primitives, as they appear in the formal description and IS 8073, must be carefully correlated to the actual access scheme, so that the semantics of the primitives is preserved โ ๏ธ. One way to do this is to create a library of routines, each of which corresponds to one of the service primitives. Each routine is responsible for sending the proper signal to the network interface unit, whether that communication is direct, as on a bus, or indirect, via a device driver ๐. For a connectionless network service, there is only one primitive, the N_DATA_request (or N_UNIT_DATA_request), which has to be realized ๐.
In the formal description, flow control to the NSAP is controlled by a Slave module, which exerts "backpressure" on the TPM if its internal queue gets too long ๐. Incoming flow, however, is controlled in much the same way as the flow to the transport user is controlled ๐ธ. The implementor is reminded that the formal description of flow control is specified for completeness, and not as an implementation guide ๐. So an implementation should depend upon the actual interfaces in the operating environment to realize the necessary functions ๐.
3.4.2. Instances of operation ๐
3.4.2.1. ARPANET ๐ฐ๏ธ
An early implementation of the class 4 transport protocol was developed by the NBS as a basis for conformance tests [NBS83]. This implementation was used over the ARPANET to communicate between NBS, BBN, and DCA ๐. The early NBS implementation ran on a PDP-11/70. A later revision of the NBS implementation was moved to a VAX-11/750 and a VAX-11/7;80 ๐ฅ๏ธ. The Norwegian Telecommunication Administration (NTA) implemented class 4 transport for the UNIX BSD 4.2 operating system to run on a VAX [NTA84]. A later NTA implementation runs on a Sun 2-120 workstation โจ. The University of Wisconsin has also implemented the class 4 transport protocol on a VAX-11/750 [BRI85]. The Wisconsin implementation is embedded in the BSD 4.2 UNIX kernel ๐ง. For most of these implementations, class 4 transport runs above the DOD IP and below DOD application protocols ๐.
3.4.2.2. X.25 networks ๐
The NBS implementations have been used over Telenet, an X.25 public data network (PDN) ๐ฆ. The heaviest use was testing class 4 transport between the NBS and several remotely located vendors, in preparation for a demonstration at the 1984 National Computing Conference and the 1985 Autofact demonstration ๐ฅ. Several approaches to implementation were seen in the vendors' systems, including ones similar to those discussed in Part 6.2 ๐ . At the Autofact demonstration, many vendors operated class 4 transport and the ISO internetwork protocol across an internetwork of CSMA/CD and token bus local networks, and Accunet, an AT&T X.25 public data network ๐.
3.4.2.3. Satellite channels ๐ฐ๏ธ
The COMSAT Laboratories have implemented class 4 transport for operation over point-to-point satellite channels with data rates up to 1.544 Mbps [CHO85] โญ. This implementation has been used for experiments between the NBS and COMSAT ๐ซถ. As a result of these experiments, several improvements have been made to the class 4 transport specification within the international standards arena (both ISO and CCITT) ๐. The COMSAT implementation runs under a proprietary multiprocessing operating system known as COSMOS ๐. The hardware base includes multiple Motorola 68010 CPUs with local memory, and Multibus shared memory for data messages ๐ฅ๏ธ.
3.4.2.4. CSMA/CD networks ๐ธ
The CSMA/CD network defined by the IEEE 802.3 standard is lowkey the most popular network for class 4 transport, bestie ๐. Transport has been shown running on it by AT&T, Charles River Data Systems, Computervision, DEC, Hewlitt-Packard, ICL, Intel, Intergraph, NCR and SUN ๐. Most of those demos happened at the 1984 National Computer Conference [MIL85b] and then again at the 1985 Autofact Conference โจ. Several of these vendors are now shipping products built on that demo software, and that is so iconic ๐ .
3.4.2.5. Token bus networks ๐ฆ
Class 4 transport became a mandatory protocol in General Motors' manufacturing automation protocol (MAP), so a bunch of implementations have been demoed running over a token bus network defined by the IEEE 802.4 standard ๐. Most of the older ones depended on a Concord Data Systems token interface module (TIM) to get onto the 5 Mbps broadband 802.4 service ๐ง.
Newer vendors have announced boards that support a 10 Mbps broadband 802.4 service ๐ฅ. The new boards plug straight into the computer's system buses, while the TIMs are reached over a high level data link control (HDLC) serial channel ๐. Vendors demoing class 4 transport over IEEE 802.4 networks include Allen-Bradley, AT&T, DEC, Gould, Hewlett-Packard, Honeywell, IBM, Intel, Motorola, NCR and Siemens ๐.
3.4.2.6. Token ring networks ๐
The class 4 transport implementations from the University of Wisconsin and from the NTA run over a 10 Mbps token ring network, plus ARPANET ๐ธ. The ring they used is from Proteon, not the recently finished IEEE 802.5 standard ๐.
3.4.3. Performance expectations ๐
Okay so, performance research on class 4 transport has been pretty limited, not gonna lie ๐ญ. Some work was done at the University of Wisconsin, at NTA, at Intel, at COMSAT, and at the NBS โญ. The stuff below pulls from this small body of research so an implementor gets a quantitative feel for the performance they can expect from class 4 transport implementations on different network types ๐. More detail is in several published reports [NTA84, BRI85, INT85, MIL85b, COL85]. Some results come from actual measurements and others come from simulation, and this difference is clearly noted, so you won't be confused ๐ซถ.
3.4.3.1. Throughput ๐
Several live experiments have measured the throughput possible with class 4 transport implementations ๐ฅ. Achievable throughput depends on a lot of factors, including: 1) CPU capabilities, 2) use or non-use of transport checksum, 3) IPC mechanism, 4) buffer management technique, 5) receiver resequencing, 6) network error properties, 7) transport flow control, 8) network congestion and 9) TPDU size ๐ง . Some of these get their own discussion elsewhere in this document. Keep these issues in mind when you read the throughput numbers here, periodt ๐ .
The University of Wisconsin put class 4 transport in the UNIX kernel for a VAX-11/750, with the express purpose of measuring achievable throughput ๐. Throughputs observed over the ARPANET ranged between 10.4 Kbps and 14.4 Kbps ๐ข. On an unloaded Proteon ring local network, observed throughput with checksum ranged between 280 Kbps and 560 Kbps ๐. Without checksum, throughput ranged between 384 Kbps and 1 Mbps โจ.
COMSAT Laboratories ran class 4 transport under a proprietary multiprocessor operating system on a multiprocessor 68010 hardware architecture ๐ฐ๏ธ. The transport implementation ran on one 68010, while the traffic generator and link drivers ran on a second 68010 ๐ค. All user messages were created in a global shared memory and only copied for transmission over the satellite link ๐ฐ๏ธ. Throughputs as high as 1.4 Mbps were observed without transport checksumming, while up to 535 Kbps could be reached when transport checksums were used ๐ค. Note that when the 1.4 Mbps was reached, the transport CPU was idle 20% of the time (i.e., the 1.544 Mbps satellite link was the bottleneck) ๐. So the transport implementation used here could probably achieve around 1.9 Mbps user throughput with the experiment parameters unchanged ๐. Higher throughputs are possible by increasing the TPDU size, however larger messages have a greater chance of damage during transmission โ ๏ธ.
Intel built a class 4 transport product for operation over a CSMA/CD local network (iNA-960 running on the iSBC 186/51 or iSXM 552) ๐ป. Intel measured throughputs for this combo and published the results in a technical analysis comparing iNA-960 performance on the 186/51 with iNA-960 on the 552 ๐. The CPU running transport was a 6 MHz 80186, and an 82586 co-processor handled the medium access control ๐ง. Measured throughputs ranged between 360 Kbps and 1.32 Mbps, depending on the parameter values used ๐ซ.
A simulation of class 4 transport, using a model developed at the NBS, was used to predict the performance of the COMSAT implementation, and it's now being used to predict the performance of a three processor architecture ๐ฎ. That architecture includes an 8 MHz host connected to an 8 MHz front end over a system bus ๐ฅ๏ธ. The third processor provides medium access control for the specific local networks being modeled ๐ฏ. Early model results predict throughputs over an unloaded CSMA/CD local network of up to 1.8 Mbps ๐. The same system modeled over a token bus local network with the same transport parameters yields throughput estimates of up to 1.6 Mbps ๐ฆ. The token bus technology, however, permits larger message sizes than CSMA/CD does ๐. When TPDUs of 5120 bytes are used, throughput on the token bus network is predicted to reach 4.3 Mbps ๐๐.
3.4.3.2. Delay โณ
The one-way delay between the sending transport user and the receiving transport user is determined by a complex set of factors ๐งฉ. Readers should also know that this is generally a difficult thing to measure, and little work has been done so far on expected one-way delays with class 4 transport implementations ๐ฉ. This section gives a tutorial explaining the factors that determine the one-way delay a transport user can expect ๐. Delay experiments performed by Intel are reported [INT85], along with some simulation experiments conducted by the NBS [MIL85a] ๐ฌ.
A transport user can generally expect one-way delays to be determined by the following equation ๐งฎ.
D = TS + ND + TR + [IS] + [IR] (1)
where:
[.] means the enclosed quantity may be 0
D is the one-way transport user delay,
TS is the transport data send processing time,
IS is the internet datagram send processing time,
ND is the network delay,
IR is the internet datagram receive processing
time, and
TR is the transport data receive processing time.
Although no performance measurements exist for the ISO internetwork protocol (ISO IP), the ISO IP is so similar to the DOD IP that processing times for sending and receiving datagrams should be about the same for both IPs ๐ค. So the IS and IR terms above get ignored from here on out ๐ โโ๏ธ. Keep in mind that many of these factors vary depending on the application traffic pattern and the loads a transport implementation sees ๐ช๏ธ. In the discussion that follows, the transport traffic is assumed to be a single message ๐.
The value for TS depends on the CPU used, the IPC mechanism, the use or non-use of checksum, the size of the user message and the size of TPDUs, the buffer management scheme in use, and the method chosen for timer management ๐ง . Checksum processing times have been observed at 3.9 us per octet for a VAX-11/750, 7.5 us per octet on a Motorola 68010, and 6 us per octet on an Intel 80186 โฑ๏ธ. The class 4 transport checksum algorithm has a considerable effect on achievable performance, and this is discussed further in Part 7 ๐ซ . Typical values for TS, excluding the processing due to the checksum, are about 4 ms for CPUs such as the Motorola 68010 and the Intel 80186 โจ. For 1024 octet TPDUs, checksum calculation can increase the TS value to about 12 ms ๐.
The value of TR depends on similar details as TS ๐ฏ. An additional consideration is whether or not the receiver caches (buffers) out-of-order TPDUs ๐๏ธ. If it does, TR will be higher when no packets are lost (because of the overhead from the resequencing logic) ๐ตโ๐ซ. Also, when packets are lost, TR can look like it's going up because of transport resequencing delay ๐. When out-of-order packets aren't cached, lost packets increase D, because each unacknowledged packet has to be retransmitted (and only after a delay waiting for the retransmission timer to expire) โ. These details aren't taken into account in equation 1 ๐. Typical TR values you can expect with non-caching implementations on Motorola 68010 and Intel 80186 CPUs are approximately 3 to 3.5 ms ๐ญ. When transport checksumming is used on these CPUs, TR becomes about 11 ms for 1024 byte TPDUs ๐ .
The value of ND is highly variable, depending on the specific network technology in use and on the conditions in that network ๐. In general, ND can be defined by the following equation ๐งพ.
ND = NQ + MA + TX + PD + TQ (2)
where:
NQ is network queuing delay,
MA is medium access delay,
TX is message transmission time,
PD is network propagation delay, and
TQ is transport receive queuing delay.
Each term of the equation gets its own discussion in the paragraphs below ๐.
Network queuing delay (NQ) is the time a TPDU spends waiting in a network transmit queue until it's first in line for transmission ๐ถโโ๏ธ. NQ depends on the size of the network transmit queue, the rate at which the queue is emptied, and the number of TPDUs already on the queue ๐. The size of the transmit queue is usually an implementation parameter and is generally at least two messages ๐. The rate at which the queue empties depends on MA and TX (see the discussion below) ๐. The number of TPDUs already on the queue is determined by the traffic intensity (ratio of mean arrival rate to mean service rate) ๐. As an example, consider an 8 Kbps point-to-point link serving an eight message queue that contains 4 messages with an average size of 200 bytes per message ๐ง. The next message to be placed into the transmit queue would experience an NQ of 800 ms (i.e., 4 messages times 200 ms) โฐ. In this example, MA is zero 0๏ธโฃ. These basic facts let you compute NQ for particular environments ๐ง โจ. Note that if the network send queue is full, back pressure flow control will force TPDUs to queue in the transport transmit buffers and make TS appear to increase by the amount of the transport queuing delay ๐ซธ. This condition depends on application traffic patterns, but it's ignored for the purpose of this discussion ๐.
The value of MA depends on the network access method and on how congested or loaded the network is ๐ธ. On a point-to-point link, MA is zero, no cap. On CSMA/CD networks, MA depends on the load, the number of stations, the arrival pattern, and the propagation delay. It typically ranges from zero (no load) up to about 3 ms at 80% loads. NBS simulations predict that an individual station on a CSMA/CD network can see MA as high as 27 ms under 70% loads ๐ญ. So depending on the traffic patterns, a single station might see an average MA that's way higher than the network-wide average. On token bus networks, MA is determined by the token rotation time (TRT), which depends on the load, the number of stations, the arrival pattern, the propagation delay, and the values of the token holding time and target rotation times at each station ๐ฆ.
For small networks of 12 stations with a propagation delay of 8 ns, NBS simulations predict TRT values of about 1 ms for zero load and 4.5 ms for 70% loads. This is for 200 byte messages arriving with an exponential arrival distribution โจ. Traffic patterns also seem to be a big deal for target rotation time. When a pair of stations does a continuous file transfer, the average TRT for the simulated network is predicted to be 3 ms for zero background load and 12.5 ms for 70% background load (total network load of 85%) ๐.
The message size and the network transmission speed directly determine TX. Typical transmission speeds include 5 and 10 Mbps for standard local networks, 64 Kbps, 384 Kbps, or 1.544 Mbps for point-to-point satellite channels, and 9.6 Kbps or 56 Kbps for public data network access links ๐.
The properties of the network in use determine the values of PD. On an IEEE 802.3 network, PD is limited to 25.6 us. For IEEE 802.4 networks, the signal is propagated up-link to a head end and then down-link from the head end. PD in these networks depends on the distance of the source and destination stations from the head end, and on the head end latency. Because the maximum network length is much greater than with IEEE 802.3 networks, the PD values can also be much greater ๐. The IEEE 802.4 standard requires that a network provider give a value for the maximum transmission path delay. For satellite channels, PD is typically between 280 and 330 ms. For the ARPANET, PD depends on the number of hops that a message makes between source and destination nodes. The NBS and NTIA measured ARPANET PD average values of about 190 ms [NTI85]. In the ARPA internet system, PD is quite variable, depending on the number of internet gateway hops and the PD values of any intervening networks (possibly containing satellite channels). In experiments on an internetwork containing a satellite link to Korea, David Mills determined [RFC85] that internet PD values could range from 19 ms to 1500 ms ๐คฏ. Thus, PD values ranging from 300 to 600 ms can be considered typical for ARPANET internetwork operation ๐.
The amount of time a TPDU waits in the network receive queue before being processed by the receiving transport is represented by TQ. It's similar to NQ, in that the value of TQ depends on the size of the queue, the number of TPDUs already in the queue, and the rate at which transport empties the queue ๐ง.
Often the user delay D will be dominated by one of the components. On a satellite channel, the principal component of D is PD, which implies that ND is a principal component by equation (2). On an unloaded LAN, TS and TR might contribute most to D. On a highly loaded LAN, MA may cause NQ to rise, again implying that ND is a major factor in determining D ๐ .
Some one-way delay measures have been made by Intel for the iNA-960 product running on a 6 MHz 80186. For an unloaded 10 Mbps CSMA/CD network, the Intel measures show delays as low as 22 ms. The NBS has done some simulations of class 4 transport over 10 Mbps CSMA/CD and token bus networks. These (unvalidated) predictions show one-way delays as low as 6 ms on unloaded LANs and as high as 372 ms on CSMA/CD LANs with 70% load ๐.
3.4.3.3. Response time ๐
Determining the transport user response time (i.e., two-way delay) depends on many of the same factors discussed above for one-way delay. In fact, response time can be represented by equation 3 as shown below ๐.
R = 2D + AS + AR (3)
where:
Ris transport user response time,Dis one-way transport user delay,ASis acknowledgement send processing time, andARis acknowledgement receive processing time.
D has been explained above. AS and AR deal with the acknowledgement sent by transport in response to the TPDU that embodies the user request ๐ซถ.
AS is simply the amount of time the receiving transport must spend to generate an AK TPDU. Typical times for this function are about 2 to 3 ms on processors such as the Motorola 68010 and the Intel 80186. Of course, the actual time required depends on factors such as those explained for TS above ๐ฅ.
AR is the amount of time the sending transport must spend to process a received AK TPDU. Determining the actual time required depends on factors previously described. Note that for AR and AS, processing takes somewhat longer when the checksum is included. However, AK TPDUs are usually between 10 and 20 octets in length, so the increased time due to checksum processing is much less than for DT TPDUs โจ.
No class 4 transport user response time measures are available, but some simulations have been done at the NBS. These predictions are based on implementation strategies that commercial vendors have used when building microprocessor-based class 4 transport products. The simulations predicted average response times of about 21 ms on an unloaded 10 Mbps token bus network, and 25 ms with 70% loading. On a 10 Mbps CSMA/CD network, the simulations predict response times of about 17 ms for no load and 54 ms for a 70% load ๐ธ.
3.5. Error and status reporting ๐ฆ
Although the abstract service definition for the transport protocol specifies a set of services to be offered, the actual set of services provided by an implementation need not be limited to these. In particular, local status and error information can be provided as a confirmed service (request/response) and as an asynchronous "interrupt" (indication). One use for this service is to let users query the transport entity about the status of their connections. An example of information that could be returned from the entity is:
- connection state
- current send sequence number
- current receive and transmit credit windows
- transport/network interface status
- number of retransmissions
- number of DTs and AKs sent and received
- current timer values
Another use for the local status and error reporting service is administration. Using the service, an administrator can gather information like that described above for each open connection. In addition, statistics about the transport entity as a whole can be obtained, such as the number of transport connections open, the average number of connections open over a given reporting period, buffer use statistics, and the total number of retransmitted DT TPDUs. The administrator might also be given the authority to cancel connections, restart the entity, or manually set timer values ๐.
4. Entity resource management โจ
4.1. CPU management ๐
The formal description has implicit scheduling of TPM modules, due to the semantics of the Estelle structuring principles. However, the implementor should not depend on this scheduling to obtain optimal behavior, since, as stated in Part 1, the structures in the formal description were imposed for purposes other than operational efficiency ๐.
Whether by design or by default, every implementation of the transport protocol embodies some decision about allocating the CPU resource among transport connections. The resource may be monolithic, i.e., a single CPU, or it may be distributed, as in the example design given in Part 2.3. In the former case, there are two simple techniques for apportioning CPU processing time among transport connections. The first, first-come/first-served, consists of the transport entity handling user service requests in the order in which they arrive. No attempt is made to prevent one transport connection from using an inordinate amount of the CPU ๐ญ.
The second simple technique is round-robin scheduling of connections. Under this method, each transport connection is serviced in turn. For each connection, transport processes one user service request, if one is present at the interface, before proceeding to the next connection ๐.
The quality of service parameters provided in the connection request can be used to provide a finer-grained strategy for managing the CPU. The CPU could be allocated to connections requiring low delay more often, while those requiring high throughput would be served less often but for longer periods (i.e., several connections requiring high throughput might be serviced in a concurrent cluster) ๐.
For example, in the service sequence below, let "T" represent m > 0 service requests, each requiring high throughput. Let "D" represent one service request requiring low delay, and let the suffix n = 1,2,3 represent a connection identifier, unique only within a particular service requirement type (T,D). Thus T1 represents a set of service requests for connection 1 of the service requirement type T, and D1 represents a service set (with one member) for connection 1 of service requirement type D ๐ง.
D1___D2___D3___T1___D1___D2___D3___T2___D1___D2___D3___T1...
If m = 4 in this service sequence, then service set D1 will get worst-case service once every seventh service request processed. Service set T1 receives service on its four requests only once in fourteen requests processed.
D1___D2___D3___T1___D1___D2___D3___T2___D1___D2___D3___T1...
| | | | | |
| 3 requests | 4 | 3 | 4 | 3 |
This means the CPU is allocated to T1 29% ( 4/14 ) of the available time, whereas D1 obtains service 14% ( 1/7 ) of the time, assuming processing requirements for all service requests are equal. Now assume that, on average, there is a service request arriving for one out of three of the service requirement type D connections. The CPU is then allocated to the T type 40% ( 4/10 ), while the D type is allocated 10% ( 1/10 ) ๐.
4.2. Buffer management ๐ซง
Buffers are used as temporary storage areas for data on its way to or arriving from the network. Decisions must be made about buffer management in two areas. The first is the overall strategy for managing buffers in a multi-layered protocol environment. The second is specifically how to allocate buffers within the transport entity ๐.
In the formal description, no details of buffer strategy are given, since such strategy depends so heavily on the implementation environment. Only a general mechanism is discussed in the formal description for allocating receive credit to a transport connection, without any expression as to how this resource is managed ๐ธ.
Okay bestie, good buffer management should match up with the traffic that applications throw at the transport service ๐ And that traffic also affects how well the protocol performs โจ Right now, nobody really understands how a buffer strategy lines up with optimal service for a given traffic distribution ๐ Some work has been done, though! Check out Jeffery Spirn [SPI82, SPI83], plus the NBS experiment plan for research [HEA85] on how application traffic patterns affect Class 4 transport performance ๐ง
4.2.1. Overall buffer strategy ๐
Three schemes for managing buffers in a multilayered environment are described here ๐ They're a whole spectrum of options for the implementor, so pick your vibe ๐
The first is a strictly layered approach. Each entity in the protocol hierarchy, as a process, manages its own pool of buffers, totally independent of the entities at other layers ๐ฆ This is so simple! An entity doesn't have to coordinate buffer usage with a resource manager that's busy serving a bunch of protocol entities ๐ It's also modular. The interface shown to entities in other layers is well defined, and protocol service requests and responses get passed between layers by value (copying) instead of by reference (pointer copying) ๐ซถ This is a strict reading of the OSI reference model, IS 7498 [ISO84b], and the protocol entities hide message details from each other, which keeps things neat at the entity interfaces ๐
The one downside of a strictly layered scheme comes from that value-passing interface ๐ญ Every time protocol data and control information moves from one layer to another, it has to be copied from one layer's buffers into another's. Copying between layers in a multi-layered environment is expensive, and it hits performance hard, both for the communications system and for the computer system it's running on overall ๐
The second scheme is buffer sharing. Here, buffers are a shared resource among multiple protocol entities, and protocol data and control information in the buffers gets exchanged by passing a buffer pointer, or reference, instead of the values like in the strictly layered approach ๐ฅ The big win is that only a tiny bit of information, the buffer pointer, gets copied from layer to layer. So the performance is way better than the strictly layered approach ๐
There are several requirements you have to meet to implement buffer sharing โจ First, the host system architecture must allow memory sharing among the protocol entities that share the buffers ๐ธ You can do this in a few ways. Multiple protocol entities might be implemented as one process, all sharing the same process space (e.g., kernel space). Or the host system architecture may let processes map portions of their address space to common buffer areas at some known location in physical memory ๐ง
Next, you need a buffer manager ๐ It's responsible for handing out buffers to protocol entities when they need them, pulling from a list of free buffers, and recycling used buffers back onto the free list ๐ The pool can be one or more lists, depending on how much control you want. For example, there could be separate lists for outgoing and incoming messages ๐ฆ
The protocol entities also have to be implemented so they cooperate with the buffer manager ๐ซถ Sounds obvious, but it really shapes how implementors build the communications system, so it's a big deal ๐ค Here's how the cooperation works: an entity at layer N requests a buffer and is allocated one by the manager. Then each buffer gets returned to the manager by some entity at layer N - k (outgoing data) or N + k (incoming data) ๐
Protocol entities also have to cooperate with each other, obviously ๐ As buffers get allocated and sent toward the network from higher layers, you have to leave room for protocol control information that lower layers will add. That usually means allocating oversized buffers so there's space for headers to be prepended at lower layers ๐ Going the other way, as buffers move up from the network, each protocol entity processes its headers before passing the buffer along โจ You can handle all of this by managing pointers into the buffer header space ๐ช
In their pure forms, neither the strictly layered nor the shared buffer scheme is practical ๐ The strictly layered one takes a performance penalty for copying buffers. But you also can't realistically make buffers shared by entities at every layer of the protocol hierarchy ๐ญ The lower protocol layers (OSI layers 1 - 4) have essentially static buffer requirements, while the upper layers (OSI layers 5 - 7) tend to be dynamic ๐ Several different applications might be running at once, and their buffer needs change as the set of applications changes ๐ธ At the transport layer, though, that variation isn't visible, and buffer requirements depend more on service quality considerations than on the specific nature of the applications being served ๐ง So this suggests a hybrid scheme: entities in OSI layers 1 - 4 share buffers, while entities in each of OSI layers 5 - 7 share a buffer pool associated with each layer ๐ You get most of the efficiency of a pure shared buffer scheme, and you still get simple, modular interfaces where they matter most ๐ซถ
4.2.2. Buffer management in the transport entity ๐
Buffers get allocated in the transport entity for two purposes: sending and receiving data ๐ Sending is the simpler one! You should allocate enough space for outgoing data to hold the maximum number of data messages the entity will have outstanding (i.e., sent but unacknowledged) at any time ๐ The send buffer space is set by whichever of two values is lower: the send credit received from the receiving transport entity, or a maximum value imposed by the local implementation, based on factors like overall buffer capacity โจ
Receive buffer allocation is way more interesting ๐ It's directly tied to the credit value sent to the peer transport entity in CR (or CC) and AK TPDUs ๐ฆ If the total credit offered to the peer exceeds the total available buffer space and credit reduction isn't implemented, deadlock may happen, which can cause one or more transport connections to get terminated ๐ฑ For this discussion, offered credit is assumed to be equivalent to available buffer space ๐ซถ
The simplest scheme is a fixed amount per transport connection ๐ That amount gets allocated no matter how the connection is going to be used. It's fair, since all connections get treated equally ๐ The implementation approach in Part 2.3, where each transport connection is handled by a physically separate processor, could obviously use this scheme, since the allocation would be in the form of memory chips assigned by the system designer when the system is built ๐ง
A more flexible method is based on the connection quality of service (QOS) the user requests ๐ธ For example, a QOS indicating high throughput would get more send and receive buffer space than one indicating low delay ๐ฅ Connection priority can also decide send and receive buffer allocation, with important (i.e., high priority) connections getting more buffer space ๐
A slightly more complex scheme apportions send and receive buffer space using both QOS and priority ๐ For each connection, QOS indicates a general category of operation (e.g., high throughput or low delay) ๐ Within that category, priority determines the specific amount of buffer space allocated from a range of possible values ๐ The general categories may overlap, so you could end up with a high priority connection with low throughput requirements getting more buffer space than a low priority connection that needs high throughput ๐ Chaotic, but that's the spec ๐
5. Management of Transport service endpoints โจ
As mentioned in Part 1.2.1.1, a transport entity needs some way of referencing a transport connection endpoint within the end system, called a TCEP_id ๐ฆ A few factors influence how TCEP_ids get managed:
- IPC mechanism between the transport entity and the session entity (Part 3.3);
- transport entity resources and resource management (Part 4);
- number of distinct TSAPs supported by the entity (Part 1.2.2.1); and
- user process rendezvous mechanism (the means by which session processes identify themselves to the transport entity, at a given TSAP, for association with a transport connection).
The IPC mechanism and the user process rendezvous mechanism have more direct influence than the other two factors on how TCEP_id management gets implemented ๐ซถ
The number of TCEP_ids available should reflect the resources available to the transport entity, since each TCEP_id in use represents a potential transport connection ๐ The formal description assumes there's a function in the TPE that decides, based on current resource availability, whether or not to issue a TCEP_id for any connection request received ๐ If a TCEP_id is issued, resources get allocated for the connection endpoint โจ But users of transport have a somewhat different problem: the transport entity has to somehow tell the session entity which TCEP_ids are available at a given TSAP ๐
In the formal description, a T-CONNECT-request is permitted to enter at any TSAP/TCEP_id ๐ธ A function in the TPE considers whether or not resources are available to support the requested connection ๐
There's also a function that checks whether a TSAP/TCEP_id is busy by seeing if a TPM is allocated to it ๐ง But that function isn't useful to the session entity, which doesn't have access to the transport entity's operations ๐ญ Honestly, this description of the procedure is clearly too loose for an implementation ๐
One solution is to provide a new (abstract) service, T-REGISTER, locally, at the interface between transport and session ๐๐
Okay, bestie, this is where the T-REGISTER service comes in, and it's honestly such a clever fix for a messy problem ๐
___________________________________________________________________
| Primitives Parameters |
|_________________________________________________________________|
| T-REGISTER request | Session process identifier |
|________________________________|________________________________|
| T-REGISTER indication | Transport endpoint identifier,|
| | Session process identifier |
|________________________________|________________________________|
| T-REGISTER refusal | Session process identifier |
|________________________________|________________________________|
So here's how it goes, step by step ๐
- A session process gets identified to the transport entity with a T-REGISTER-request event. If a TCEP_id is available, the transport entity picks one and puts it into a table for the TSAP where that T-REGISTER-request happened, along with the session process identifier. Then the TCEP_id and the session process identifier get sent up to the session entity through a T-REGISTER-indication event. If no TCEP_id is available, a T-REGISTER-refusal event comes back carrying the session process identifier ๐ฅบ Also, any time an assigned TCEP_id isn't tied to an active transport connection process (an allocated TPM), the transport entity can send a T-REGISTER-refusal to the session entity. That could mean stuff like resources aren't around to support a connection anymore, since TC resources don't get allocated at registration time.
- If the session entity is the one starting the transport connection, it issues a T-CONNECT-request with the TCEP_id as a parameter. (Fair warning, this is a slightly different move than what N3756 does, since N3756 doesn't have that parameter. It's needed so the formal description lines up with the transport service description and the session protocol definition ๐ง) If the session entity is waiting for a connection request from a remote peer at this TSAP, the transport just sits there and doesn't do anything with the TCEP_id until a CR TPDU addressed to that TSAP shows up. When it does, the transport entity sends a T-CONNECT-indication to the session entity with a TCEP_id as a parameter. As a little management helper, the table entry for the TCEP_id can get marked "busy" once that TCEP_id is tied to an allocated TPM ๐ซถ
- If a CR TPDU arrives and there's no TCEP_id in the table for the TSAP it's addressed to, the transport picks a TCEP_id, puts it in the T-CONNECT-indication sent to the session entity as a parameter, and stores it in the table. The T-CONNECT-response that comes back from the session entity will carry the TCEP_id and the session process identifier. If that session process identifier is already in the table, the new one gets thrown out. Otherwise, it goes into the table. This same thing happens if the table has entries but they're all marked busy or empty. And if the table is full with every entry marked busy, the transport entity sends a DR TPDU to the peer transport entity to say the connection can't be made ๐ Lowkey, the transport entity can also shut a TSAP down by marking all of its table entries busy ๐ฅ
The T-REGISTER service only works as well as the IPC mechanisms between the transport and session entities allow. The user process rendezvous problem gets solved in general by T-REGISTER, and that idea came from Michael Chernik of the NBS [CHK85] ๐
6. Management of Network service endpoints in Transport โจ
6.1. Endpoint identification.
Okay, so endpoints at an NSAP work differently than endpoints at a TSAP ๐ฆ The services at different TSAPs are basically the same thing, even though the quality can vary, and that's a local choice. But distinct NSAPs can totally give access to different network services. For example, one NSAP might give access to a connectionless network service through an internetwork protocol, while another gives access to a connection-oriented service for talking over a local subnetwork. It's also possible to have a bunch of distinct NSAPs on the same subnetwork, each one offering some service features that make it stand out from the others and that matter locally ๐
A transport entity that's accessing an X.25 service can use the logical channel numbers for the virtual circuits as NCEP_ids ๐ธ An NSAP that only gives access to a permanent virtual circuit only needs one NCEP_id to multiplex the transport connections. And a CSMA/CD network also only needs one NCEP_id, even though it's connectionless ๐
6.2. Management issues.
The Class 4 transport protocol has successfully run over both connectionless and connection-oriented network services, and that's honestly iconic ๐ In both modes, there's some information about the network service that a transport implementation could use to level up its performance โจ For example, if you know the expected delay to a destination, you can pick an optimal retransmission timer value for a connection instance ๐ง The thing is, the information transport implementations could use, plus the mechanisms for getting and managing it, are as a group not really well understood yet ๐ Projects are underway in ISO committees to deal with managing OSI as an architecture and managing the transport layer as a layer.
When you're running the Class 4 transport protocol over a connection-oriented network service, there are a few issues that need to be handled, including:
- When should a new network connection be opened to support a transport connection, versus multiplexing onto an existing one?
- When a network connection isn't being used by any transport connection anymore, should it be closed, or should it stay open waiting for a new transport connection? ๐ค
- When a network connection is aborted, how should the peer transport entities that were using it work together to re-establish it? If splitting isn't going to be used, how can re-establishment happen so that one and only one network connection results? ๐ญ
The Class 4 transport spec lets a transport entity multiplex several transport connections (TCs) over one network connection (NC), and split one TC across several NCs. The implementor has to decide whether to support these options and, if so, how ๐ Even if the implementor decides never to start splitting or multiplexing, the transport entity still has to be ready to accept that behavior from other transport implementations, no exceptions ๐ซถ When multiplexing is in use, TPDUs from multiple TCs can get concatenated into a single network service data unit (NSDU). So damage to one NSDU can affect several TCs at once ๐ In general, Class 2 connections should not be multiplexed with Class 4 connections. The reason is that if the error rate on the network connection is high enough that Class 4's error recovery is needed, then it's too high for Class 2 operation ๐ฅ The deciding criterion is how much the user can tolerate frequent disconnections and data errors.
Several issues in splitting have to be considered:
- The maximum number of NCs that can be assigned to a given TC.
- The minimum number of NCs a TC needs to keep the "quality of service" it expects (default of 1).
- When to split.
- Inactivity control.
- Assignment of received TPDUs to a TC.
- Notifying the TC of NC status (assigned, dissociated, etc).
All of these except number 3 are covered in the formal description. The methods in the formal description don't have to be used explicitly, but they do suggest approaches for implementation โจ
To support multiplexing and splitting, the implementor has to provide a common function below the TC state machines that maps a set of TCs to a set of NCs. The formal description gives a general way of doing this, and mostly just needs implementation environment details filled in to finish the mechanism ๐ Decisions about when network connections get opened or closed can be made locally, using local decision criteria. Factors that might affect the decision include the cost of establishing an NC, the cost of keeping an open NC with little traffic flowing, and estimates of how likely data flow is between the source node and known destinations. This kind of management is doable when you have a priori knowledge, but it's really hard when you need to adapt to dynamic traffic patterns and/or fluctuating network charging mechanisms ๐ฉ
To handle re-establishing the NC after a failure, ISO has proposed an addendum, N3279 [ISO85c], to the basic transport standard. It describes a network connection management subprotocol (NCMS) to be used together with the transport protocol ๐
7. Enhanced checksum algorithm โจ
7.1. Effect of checksum on transport performance.
Performance experiments with Class 4 transport at the NBS revealed that a straightforward implementation of the Fletcher checksum, using the algorithm recommended in the ISO transport standard, leads to a severe reduction in transport throughput ๐ญ Early modeling showed throughput drops of as much as 66% when using the checksum. Then Anastase Nakassis [NAK85] of the NBS did some work that led to several improved implementations ๐ฆ With those improved implementations, the performance degradation due to the checksum is now in the range of 40-55%.
It's possible that transport gets used over a network that doesn't provide error detection. In that case, the transport checksum is necessary to keep data integrity intact ๐ซถ In lots of cases though, the underlying subnetwork already has some error checking going on. The HDLC frame check sequence used by X.25, IEEE 802.3 and 802.4 relies on a 32 bit cyclic redundancy check, and satellite link hardware often provides the HDLC frame check sequence too ๐ฐ๏ธ But these are all link or physical layer error detection mechanisms, and they only work point-to-point, not end-to-end like the transport checksum does ๐ Some links provide error recovery, while other links just discard damaged messages. If adequate error recovery is already provided, then the transport checksum is extra overhead. That's because transport will notice when the link mechanism has discarded a message, and it'll retransmit the message ๐ Even when IP fragments the TPDU, the receiving IP will find a hole in the reassembly buffer and throw out the partially assembled datagram (aka the TPDU). Transport will notice that TPDU is missing and recover through the retransmission mechanism ๐ง
7.2. Enhanced algorithm.
The Fletcher checksum algorithm given in an annex to IS 8073 is not part of the standard. It's included in the annex as a suggestion for implementors ๐ This was done so that as improvements or new algorithms came along, they could be added without having to change the standard. Honestly, that's such a smart move ๐
okay so Nakassis gave us three ways to code this algorithm ๐ . The idea is to give implementors insight, not one magic copy-paste blob ๐ง. Version one is in a high order language (C) ๐. Version two mixes C with VAX assembler ๐ธ. Version three is pure VAX assembler ๐ฆ.
Every version uses a constant called MODX โจ. It's the maximum number of sums you can take before overflow happens ๐ญ. The value depends on the processor's word size and the arithmetic mode, like this:
Choose n such that
(n+1)*(254 + 255*n/2) <= 2**N - 1
Here N is the number of usable bits for signed (unsigned) arithmetic. Nakassis shows [NAK85] that it's sufficient to take
n <= sqrt( 2*(2**N - 1)/255 )
and that n = sqrt( 2*(2**N - 1)/255 ) - 2 generally yields usable values. So MODX is taken to be n. ๐
Some typical values for MODX are in this table, bestie ๐:
BITS/WORD MODX ARITHMETIC
15 14 signed
16 21 unsigned
31 4102 signed
32 5802 unsigned
This constant is used to reduce the number of times mod 255 addition is invoked, which is how it speeds the algorithm up โก.
It should be noted that the checksum can also be done in separate hardware ๐ง. But the checksum lives in the TPDU header instead of at the end, so building it with registers and an adder needs a LOT of extra logic ๐ฉ. That logic has to access and process each octet of the TPDU and move the checksum octets into the right positions ๐. An alternative is a fast, microcoded 8-bit CPU that handles that access and the computation ๐. There's some speed penalty compared to separate logic, but you can save on chip count and development time ๐ซถ.
7.2.1. C language algorithm ๐
#define MODX 4102
encodecc( mess,len,k )
unsigned char mess[] ; /* the TPDU to be checksummed */
int len,
k; /* position of first checksum octet
as an offset from mess[0] */
{ int ip,
iq,
ir,
c0,
c1;
unsigned char *p,*p1,*p2,*p3 ;
p = mess ; p3 = mess + len ;
if ( k > 0) { mess[k-1] = 0x00 ; mess[k] = 0x00 ; }
/* insert zeros for checksum octets */
c0 = 0 ; c1 = 0 ; p1 = mess ;
while (p1 < p3) /* outer sum accumulation loop */
{
p2 = p1 + MODX ; if (p2 > p3) p2 = p3 ;
for (p = p1 ; p < p2 ; p++) /* inner sum accumulation loop */
{ c0 = c0 + (*p) ; c1 = c1 + c0 ;
}
c0 = c0%255 ; c1 = c1%255 ; p1 = p2 ;
/* adjust accumulated sums to mod 255 */
}
ip = (c1 << 8) + c0 ; /* concatenate c1 and c0 */
if (k > 0)
{ /* compute and insert checksum octets */
iq = ((len-k)*c0 - c1)%255 ; if (iq <= 0) iq = iq + 255 ;
mess[k-1] = iq ;
ir = (510 - c0 - iq) ;
if (ir > 255) ir = ir - 255 ; mess[k] = ir ;
}
return(ip) ;
}
7.2.2. C/assembler algorithm ๐ท
#include <math>
encodecm(mess,len,k)
unsigned char *mess ;
int len,k ;
{
int i,ip,c0,c1 ;
if (k > 0) { mess[k-1] = 0x00 ; mess[k] = 0x00 ; }
ip = optm1(mess,len,&c0,&c1) ;
if (k > 0)
{ i = ( (len-k)*c0 - c1)%255 ; if (i <= 0) i = i + 255 ;
mess[k-1] = i ;
i = (510 - c0 - i) ; if (i > 255) i = i - 255 ;
mess[k] = i ;
}
return(ip) ;
}
; calling sequence optm(message,length,&c0,&c1) where
; message is an array of bytes
; length is the length of the array
; &c0 and &c1 are the addresses of the counters to hold the
; remainder of; the first and second order partial sums
; mod(255).
.ENTRY optm1,^M<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
movl 4(ap),r8 ; r8---> message
movl 8(ap),r9 ; r9=length
clrq r4 ; r5=r4=0
clrq r6 ; r7=r6=0
clrl r3 ; clear high order bytes of r3
movl #255,r10 ; r10 holds the value 255
movl #4102,r11 ; r11= MODX
xloop: movl r11,r7 ; if r7=MODX
cmpl r9,r7 ; is r9>=r7 ?
bgeq yloop ; if yes, go and execute the inner
; loop MODX times.
movl r9,r7 ; otherwise set r7, the inner loop
; counter,
yloop: movb (r8)+,r3 ;
addl2 r3,r4 ; sum1=sum1+byte
addl2 r4,r6 ; sum2=sum2+sum1
sobgtr r7,yloop ; while r7>0 return to iloop
; for mod 255 addition
ediv r10,r6,r0,r6 ; r6=remainder
ediv r10,r4,r0,r4 ;
subl2 r11,r9 ; adjust r9
bgtr xloop ; go for another loop if necessary
movl r4,@12(ap) ; first argument
movl r6,@16(ap) ; second argument
ashl #8,r6,r0 ;
addl2 r4,r0 ;
ret
7.2.3. Assembler algorithm ๐ฆ
buff0: .blkb 3 ; allocate 3 bytes so that aloop is
; optimally aligned
; macro implementation of Fletcher's algorithm.
; calling sequence ip=encodemm(message,length,k) where
; message is an array of bytes
; length is the length of the array
; k is the location of the check octets if >0,
; an indication not to encode if 0.
;
movl 4(ap),r8 ; r8---> message
movl 8(ap),r9 ; r9=length
clrq r4 ; r5=r4=0
clrq r6 ; r7=r6=0
clrl r3 ; clear high order bytes of r3
movl #255,r10 ; r10 holds the value 255
movl 12(ap),r2 ; r2=k
bleq bloop ; if r2<=0, we do not encode
subl3 r2,r9,r11 ; set r11=L-k
addl2 r8,r2 ; r2---> octet k+1
clrb (r2) ; clear check octet k+1
clrb -(r2) ; clear check octet k, r2---> octet k.
bloop: movw #4102,r7 ; set r7 (inner loop counter) = to MODX
cmpl r9,r7 ; if r9>=MODX, then go directly to adjust r9
bgeq aloop ; and execute the inner loop MODX times.
movl r9,r7 ; otherwise set r7, the inner loop counter,
; equal to r9, the number of the
; unprocessed characters
aloop: movb (r8)+,r3 ;
addl2 r3,r4 ; c0=c0+byte
addl2 r4,r6 ; sum2=sum2+sum1
sobgtr r7,aloop ; while r7>0 return to iloop
; for mod 255 addition
ediv r10,r6,r0,r6 ; r6=remainder
ediv r10,r4,r0,r4 ;
subl2 #4102,r9 ;
bgtr bloop ; go for another loop if necessary
ashl #8,r6,r0 ; r0=256*r6
addl2 r4,r0 ; r0=256*r6+r4
cmpl r2,r7 ; since r7=0, we are checking if r2 is
bleq exit ; zero or less: if yes we bypass
; the encoding.
movl r6,r8 ; r8=c1
mull3 r11,r4,r6 ; r6=(L-k)*c0
ediv r10,r6,r7,r6 ; r6 = (L-k)*c0 mod(255)
subl2 r8,r6 ; r6= ((L-k)*c0)%255 -c1 and if negative,
bgtr byte1 ; we must
addl2 r10,r6 ; add 255
byte1: movb r6,(r2)+ ; save the octet and let r2---> octet k+1
addl2 r6,r4 ; r4=r4+r6=(x+c0)
subl3 r4,r10,r4 ; r4=255-(x+c0)
bgtr byte2 ; if >0 r4=octet (k+1)
addl2 r10,r4 ; r4=255+r4
byte2: movb r4,(r2) ; save y in octet k+1
exit: ret
8. Parameter selection โจ
8.1. Connection control ๐
Expressions for timer values that control general transport connection behavior are given in IS 8073 ๐ฐ๏ธ. But the values for the specific factors in those expressions aren't given, and the expressions are only estimates ๐คทโโ๏ธ. Deriving timer values from these expressions is not mandatory in the standard. These expressions are for a connection-oriented network service, so they may not apply to a connectionless network service ๐ซ .
The following symbols denote the factors that contribute to timer values, for the rest of this Part ๐ง :
Elr = expected maximum transit delay, local to remote
Erl = expected maximum transit delay, remote to local
Ar = time needed by remote entity to generate an acknowledgement
Al = time needed by local entity to generate an acknowledgement
x = local processing time for an incoming TPDU
Mlr = maximum NSDU lifetime, local to remote
Mrl = maximum NSDU lifetime, remote to local
T1 = bound for maximum time local entity will wait for
acknowledgement before retransmitting a TPDU
R = bound for maximum local entity will continue to transmit a
TPDU that requires acknowledgment
N = bound for maximum number of times local entity will transmit
a TPDU requiring acknowledgement
L = bound for the maximum time between the transmission of a
TPDU and the receipt of any acknowledgment relating to it.
I = bound for the time after which an entity will initiate
procedures to terminate a transport connection if a TPDU is
not received from the peer entity
W = bound for the maximum time an entity will wait before
transmitting up-to-date window information
These symbols and their definitions match the ones in Clause 12 of IS 8073 ๐.
8.1.1. Give-up timer โณ
The give-up timer decides how long the transport entity keeps waiting for an acknowledgement (or other appropriate reply) to a transmitted message ๐ฅบ. That's after the message has already been retransmitted the maximum number of times. IS 8073 recommends values for this timer expressed by:
T1 + W + Mrl, for DT and ED TPDUs
T1 + Mrl, for CR, CC, and DR TPDUs,
where:
T1 = Elr + Erl + Ar + x.
Okay, real talk: Ar won't be known for either the CR or the CC TPDU ๐ฉ. Also, Elr and Erl can vary a LOT because of routing in some connectionless network services ๐. More on T1 in Part 8.3.1, which goes deeper into it ๐. Mrl is usually pretty fixed for a given network service ๐งฑ, and since Mrl is usually way bigger than the expected values of T1, a rule-of-thumb for the give-up timer is2*Mrl + Al + xfor the CR, CC and DR TPDUs, and2*Mrl + Wfor DT and ED TPDUs ๐ .
8.1.2. Inactivity timer ๐ค
This timer measures the maximum time period during which a transport connection can be inactive ๐ด. In other words, it's the longest an entity can wait without receiving incoming messages. A usable value for the inactivity timer is:
I = 2*( max( T1,W )*N ).
This accounts for the possibility that the remote peer is using a window timer value that's different from the local peer's ๐ช. Also, an inactivity timer is important for operation over connectionless network services, because the periodic receipt of AK TPDUs is the only way the local entity can be certain its peer is still functioning ๐ซถ.
8.1.3. Window timer โฐ
The window timer has two jobs, bestie ๐. First, it makes sure the remote peer periodically gets the current state of the local entity's flow control. Second, it lets the remote peer know the local entity is still alive โจ. The first job puts an upper bound on how long it takes to resync flow control if an AK TPDU that announces new credit gets lost. The second job stops the remote peer's inactivity timer from expiring ๐. How big W should be depends on the transit delay, the acknowledgement strategy, and the chance of TPDU loss in the network. Generally, W should satisfy this condition:
W > C*(Erl + x)
The logic is that the right-hand side is the longest time it could take to receive the whole window ๐ง . The protocol requires that all received data be acknowledged once the upper edge of the window shows up as a sequence number in a received DT TPDU. The window timer gets reset every time an AK TPDU goes out, so there's usually no reason to set it any lower than the right-hand side. The exception is when both C and the maximum TPDU size are large and Erl is large too ๐.
When the odds of a TPDU getting lost are low, W can be pretty big, like several minutes ๐ธ. The catch is that the peer takes longer to notice when the local transport entity has been deactivated. So you should think about how fast the peer needs to detect inactivity when picking W. One way to handle that is to put this info into a quality of service record tied to the peer's address ๐ .
When the expected network error rate is high, you may need to lower W so AK TPDUs keep arriving at the remote entity, especially when both entities are quiet for a while ๐ฆ.
8.1.4. Reference timer ๐ง
The reference timer tracks how long a source reference has to wait before it can be given to a different transport connection. The point is so spurious duplicate messages can't mess with a new connection ๐ญ. The value for this timer in IS 8073 is:
L = Mlr + Mrl + R + Ar
where:
R = T1*N + z
z is a small tolerance quantity that covers factors internal to the entity. Using L as a bound takes some care, though ๐. Sometimes L can be super large and not realistic as either an upper or lower bound. That can happen on routes across several catenated networks, where R is set high to recover well from TPDU loss. Other times L can be really small, like when transmission runs over a LAN and R is set low because TPDU loss is unlikely ๐. If L comes out very small, the reference doesn't need timing out at all, since the chance of interference is zero. And if L comes out very large, a smaller value can be used instead ๐.
One choice for the value might be:
L = min( R,(Mrl + Mlr)/2 )
If an entity assigns reference numbers to new connections by incrementing them monotonically through the whole available reference space (maximum 2**16 - 1), the timer isn't critical ๐ฅ. The sequence space is big enough that spurious messages are unlikely to still be in the network by the time reference numbers get reused.
8.2. Flow control ๐
Peer-to-peer flow control in the transport protocol sets the upper bound on how fast data moves across transport connections ๐. The transport entity at each end of a connection offers its peer a credit, which is how many data messages it's currently willing to accept ๐ซถ. Every received data message gets acknowledged, and each acknowledgement carries the current receive credit information. The three credit allocation schemes below are different examples of how receive credit values can be worked out ๐.
8.2.1. Pessimistic credit allocation ๐ฃ
Pessimistic credit allocation is probably the simplest form of flow control, and it's kind of like X-on/X-off control โจ. Here, the receiver always offers a credit of one TPDU. When a DT TPDU arrives, the receiver replies with an AK TPDU carrying a credit of zero. Once the receiving entity has processed the DT TPDU, it sends another AK TPDU carrying a credit of one. The upside is that the receiving entity keeps the data exchange tightly controlled ๐. The downsides are: 1) the exchange is slow, since every data message needs at least the time of two round trips to finish the transfer, and 2) the ratio of acknowledgement messages to data messages sent is 2:1. It's not recommended, but it shows one extreme way to do credit allocation ๐ญ.
8.2.2. Optimistic credit allocation ๐ข
Optimistic credit allocation sits at the opposite extreme from pessimistic. The receiver offers more credit than it has buffers for ๐ฌ. This approach has two dangers. The first: if the receiving user isn't accepting data fast enough, the receiving transport's buffers fill up. Since the credit offered was optimistic, the sender keeps transmitting, and the receiving entity has to drop that data for lack of buffers. Eventually the sender might hit the maximum number of retransmissions and terminate the connection ๐.
The second danger is that the sender may transmit faster than the receiver can consume. That could happen if the sender runs on a faster machine or has a more efficient implementation ๐๏ธ. The result is basically the same as above: receive buffer saturation, dropped data messages, and connection termination ๐ฅฒ.
The credit reduction scheme in the protocol can soften both of these dangers. Still, optimistic credit allocation only works well in limited circumstances. In most situations it's inappropriate and inefficient, even with credit reduction ๐ โโ๏ธ. Instead of avoiding congestion, optimistic allocation usually causes it, and credit reduction just helps you recover once congestion has already happened ๐ช๏ธ. Also, optimistic credit allocation combined with caching out-of-sequence messages needs a sophisticated buffer management scheme to avoid reassembly deadlock and the loss of the transport connection that follows ๐งจ.
8.2.3. Buffer-based credit allocation ๐งบ
Basing the receive credit on how many receive buffers are actually available is a better way to do flow control ๐. With few exceptions, the implementations that have been studied used this method. It supports a continuous flow of data and gets rid of the need for credit-restoring acknowledgements โจ. Since only available buffer space gets offered, the dangers of optimistic credit allocation are avoided too ๐ซง.
The buffer space needed to keep a continuous bulk data transfer going is the maximum buffer requirement, and it depends on the round trip delay and the network speed ๐. Generally, you'd want the buffer space, and therefore the credit, big enough for the sender to keep sending non-stop, so that incremental credit updates show up just before the sender runs out of credit ๐โโ๏ธ. One example is a single-hop satellite link running at 1.544 Mbits/sec. One report [COL85] says the buffer requirement for continuous flow is about 120 Kbytes ๐ฐ๏ธ. For 10 Mbits/sec. IEEE 802.3 and 802.4 LANs, the figure is roughly 10K to 15K bytes [BRI85, INT85, MIL85] ๐.
R.K. Jain [JAI85] suggested an interesting twist on buffer-based credit allocation ๐ง . The approach above relies strictly on available buffer space, but Jain proposes that the sending entity voluntarily reduce its credit when it detects network congestion ๐ซถ. Congestion is implied when retransmissions happen. The sender notices the retransmissions and drops its local credit value to one, then slowly raises it back toward the actual receive credit allocation as error-free transmissions continue ๐. This technique can handle various kinds of network congestion, like when a fast sender overruns a slow receiver and no link level flow control is available ๐ฆ.
8.2.4. Acknowledgement policies ๐
First, let's review the four uses of the acknowledgement message in Class 4 transport. An acknowledgement message:
- confirms correct receipt of data messages,
- contains a credit allocation, indicating how many data messages the entity is willing to receive from the correspondent entity,
- may optionally contain fields which confirm receipt of critical acknowledgement messages, known as flow control confirmation (FCC), and
- is sent upon expiration of the window timer to maintain a minimum level of traffic on an otherwise quiescent connection.
When picking an acknowledgement strategy, the first and third uses (data confirmation and FCC) matter most ๐ฏ. The second one, credit allocation, depends on whichever flow control strategy you chose. The fourth, the window acknowledgement, only gets a brief mention in the flow control confirmation discussion ๐.
8.2.4.1. Acknowledgement of data ๐ฌ
The main job of the acknowledgement message is confirming correct receipt of data messages โ . The implementor has to make several choices when designing a specific implementation ๐ ๏ธ. Which choice to make depends mostly on the operating environment, like network error characteristics ๐ฆ๏ธ. The issues to decide on are covered in the sections below ๐.
8.2.4.1.1. Misordered data messages ๐
Data messages that arrive out of order, because of network misordering or loss, can either be cached or discarded ๐๏ธ. No single factor pushes the implementor one way or the other. Instead, there are a bunch of issues to weigh ๐งฉ.
One issue is keeping the delay the user perceives as low ๐ข. If transport data messages get lost or damaged in transit, the missing positive acknowledgement triggers a retransmission at the sending entity ๐. When the retransmitted data message reaches the receiving transport, it can be delivered to the user. If the later data messages were cached, they can all be delivered to the user at the same time ๐. On average, the delay between the sending and receiving users would be shorter than if messages after a lost message had to wait on retransmission to recover ๐จ. Okay so this is where we pick up, the story keeps going, and babe, I'm not done yet ๐
A second thing that decides whether to cache is the cost of transmission. โจ If transmission is expensive, it's more economical to cache misordered data and pair that with selective acknowledgement (more on that below) so you avoid retransmissions. ๐ธ
Not caching misordered data saves two things: design and implementation time for the transport entity, and CPU processing time while it runs. ๐ง A non-caching implementation has simpler buffer management. Data TPDUs just get discarded instead of reordered. That skips the overhead of tracking gaps in the received data sequence space, searching sequenced message lists, and inserting retransmitted data messages into those lists. Less drama, more vibes. ๐ซถ
8.2.4.1.2. Nth acknowledgement โจ
Generally, an acknowledgement message is sent after receipt of every N data messages on a connection. ๐ If N is small compared to the credit offered, the data sender's buffer management function gets finer-grained buffer control. Data messages get confirmed in small groups, so buffers can be reused sooner than if N were bigger. ๐ฆ
Having N small comes with a twofold cost. First, more acknowledgement messages have to be generated by one transport entity and processed by the other, which eats into the CPU at both ends of the connection. Second, the acknowledgement messages use up transmission bandwidth, which MAY be expensive or limited. ๐ฅฒ
For larger N, buffer management gets less efficient, because the granularity of buffer control becomes N times the maximum TPDU size. ๐ For example, when a receiving entity uses this strategy with a large N, N data messages MUST be sent before an acknowledgement comes back. (The window timer still makes the acknowledgement go out eventually, no matter what N is.) If the minimum credit allocation for continuous operation is only a fraction of N, a credit of N MUST still be offered, and N receive buffers reserved, to keep data messages flowing continuously. So more receive buffers get used than are actually needed. ๐ญ (Alternatively, if you rely on the timer, which MUST be adjusted to the receipt time for N, it won't expire until some time after that fraction of N has been sent, so there MAY be idle time.)
Choosing N depends on a few things. First, if DT TPDUs are arriving at a relatively low rate, there's not much justification for an N bigger than 2. ๐ธ On the other hand, if the DT TPDU arrival rate is high, or the TPDUs arrive in large groups (like a frame from a satellite link), it MAY be reasonable to pick a larger N, just to skip the overhead of generating and sending acknowledgements while processing DT TPDUs. โญ
Second, N SHOULD be related to the maximum credit you're offering. If C is the maximum credit to be offered, one SHOULD choose N < C/2, since receiving C TPDUs without acknowledging will trigger an acknowledgement anyway. ๐ But the extended formats option for transport gives max C = 2**16 - 1, so picking N = 2**15 - 2 is likely to make some of the sender's retransmission timers expire. The retransmitted TPDUs then arrive out of sequence, which triggers AK TPDUs to be sent. ๐ Net result: not much is gained by making N large. A better choice is N = log C (base 2). ๐
Third, the value of N SHOULD be related to the maximum TPDU size used on the connection and to the overall buffer management. ๐งฉ For example, buffer management MAY be tied to the largest TPDU any connection will use, with each connection working out how its negotiated TPDU size fits into that buffer size. In that case, if a connection negotiated a maximum TPDU size of 128 octets and the buffers are 2048 octets, it MAY provide better management to partially fill a buffer before acknowledging. ๐ If the example connection has two buffers and based its offered credit on that, one choice for N could be 2*log( 2048/128 ) = 8. That means an AK TPDU gets sent when a buffer is half filled (2048/128 = 16), and a double buffering scheme manages the two buffers. ๐
Two studies indicate that, in many cases, 2 is a good choice for N [COL85, BRI85]. โจ The extra granularity in buffer management is reasonably small compared to the credit allocation, which ranges from 8K to 120K octets in the cited studies. The payoff is that the number of acknowledgements generated (and consumed) gets cut roughly in half. ๐ฅณ
8.2.4.1.3. Selective acknowledgement
Selective acknowledgement is an option that lets misordered data messages get confirmed even when there are gaps in the received message sequence. ๐ฆ (Heads up: selective acknowledgement is only meaningful when you're caching out-of-order data messages. ๐) The big win is that it greatly reduces the number of unnecessary retransmissions, which saves both computing time and transmission bandwidth [COL85] (see the discussion in Part 8.2.4.1.1 for more details). ๐
8.2.4.2. Flow control confirmation and fast retransmission
Flow control confirmation (FCC) is a transport protocol mechanism where acknowledgement messages carrying critical flow control information get confirmed. ๐ฅ The critical acknowledgement messages are the ones that open a closed flow control window, plus certain ones that come after a credit reduction. In principle, if those critical messages get lost, the flow control resynchronization relies on the window timer, which is usually pretty long. ๐ด To speed up resynchronization, the receiving entity can repeatedly send AK TPDUs within short intervals, each carrying a request for confirmation of the flow control state. This is known as "fast" retransmission (of the acknowledgement). ๐โโ๏ธ If the sender responds with an AK TPDU carrying an FCC parameter, fast retransmission stops. If no AK TPDU carrying the FCC parameter comes back, fast transmission halts after hitting a maximum number of retransmissions, and the window timer takes over control of AK TPDU transmission again. ๐ Also, FCC is OPTIONAL as a transport mechanism, and the data sender is NOT REQUIRED to respond to a request for confirmation of the flow control state with an AK TPDU carrying the FCC parameter. ๐ซง
Some things to weigh when deciding whether to use FCC and fast retransmission procedures:
- likelihood of credit reduction on a given transport connection;
- probability of TPDU loss;
- expected window timer period;
- window size; and
- acknowledgement strategy.
Honestly? There's no reported experience with using FCC and fast retransmission yet. ๐ So it's not known whether these procedures reduce resynchronization delay enough to be worth implementing. ๐คทโโ๏ธ
When implementing fast retransmission, it's suggested that the timer used for the window timer also be used as the fast timer, since the window is disabled during fast retransmission anyway. ๐ก That way you don't have to manage another timer. The formal description treats the fast retransmission timer as a separate timer, just for clarity. ๐ง
8.2.4.3. Concatenation of acknowledgement and data
When two transport entities run full duplex communication, data and acknowledgement TPDUs from each entity travel in the same direction. ๐ The transport protocol lets you concatenate AK TPDUs into the same NSDU as a DT TPDU. The upside is that fewer NSDUs get sent, so fewer total octets go out, thanks to fewer network headers being transmitted. โจ However, when operating over IP, that advantage MAY not necessarily be realized, because IP might fragment the NSDU. ๐ฌ A careful analysis of how NSDUs are handled in internetwork environments SHOULD be done to figure out whether concatenating TPDUs is worth it in that situation. ๐ง
8.2.5. Retransmission policies
There are primarily two retransmission policies you can use in a transport implementation. ๐ In the first, a separate retransmission timer gets started for each data message the transport entity sends. At first glance it looks simple and straightforward to implement, but it's inefficient, and here's why. ๐ค First, every data message needs a timer started and cancelled, which eats a significant chunk of CPU time [BRI85]. Second, as the list of outstanding timers grows, managing that list gets more and more expensive. ๐ There are techniques that make list management more efficient, like a list per connection, or hashing. But using one retransmission timer per transport connection is the superior choice. ๐
The second policy, one retransmission timer for each transport connection, dodges some of those inefficiencies. The list of outstanding timers is shorter by roughly an order of magnitude. ๐ฅ However, if the receiving entity is generating an acknowledgement for every data message, the timer still has to be cancelled and restarted for each data/acknowledgement message pair. (This is an extra reason to go with an Nth acknowledgement policy with N=2. ๐)
The rules for the single-timer-per-connection scheme are listed below. ๐
- If a data message is transmitted and the retransmission timer for the connection is not already running, the timer is started.
- If an acknowledgement for previously unacknowledged data is received, the retransmission timer is restarted.
- If an acknowledgement message is received for the last outstanding data message on the connection, then the timer is cancelled.
- If the retransmission timer expires, one or more unacknowledged data messages are retransmitted, beginning with the one sent earliest. (Two reports [HEA85, BRI85] suggest that the number to retransmit is one. ๐)
8.3. Protocol control
8.3.1. Retransmission timer values
8.3.1.1. Data retransmission timer
The value for the reference timer MAY have a significant impact on the performance of the transport protocol [COL85]. ๐ฏ Figuring out the proper value can be tricky, though. ๐ฅบ According to IS 8073, the timer value is computed using the transit delays Erl and Elr, the acknowledgement delay Ar, and the local TPDU processing time x:
T1 = Erl + Elr + Ar + x
The timer is the tricky part, bestie, because it depends on a bunch of factors that all move around. Of those, Erl and Elr are the wiggliest ๐ข, so they have the biggest say in what a good timer value looks like. The next few paragraphs walk through how to pick a retransmission timer in a few different network environments ๐ง
In a single-hop satellite environment, network delay (Erl or Elr) barely varies, because the propagation delay is a steady 270 ms or so and it totally overshadows everything else in the network delay. So a fixed retransmission timer works great here ๐ For example, a 64K bit/sec. link with a network queue size of four does well with a 650 ms. timer [COL85].
Local area networks have constant propagation delay too, but ngl it barely matters there ๐ The real drama is medium access delay and queuing delay, and (Ar + x) also plays a big role in picking the timer. From the discussion in Part 3.4.3.2, typical numbers for (Ar + x) are on the order of 5 - 6.5 ms, and for Erl or Elr they're 5 - 35 ms. So a reasonable retransmission timer is 100 ms ๐ One cited report [INT85] says this works well for local area networks, and simulation work done at the NBS agrees ๐ซถ
For better performance in an environment with long propagation delays and a lot of variance, like an internetwork, an adaptive algorithm is the move ๐ฆ The one suggested for TCP/IP [ISI81] is the go-to. As analyzed by Jain [JAI85], the algorithm uses exponential averaging to come up with a round trip delay estimate:
D(i) = b * D(i-1) + (1-b) * S(i)
Here, D(i) is the updated delay estimate, S(i) is the sample round trip time measured between sending a given packet and getting its acknowledgement back, and b is a weighting factor between 0 and 1, usually 0.5 โญ The retransmission timer is some multiplier, k, of D. Small values of k catch lost packets quickly, but you get more false timeouts and, therefore, unnecessary retransmissions ๐ On top of that, the retransmission timer should go up arbitrarily for each case of multiple transmissions. An exponential increase is suggested, like this:
D(i) = c * D(i-1)
where c is a dimensionless parameter greater than one ๐
The last parameter for the adaptive algorithm is the initial delay estimate, D(0). It's better to pick a slightly bigger value than you need, so that unnecessary retransmissions don't happen right at the beginning ๐ One option is to measure the round trip delay during connection establishment. Either way, the timer converges, except when there's sustained congestion ๐ญ
8.3.1.2 Expedited data retransmission timer. โจ
The timer that governs retransmission of expedited data should be set using the normal data retransmission timer value ๐
8.3.1.3 Connect-request/confirm retransmission timer. ๐ฆ
Connect request and confirm messages are subject to Erl + Elr, the total network delay, plus the processing time at the receiving transport entity, if those values are known ๐ If you don't have an accurate estimate of the round trip time, there are two ways to think about this timer. First, since this timer governs connection establishment, you want to keep delay low, so a small value can be chosen, which might cause unnecessary retransmissions ๐โโ๏ธ Or you can go bigger, which cuts down on unnecessary retransmissions but means a longer wait for connection establishment if the connect request or confirm message gets lost ๐ญ Which one you pick is mostly up to your local requirements ๐
8.3.1.4 Disconnect-request retransmission timer. ๐ธ
The timer that governs retransmission of the disconnect request message should be set from the normal data retransmission timer value ๐ซถ
8.3.1.5 Fast retransmission timer. โก
The fast retransmission timer makes sure critical acknowledgement messages get retransmitted, so credit resynchronization doesn't get delayed ๐ This timer should be set to approximately Erl + Elr ๐ฅ
8.3.2 Maximum number of retransmissions. ๐
This transport parameter sets the maximum number of times a data message will be retransmitted. A typical value is eight ๐ If you monitor the network service, you can adjust this value based on the error rates you observe ๐ A high error rate means a high probability of TPDU loss. So when you still want to keep sending even though the quality of service has dropped, the number of TPDU retransmissions (N) should be increased and the retransmission interval (T1) reduced ๐
8.4 Selection of maximum Transport Protocol data unit size. ๐
The maximum TPDU size you put in negotiation proposals depends on the application you're serving and the service quality of the network underneath ๐ In general, an application that produces large TSDUs should use the biggest TPDUs it can negotiate, so there's less overhead from tons of small TPDUs ๐ An application that produces small TSDUs shouldn't be bothered by a large maximum TPDU size, since a TPDU doesn't have to be filled up to the max to get sent ๐ง So file transfers would want larger TPDUs, while terminals wouldn't really care ๐ On a high bandwidth network service, large TPDUs give better channel utilization than smaller ones ๐ But when error rates are high, the chance that a given TPDU gets damaged is tied to its size and how often TPDUs are sent. So a smaller TPDU size during high error rates gives a smaller probability that any particular TPDU will be lost ๐ซถ
The implementor has to choose whether or not to use one uniform maximum TPDU size for all connections ๐ค If the network service is uniform in quality, picking one uniform maximum can simplify the implementation โจ But if the network quality isn't uniform, and you want to optimize the service for the transport user as much as possible, then it may be better to figure out the maximum size on each individual connection ๐ You can do that at the time of the network service access, as long as the characteristics of the subnetwork are known ๐ฆ
NOTE: The maximum TPDU size matters in the calculation of flow control credit, which is in numbers of TPDUs offered. If buffer space is granted on an octet base, then credit must be granted as buffer space divided by maximum TPDU size. Using a smaller TPDU size can be equivalent to optimistic credit allocation, and can lead to the expected problems if proper analysis of the management is not done ๐
9 Special options. ๐
Special options can be obtained by taking advantage of the way IS 8073 and N3756 were written ๐งฉ It has to be emphasized that these options in no way violate the intentions of the standards bodies that produced the standards. Flexibility was deliberately written into the standards so they don't constrain applicability to a wide variety of situations ๐ธ
9.1 Negotiations. ๐ค
The negotiation procedures in IS 8073 have deliberate ambiguities so there's flexibility of usage within closed groups of communicants. The standard only defines behavior among open communicants ๐ A closed group of communicants in an open system is one that, because of its organization, security, or other special needs, carries on certain communication among its members that isn't of interest to, or isn't accessible to, other open system members ๐ Some examples of closed groups within DOD might be: an Air Force Command, such as the SAC; a Navy base or an Army post; a ship; Defense Intelligence; or the Joint Chiefs of Staff ๐ซก Using this characteristic isn't standard behavior, but it doesn't violate conformance to the standard, since the effects of this usage aren't visible to non-members of the closed group ๐ Using the procedures this way lets you have options the standard doesn't provide. For example, these options might let you carry special protection codes on protocol data units, or identify DT TPDUs as carrying a particular kind of message ๐
Standard negotiation procedures say that any parameter in a received CR TPDU that isn't defined by the standard shall be ignored ๐ This only defines the behavior that should be shown between two open systems. It doesn't say that an implementation that recognizes such non-standard parameters shall not be operated in networks supporting open systems interconnection ๐ Also, any other type of TPDU containing non-standard parameters is to be treated as a protocol error when it's received. The presumption here is that the non-standard parameter isn't recognized, since it hasn't been defined ๐ง Now let's look at this example, bestie:
Entity A sends Entity B a CR TPDU containing a non-standard parameter.
Entity B has been implemented to recognize the non-standard parameter, and it reads the parameter's presence as meaning that Entity A will be sending DT TPDUs to Entity B with a special protection identifier parameter included ๐
Entity B sends a CC TPDU containing the non-standard parameter to show Entity A that it received and understood the parameter, and that it's ready to receive the specially marked DT TPDUs from Entity A ๐ซถ Since Entity A originally sent the non-standard parameter, it recognizes the parameter in the CC TPDU and doesn't treat it as a protocol error ๐ฆ
Entity A can now send the specially marked DT TPDUs to Entity B, and Entity B won't reject them as protocol errors โจ
Note that Entity B sends a CC TPDU with the non-standard parameter only if it receives a CR TPDU containing the parameter. That way it doesn't create a protocol error for an initiating entity that doesn't use the parameter ๐ Also note that if Entity B hadn't recognized the parameter in the CR TPDU, it would have ignored it and not returned a CC TPDU containing the parameter ๐ธ This non-standard behavior is totally invisible and inaccessible to Transport entities outside the closed group that chose to implement it, since they can't tell it apart from protocol errors ๐
9.2 Recovery from peer deactivation. ๐
Transport doesn't directly support recovering the transport connection from a crashed remote transport entity ๐ญ A partial recovery is possible, given a proper interpretation of the state tables in Annex A to IS 8073 and good implementation design. The interpretation of the Class 4 state tables needed to pull this off is as follows ๐ง
Whenever a CR TPDU is received in the state OPEN, the entity is required only to record the new network connection and to reset the inactivity timer ๐ So if the initiator of the original connection is the peer that crashed, it can send a new CR TPDU to the surviving peer, somehow communicating the original reference numbers to it (there are several ways to do that) ๐ซถ
Whenever a CC TPDU is received in the
So in state OPEN, the receiver is literally only required to record the new network connection, reset the inactivity timer, and send either an AK, DT or ED TPDU ๐ . That means if the responder for the original connection is the peer that crashed, it can send a brand new CC TPDU to the surviving peer, telling it the original reference numbers ๐ซถ.
In order for this to work, the situation in a., above, needs a CC TPDU sent back. It could be the original CC TPDU, just with new reference numbers. The original initiator will have sent a new reference number in the new CR TPDU, so that goes straight into the CC TPDU coming back ๐ฆ. The responder's new reference number could just be a fresh assignment, with the old one frozen. In situation b., the originator could keep its reference number (or assign a new one if it needs to), since the CC TPDU should carry both old reference numbers and a new one for the responder (see below) โจ. Either way, only the new reference numbers need to be pulled out of the CR/CC TPDUs, since the options and parameters were already negotiated. This whole procedure obviously requires that the CR and CC TPDUs of each connection be stored by the peers in nonvolatile memory, plus the particulars of the negotiations ๐พ.
To transfer the new reference numbers, it is suggested that a new parameter be defined in the CR and CC TPDU, as in Part 9.1, above ๐. This parameter could also carry the state of data transfer, to help with resynchronizing, in the following form:
- the last DT sequence number received by the peer that crashed;
- the last DT sequence number sent by the peer that crashed;
- the credit last extended by the peer that crashed;
- the last credit perceived as offered by the surviving peer;
- the next DT sequence number the peer that crashed expects to send (this may not be the same as the last one sent, if the last one sent was never acknowledged);
- the sequence number of an unacknowledged ED TPDU, if any;
- the normal data sequence number corresponding to the transmission of an unacknowledged ED TPDU, if any (this is to ensure the proper ordering of the ED TPDU in the normal data flow);
A bunch of other things need to be considered when attempting data transfer resynchronization ๐. First, the recovery will be greatly complicated if subsequencing or flow control confirmation is in effect when the crash occurs. Careful analysis should be done to figure out whether these features give enough benefit to justify including them in a survivable system. Second, non-volatile storage of TPDUs which are unacknowledged must be used so that data loss at the time of recovery can be minimized ๐. Third, the values for the retransmission timers for the communicating peers must allow sufficient time for the recovery to be attempted. This may result in longer delays in retransmitting when TPDUs are lost under normal conditions. One way this might be achieved is for the peers to exchange their expected lower bounds for the retransmission timers during the original CR/CC TPDU exchange, following the procedure in Part 9.1. That way, the peer that crashed may determine whether or not a new connection should be attempted โฑ๏ธ. Fourth, while the recovery involves only the transport peers directly when operating over a connectionless network service, recovery when operating over a connection-oriented network service requires some sort of agreement about when a new network connection is to be established (if necessary) and which peer is responsible for doing it. This is required to make sure unnecessary network connections are not opened as a result of the recovery. Splitting network connections may help to ameliorate this problem ๐.
9.3. Selection of transport connection reference numbers โจ
In N3756, when the reference wait period for a connection begins, the resources associated with the connection are released and the reference number is placed in a set of frozen references ๐ง. A timer associated with this number is started, and when it expires, the number is removed from the set. A function which chooses reference numbers checks this set before assigning the next reference number. If you want a much longer period by using a large reference number space, you can meet that by replacing the implementation dependent function "select_local_ref" (page TPE-17 of N3756) with the following code ๐:
function select_local_ref : reference_type;
begin
last_ref := (last_ref + 1) mod( N+1 ) + 1;
while last_ref in frozen_ref[class_4] do
last_ref := (last_ref + 1) mod( N+1 ) + 1;
select_local_ref := last_ref;
end;
Here "last_ref" is a new variable to be defined in declarations (pages TPE-10 - TPE-11), used to keep track of the last reference value assigned. N is the length of the reference number cycle, which cannot exceed 2**16 - 1, since the reference number fields in TPDUs are restricted to 16 bits in length ๐ข.
9.4. Obtaining Class 2 operation from a Class 4 implementation ๐
Okay, so the operation of Class 4 as described in IS 8073 logically contains that of the Class 2 protocol ๐ง . The formal description, though, is written assuming Class 4 and Class 2 are distinct. This was done because the description has to reflect the conformance statement of IS 8073, which says Class 2 alone may be implemented.
Here's the good part, though: Class 2 operation can be obtained from a Class 4 implementation ๐คฉ. That gives you lower complexity, smaller memory requirements, and lower implementation costs compared to implementing the classes separately. The implementor will have to make the following provisions in the transport entity and the Class 4 transport machine to realize Class 2 operation:
- Disable all timers. In the formal description, all Class 4 timers except the reference timer are in the Class 4 TPM. These timers can be designed at the outset to be enabled or not when the TPM is instantiated. The reference timer lives in the Transport Entity module (TPE) and is activated by the TPE recognizing that the TPM has set its "please_kill_me" variable to "freeze". If the TPM sets this variable to "now" instead, the reference timer for that transport connection is never started. However, IS 8073 provides that the reference timer can be used, as a local entity management decision, for Class 2.
The above procedure should be used when negotiating from Class 4 to Class 2. If Class 2 is proposed as the preferred class, then it is advisable not to disable the inactivity timer, to avoid the possibility of deadlock during connection establishment if the peer entity never responds to the CR TPDU. The inactivity timer should be set when the CR TPDU is sent and deactivated when the CC TPDU is received โฐ.
- Disable checksums. This can be done simply by making sure the boolean variable "use_checksums" is always set to "false" whenever Class 2 is to be proposed or negotiated.
- Never permit flow control credit reduction. The formal description makes flow control credit management a function of the TPE operations, and that management is not reflected in the operation of the TPM. So this provision may be handled by always making the "credit-granting" mechanism aware of the class of the TPM being served ๐ฏ.
- Include Class 2 reaction to network service events. The Class 4 handling of network service events is more flexible than that of Class 2, which gives Class 4 its characteristic recovery behavior. So an option should be provided for how N_DISCONNECT_indication and N_RESET_indication are handled for Class 2 operation. This consists of sending a T_DISCONNECT_indication to the Transport User, setting "please_kill_me" to "now" (optionally to "freeze"), and transitioning to the CLOSED state, for both events. (The Class 4 action for N_DISCONNECT is to remove the network connection from the set of those associated with the transport connection, and to attempt to obtain a new network connection if the set becomes empty. The action on receipt of N_RESET is to do nothing, since the TPE has already issued the N_RESET_response.) ๐ธ
- Ensure that TPDU parameters conform to Class 2. This implies that subsequence numbers should not be used on AK TPDUs, and no flow control confirmation parameters should ever appear in an AK TPDU. The checksum parameter is kept from appearing by the "false" value of the "use_checksums" variable. (The acknowledgement time parameter in the CR and CC TPDUs will not be used, because of the negotiation procedure. No special assurance for its non-use is necessary.)
The TPE management of network connections should make sure that splitting is never attempted with Class 4 TPMs running as Class 2. The handling of multiplexing is the same for both classes, but it is not good practice to multiplex Class 4 and Class 2 together on the same network connection ๐ซ.
10. References ๐
- [BRI85] Bricker, A., L. Landweber, T. Lebeck, M. Vernon, "ISO Transport Protocol Experiments," Draft Report prepared by DLS Associates for the Mitre Corporation, October 1985.
- [COL85] Colella, Richard, Marnie Wheatley, Kevin Mills, "COMSAT/NBS Experiment Plan for Transport Protocol," NBS, Report No. NBSIR 85-3141, May l985.
- [CHK85] Chernik, C. Michael, "An NBS Host to Front End Protocol," NBSIR 85-3236, August 1985.
- [CHO85] Chong, H.Y., "Software Development and Implementation of NBS Class 4 Transport Protocol," October 1985 (available from the author).
- [HEA85] Heatley, Sharon, Richard Colella, "Experiment Plan: ISO Transport Over IEEE 802.3 Local Area Network," NBS, Draft Report (available from the authors), October 1985.
- [INT85] "Performance Comparison Between 186/51 and 552," The Intel Corporation, Reference No. COM,08, January 1985.
- [ISO84a] IS 8073 Information Processing - Open Systems Interconnection - Transport Protocol Specification, available from ISO TC97/SC6 Secretariat, ANSI, 1430 Broadway, New York, NY 10018.
- [ISO84b] IS 7498 Information Processing - Open Systems Interconnection - Basic Reference Model, available from ANSI, address above.
- [ISO85a] DP 9074 Estelle - A Formal Description Technique Based on an Extended State Transition Model, available from ISO TC97/SC21 Secretariat, ANSI, address above.
- [ISO85b] N3756 Information Processing - Open Systems Interconnection - Formal Description of IS 8073 in Estelle. (Working Draft, ISO TC97/SC6)
[ISO85c] N3279 Information Processing - Open Systems
Interconnection - DAD1, Draft Addendum to IS 8073
to Provide a Network Connection Management
Service, ISO TC97/SC6 N3279, available from
SC6 Secretariat, ANSI, address above.
[JAI85] Jain, Rajendra K., "CUTE: A Timeout Based Congestion
Control Scheme for Digitial Network Architecture,"
Digital Equipment Corporation (available from the
author), March 1985.
[LIN85] Linn, R.J., "The Features and Facilities of Estelle,"
Proceedings of the IFIP WG 6.1 Fifth International
Workshop on Protocol Specification, Testing and
Verification, North Holland Publishing, Amsterdam,
June 1985.
[MIL85a] Mills, Kevin L., Marnie Wheatley, Sharon Heatley,
"Predicting Transport Protocol Performance",
(in preparation).
[MIL85b] Mills, Kevin L., Jeff Gura, C. Michael Chernik,
"Performance Measurement of OSI Class 4 Transport
Implementations," NBSIR 85-3104, January 1985.
[NAK85] Nakassis, Anastase, "Fletcher's Error Detection
Algorithm: How to Implement It Efficiently and
How to Avoid the Most Common Pitfalls," NBS,
(in preparation).
[NBS83] "Specification of a Transport Protocol for
Computer Communications, Volume 3: Class 4
Protocol," February 1983 (available from
the National Technical Information Service).
[NTA84] Hvinden, Oyvind, "NBS Class 4 Transport Protocol,
UNIX 4.2 BSD Implementation and User Interface
Description," Norwegian Telecommunications
Administration Establishment, Technical Report
No. 84-4053, December 1984.
[NTI82] "User-Oriented Performance Measurements on the
ARPANET: The Testing of a Proposed Federal
Standard," NTIA Report 82-112 (available from
NTIA, Boulder CO)
[NTI85] "The OSI Network Layer Addressing Scheme, Its
Implications, and Considerations for Implementation",
NTIA Report 85-186, (available from NTIA, Boulder CO)
[RFC85] Mills, David, "Internet Delay Experiments," RFC889,
December 1983 (available from the Network Information
Center).
[SPI82] Spirn, Jeffery R., "Network Modeling with Bursty
Traffic and Finite Buffer Space," Performance
Evaluation Review, vol. 2, no. 1, April 1982.
[SPI84] Spirn, Jeffery R., Jade Chien, William Hawe,
"Bursty Traffic Local Area Network Modeling,"
IEEE Journal on Selected Areas in Communications,
vol. SAC-2, no. 1, January 1984.
And that's the whole RFC, bestie! ๐๐ Every reference is right where it belongs, so go forth and implement with main character energy โจ๐ฆ
๐ฆ where this page comes from
- ietf: rfc1008 1987-06
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms