Section 5.1: Introduction
- This chapter documents the API for the Rx facility. Included are descriptions of all the constants, structures, exported variables, macros, and interface functions available to the application programmer. This interface is identical regardless of whether the application lives within the unix kernel or above it.
- This chapter actually provides more information than what may be strictly considered the Rx API. Many objects that were intended to be opaque and for Rx internal use only are also described here. The reason driving the inclusion of this "extra" information is that such exported Rx interface files as rx.h make these objects visible to application programmers. It is prefereable to describe these objects here than to ignore them and leave application programmers wondering as to their meaning.
- An example application illustrating the use of this interface, showcasing code from both server and client sides, appears in the following chapter.
Section 5.2: Constants
- This section covers the basic constant definitions of interest to the Rx application programmer. Each subsection is devoted to describing the constants falling into the following categories:
- Configuration quantities
- Waiting options
- Connection ID operations
- Connection flags
- Connection types
- Call states
- Call flags
- Call modes
- Packet header flags
- Packet sizes
- Packet types
- Packet classes
- Conditions prompting ack packets
- Ack types
- Error codes
- Debugging values
- An attempt has been made to relate these constant definitions to the objects or routines that utilize them.
Section 5.2.1: Configuration Quantities
- These definitions provide some basic Rx configuration parameters, including the number of simultaneous calls that may be handled on a single connection, lightweight thread parameters, and timeouts for various operations.
- Name
- RX IDLE DEAD TIME
- Value
- 60
- Description
- Default idle dead time for connections, in seconds.
- Name
- RX MAX SERVICES
- Value
- 20
- Description
- The maximum number of Rx services that may be installed within one application.
- Name
- RX PROCESS MAXCALLS
- Value
- 4
- Description
- The maximum number of asynchronous calls active simultaneously on any given Rx connection. This value must be set to a power of two.
- Name
- RX DEFAULT STACK SIZE
- Value
- 16,000
- Description
- Default lightweight thread stack size, measured in bytes. This value may be overridden by calling the rx_SetStackSize() macro.
- Name
- RX PROCESS PRIORITY
- Value
- LWP NORMAL PRIORITY
- Description
- This is the priority under which an Rx thread should run. There should not generally be any reason to change this setting.
- Name
- RX CHALLENGE TIMEOUT
- Value
- 2
- Description
- The number of seconds before another authentication request packet is generated.
- Name
- RX MAXACKS
- Value
- 255
- Description
- Maximum number of individual acknowledgements that may be carried in an Rx acknowledgement packet.
Section 5.2.2: Waiting Options
- These definitions provide readable values indicating whether an operation should block when packet buffer resources are not available.
- Name
- RX DONTWAIT
- Value
- 0
- Description
- Wait until the associated operation completes.
- Name
- RX WAIT
- Value
- 1
- Description
- Don't wait if the associated operation would block.
Section 5.2.3: Connection ID Operations
- These values assist in extracting the call channel number from a connection identifier. A call channel is the index of a particular asynchronous call structure within a single Rx connection.
- Name
- RX CIDSHIFT
- Value
- 2
- Description
- Number of bits to right-shift to isolate a connection ID. Must be set to the log (base two) of RX MAXCALLS.
- Name
- RX CHANNELMASK
- Value
- (RX MAXCALLS-1)
- Description
- Mask used to isolate a call channel from a connection ID field.
- Name
- RX CIDMASK
- Value
- (~RX CHANNELMASK)
- Description
- Mask used to isolate the connection ID from its field, masking out the call channel information.
Section 5.2.4: Connection Flags
- The values defined here appear in the flags field of Rx connections, as defined by the rx connection structure described in Section 5.3.2.2.
- Name
- RX CONN MAKECALL WAITING
- Value
- 1
- Description
- rx MakeCall() is waiting for a channel.
- Name
- RX CONN DESTROY ME
- Value
- 2
- Description
- Destroy this (client) connection after its last call completes.
- Name
- RX CONN USING PACKET CKSUM
- Value
- 4
- Description
- This packet is using security-related check-summing (a non-zero header, spare field has been seen.)
Section 5.2.5: Connection Types
- Rx stores different information in its connection structures, depending on whether the given connection represents the server side (the one providing the service) or the client side (the one requesting the service) of the protocol. The type field within the connection structure (described in Section 5.3.2.2) takes on the following values to differentiate the two types of connections, and identifies the fields that are active within the connection structure.
- Name
- RX CLIENT CONNECTION
- Value
- 0
- Description
- This is a client-side connection.
- Name
- CONNECTION
- Value
- 1
- Description
- This is a server-side connection.
Section 5.2.6: Call States
- An Rx call on a particular connection may be in one of several states at any instant in time. The following definitions identify the range of states that a call may assume.
- Name
- RX STATE NOTINIT
- Value
- 0
- Description
- The call structure has never been used, and is thus still completely uninitialized.
- Name
- RX STATE PRECALL
- Value
- 1
- Description
- A call is not yet in progress, but packets have arrived for it anyway. This only applies to calls within server-side connections.
- Name
- RX STATE ACTIVE
- Value
- 2
- Description
- This call is fully active, having an attached lightweight thread operating on its behalf.
- Name
- RX STATE DAILY
- Value
- 3
- Description
- The call structure is "dallying" after its lightweight thread has completed its most recent call. This is a "hot-standby" condition, where the call structure preserves state from the previous call and thus optimizes the arrival of further, related calls.
Section 5.2.7: Call Flags:
- These values are used within the flags field of a variable declared to be of type struct rx call, as described in Section 5.3.2.4. They provide additional information as to the state of the given Rx call, such as the type of event for which it is waiting (if any) and whether or not all incoming packets have been received in support of the call.
- Name
- RX CALL READER WAIT
- Value
- 1
- Description
- Reader is waiting for next packet.
- Name
- RX CALL WAIT WINDOW ALLOC
- Value
- 2
- Description
- Sender is waiting for a window so that it can allocate buffers.
- Name
- RX CALL WAIT WINDOW SEND
- Value
- 4
- Description
- Sender is waiting for a window so that it can send buffers.
- Name
- RX CALL WAIT PACKETS
- Value
- 8
- Description
- Sender is waiting for packet buffers.
- Name
- RX CALL RECEIVE DONE
- Value
- 16
- Description
- The call is waiting for a lightweight thread to be assigned to the operation it has just received.
- Name
- RX CALL RECEIVE DONE
- Value
- 32
- Description
- All packets have been received on this call.
- Name
- RX CALL CLEARED
- Value
- 64
- Description
- The receive queue has been cleared when in precall state.
Section 5.2.8: Call Modes
- These values define the modes of an Rx call when it is in the RX STATE ACTIVE state, having a lightweight thread assigned to it.
- Name
- RX MODE SENDING
- Value
- 1
- Description
- We are sending or ready to send.
- Name
- RX MODE RECEIVING
- Value
- 2
- Description
- We are receiving or ready to receive.
- Name
- RX MODE ERROR
- Value
- 3
- Description
- Something went wrong in the current conversation.
- Name
- RX MODE EOF
- Value
- 4
- Description
- The server side has flushed (or the client side has read) the last reply packet.
Section 5.2.9: Packet Header Flags
- Rx packets carry a flag field in their headers, providing additional information regarding the packet's contents. The Rx packet header's flag field's bits may take the following values:
- Name
- RX CLIENT INITIATED
- Value
- 1
- Description
- Signifies that a packet has been sent/received from the client side of the call.
- Name
- RX REQUEST ACK
- Value
- 2
- Description
- The Rx calls' peer entity requests an acknowledgement.
- Name
- RX LAST PACKET
- Value
- 4
- Description
- This is the final packet from this side of the call.
- Name
- RX MORE PACKETS
- Value
- 8
- Description
- There are more packets following this, i.e., the next sequence number seen by the receiver should be greater than this one, rather than a retransmission of an earlier sequence number.
- Name
- RX PRESET FLAGS
- Value
- (RX CLIENT INITIATED | RX LAST PACKET)
- Description
- This flag is preset once per Rx packet. It doesn't change on retransmission of the packet.
Section 5.2.10: Packet Sizes
- These values provide sizing information on the various regions within Rx packets. These packet sections include the IP/UDP headers and bodies as well Rx header and bodies. Also covered are such values as different maximum packet sizes depending on whether they are targeted to peers on the same local network or a more far-flung network. Note that the MTU term appearing below is an abbreviation for Maximum Transmission Unit.
- Name
- RX IPUDP SIZE
- Value
- 28
- Description
- The number of bytes taken up by IP/UDP headers.
- Name
- RX MAX PACKET SIZE
- Value
- (1500 - RX IPUDP SIZE)
- Description
- This is the Ethernet MTU minus IP and UDP header sizes.
- Name
- RX HEADER SIZE
- Value
- sizeof (struct rx header)
- Description
- The number of bytes in an Rx packet header.
- Name
- RX MAX PACKET DATA SIZE
- Value
- (RX MAX PACKET SIZE RX - HEADER SIZE)
- Description
- Maximum size in bytes of the user data in a packet.
- Name
- RX LOCAL PACKET SIZE
- Value
- RX MAX PACKET SIZE
- Description
- Packet size in bytes to use when being sent to a host on the same net.
- Name
- RX REMOTE PACKET SIZE
- Value
- (576 - RX IPUDP SIZE)
- Description
- Packet size in bytes to use when being sent to a host on a different net.
Section 5.2.11: Packet Types
- The following values are used in the packetType field within a struct rx packet, and define the different roles assumed by Rx packets. These roles include user data packets, different flavors of acknowledgements, busies, aborts, authentication challenges and responses, and debugging vehicles.
- Name
- RX PACKET TYPE DATA
- Value
- 1
- Description
- A user data packet.
- Name
- RX PACKET TYPE ACK
- Value
- 2
- Description
- Acknowledgement packet.
- Name
- RX PACKET TYPE BUSY
- Value
- 3
- Description
- Busy packet. The server-side entity cannot accept the call at the moment, but the requestor is encouraged to try again later.
- Name
- RX PACKET TYPE ABORT
- Value
- 4
- Description
- Abort packet. No response is needed for this packet type.
- Name
- RX PACKET TYPE ACKALL
- Value
- 5
- Description
- Acknowledges receipt of all packets on a call.
- Name
- RX PACKET TYPE CHALLENGE
- Value
- 6
- Description
- Challenge the client's identity, requesting credentials.
- Name
- RX PACKET TYPE RESPONSE
- Value
- 7
- Description
- Response to a RX PACKET TYPE CHALLENGE authentication challenge packet.
- Name
- RX PACKET TYPE DEBUG
- Value
- 8
- Description
- Request for debugging information.
- Name
- RX N PACKET TYPES
- Value
- 9
- Description
- The number of Rx packet types defined above. Note that it also includes packet type 0 (which is unused) in the count.
- The RX PACKET TYPES definition provides a mapping of the above values to human-readable string names, and is exported by the rx packetTypes variable catalogued in Section 5.4.9.
{
"data",
"ack",
"busy",
"abort",
"ackall",
"challenge",
"response",
"debug"
}
Section 5.2.12: Packet Classes
- These definitions are used internally to manage alloction of Rx packet buffers according to quota classifications. Each packet belongs to one of the following classes, and its buffer is derived from the corresponding pool.
- Name
- RX PACKET CLASS RECEIVE
- Value
- 0
- Description
- Receive packet for user data.
- Name
- RX PACKET CLASS SEND
- Value
- 1
- Description
- Send packet for user data.
- Name
- RX PACKET CLASS SPECIAL
- Value
- 2
- Description
- A special packet that does not hold user data, such as an acknowledgement or authentication challenge.
- Name
- RX N PACKET CLASSES
- Value
- 3
- Description
- The number of Rx packet classes defined above.
Section 5.2.13: Conditions Prompting Ack Packets
- Rx acknowledgement packets are constructed and sent by the protocol according to the following reasons. These values appear in the Rx packet header of the ack packet itself.
- Name
- RX ACK REQUESTED
- Value
- 1
- Description
- The peer has explicitly requested an ack on this packet.
- Name
- RX ACK DUPLICATE
- Value
- 2
- Description
- A duplicate packet has been received.
- Name
- RX ACK OUT OF SEQUENCE
- Value
- 3
- Description
- A packet has arrived out of sequence.
- Name
- RX ACK EXCEEDS WINDOW
- Value
- 4
- Description
- A packet sequence number higher than maximum value allowed by the call's window has been received.
- Name
- RX ACK NOSPACE
- Value
- 5
- Description
- No packet buffer space is available.
- Name
- RX ACK PING
- Value
- 6
- Description
- Acknowledgement for keep-alive purposes.
- Name
- RX ACK PING RESPONSE
- Value
- 7
- Description
- Response to a RX ACK PING packet.
- Name
- RX ACK DELAY
- Value
- 8
- Description
- An ack generated due to a period of inactivity after normal packet receptions.
- These are the set of values placed into the acks array in an Rx acknowledgement packet, whose data format is defined by struct rx ackPacket. These definitions are used to convey positive or negative acknowledgements for a given range of packets.
- Name
- RX ACK TYPE NACK
- Value
- 0
- Description
- Receiver doesn't currently have the associated packet; it may never hae been received, or received and then later dropped before processing.
- Name
- RX ACK TYPE ACK
- Value
- 1
- Description
- Receiver has the associated packet queued, although it may later decide to discard it.
Section 5.2.15: Error Codes
- Rx employs error codes ranging from -1 to -64. The Rxgen stub generator may use other error codes less than -64. User programs calling on Rx, on the other hand, are expected to return positive error codes. A return value of zero is interpreted as an indication that the given operation completed successfully.
- Name
- RX CALL DEAD
- Value
- -1
- Description
- A connection has been inactive past Rx's tolerance levels and has been shut down.
- Name
- RX INVALID OPERATION
- Value
- -2
- Description
- An invalid operation has been attempted, including such protocol errors as having a client-side call send data after having received the beginning of a reply from its server-side peer.
- Name
- RX CALL TIMEOUT
- Value
- -3
- Description
- The (optional) timeout value placed on this call has been exceeded (see Sections 5.5.3.4 and 5.6.5).
- Name
- RX EOF
- Value
- -4
- Description
- Unexpected end of data on a read operation.
- Name
- RX PROTOCOL ERROR
- Value
- -5
- Description
- An unspecified low-level Rx protocol error has occurred.
- Name
- RX USER ABORT
- Value
- -6
- Description
- A generic user abort code, used when no more specific error code needs to be communicated. For example, Rx clients employing the multicast feature (see Section 1.2.8) take advantage of this error code.
Section 5.2.16: Debugging Values
- Rx provides a set of data collections that convey information about its internal status and performance. The following values have been defined in support of this debugging and statistics-collection feature.
Section 5.2.16.1: Version Information
- Various versions of the Rx debugging/statistics interface are in existance, each defining different data collections and handling certain bugs. Each Rx facility is stamped with a version number of its debugging/statistics interface, allowing its clients to tailor their requests to the precise data collections that are supported by a particular Rx entity, and to properly interpret the data formats received through this interface. All existing Rx implementations should be at revision M.
- Name
- RX DEBUGI VERSION MINIMUM
- Value
- 'L'
- Description
- The earliest version of Rx statistics available.
- Name
- RX DEBUGI VERSION
- Value
- 'M'
- Description
- The latest version of Rx statistics available.
- Name
- RX DEBUGI VERSION W SECSTATS
- Value
- 'L'
- Description
- Identifies the earliest version in which statistics concerning Rx security objects is available.
- Name
- RX DEBUGI VERSION W GETALLCONN
- Value
- 'M'
- Description
- The first version that supports getting information about all current Rx connections, as specified y the RX DEBUGI GETALLCONN debugging request packet opcode described below.
- Name
- RX DEBUGI VERSION W RXSTATS
- Value
- 'M'
- Description
- The first version that supports getting all the Rx statistics in one operation, as specified by the RX DEBUGI RXSTATS debugging request packet opcode described below.
- Name
- RX DEBUGI VERSION W UNALIGNED CONN
- Value
- 'L'
- Description
- There was an alignment problem discovered when returning Rx connection information in older versions of this debugging/statistics interface. This identifies the last version that exhibited this alignment problem.
Section 5.2.16.2: Opcodes
- When requesting debugging/statistics information, the caller specifies one of the following supported data collections:
- Name
- RX DEBUGI GETSTATS
- Value
- 1
- Description
- Get basic Rx statistics.
- Name
- RX DEBUGI GETCONN
- Value
- 2
- Description
- Get information on all Rx connections considered "interesting" (as defined below), and no others.
- Name
- RX DEBUGI GETALLCONN
- Value
- 3
- Description
- Get information on all existing Rx connection structures, even "uninteresting" ones.
- Name
- RX DEBUGI RXSTATS
- Value
- 4
- Description
- Get all available Rx stats.
- An Rx connection is considered "interesting" if it is waiting for a call channel to free up or if it has been marked for destruction. If neither is true, a connection is still considered interesting if any of its call channels is actively handling a call or in its preparatory pre-call state. Failing all the above conditions, a connection is still tagged as interesting if any of its call channels is in either of the RX MODE SENDING or RX MODE RECEIVING modes, which are not allowed when the call is not active.
Section 5.2.16.3: Queuing
- These two queueing-related values indicate whether packets are present on the incoming and outgoing packet queues for a given Rx call. These values are only used in support of debugging and statistics-gathering operations.
- Name
- RX OTHER IN
- Value
- 1
- Description
- Packets available in in queue.
- Name
- RX OTHER OUT
- Value
- 2
- Description
- Packets available in out queue.
Section 5.3: Structures
- This section describes the major exported Rx data structures of interest to application programmers. The following categories are utilized for the purpose of organizing the structure descriptions:
- Security objects
- Protocol objects
- Packet formats
- Debugging and statistics
- Miscellaneous
- Please note that many fields described in this section are declared to be VOID. This is defined to be char, and is used to get around some compiler limitations.
Section 5.3.1: Security Objects
- As explained in Section 1.2.1, Rx provides a modular, extensible security model. This allows Rx applications to either use one of the built-in security/authentication protocol packages or write and plug in one of their own. This section examines the various structural components used by Rx to support generic security and authentication modules.
Section 5.3.1.1: struct rx securityOps
- As previously described, each Rx security object must export a fixed set of interface functions, providing the full set of operations defined on the object. The rx securityOps structure defines the array of functions comprising this interface. The Rx facility calls these routines at the appropriate times, without knowing the specifics of how any particular security object implements the operation.
- A complete description of these interface functions, including information regarding their exact purpose, parameters, and calling conventions, may be found in Section 5.5.7.
- fields
- int (*op Close)() - React to the disposal of a security object.
- int (*op NewConnection)() - Invoked each time a new Rx connection utilizing the associated security object is created.
- int (*op PreparePacket)() - Invoked each time an outgoing Rx packet is created and sent on a connection using the given security object.
- int (*op SendPacket)() - Called each time a packet belonging to a call in a connection using the security object is physically transmitted.
- int (*op CheckAuthentication)() - This function is executed each time it is necessary to check whether authenticated calls are being perfomed on a connection using the associated security object.
- int (*op CreateChallenge)() - Invoked each time a server-side challenge event is created by Rx, namely when the identity of the principal associated with the peer process must be determined.
- int (*op GetChallenge)() - Called each time a client-side packet is constructed in response to an authentication challenge.
- int (*op GetResponse)() - Executed each time a response to a challenge event must be received on the server side of a connection.
- int (*op CheckResponse)() - Invoked each time a response to an authentication has been received, validating the response and pulling out the required authentication information.
- int (*op CheckPacket) () - Invoked each time an Rx packet has been received, making sure that the packet is properly formatted and that it hasn't been altered.
- int (*op DestroyConnection)() - Called each time an Rx connection employing the given security object is destroyed.
- int (*op GetStats)() - Executed each time a request for statistics on the given security object has been received.
- int (*op Spare1)()-int (*op Spare3)() - Three spare function slots, reserved for future use.
Section 5.2.1.2: struct rx securityClass
- Variables of type struct rx securityClass are used to represent instantiations of a particular security model employed by Rx. It consists of a pointer to the set of interface operations implementing the given security object, along with a pointer to private storage as necessary to support its operations. These security objects are also reference-counted, tracking the number of Rx connections in existance that use the given security object. If the reference count drops to zero, the security module may garbage-collect the space taken by the unused security object.
- fields
- struct rx securityOps *ops - Pointer to the array of interface functions for the security object.
- VOID *privateData - Pointer to a region of storage used by the security object to support its operations.
- int refCount - A reference count on the security object, tracking the number of Rx connections employing this model.
Section 5.3.1.3: struct rx
securityObjectStats
- This structure is used to report characteristics for an instantiation of a security object on a particular Rx connection, as well as performance figures for that object. It is used by the debugging portions of the Rx package. Every security object defines and manages fields such as level and flags differently.
- fields
- char type - The type of security object being implemented. Existing values are:
- 0: The null security package.
- 1: An obsolete Kerberos-like security object.
- 2: The rxkad discipline (see Chapter 3).
- char level - The level at which encryption is utilized.
- char sparec[10] - Used solely for alignment purposes.
- long flags - Status flags regarding aspects of the connection relating to the security object.
- u long expires - Absolute time when the authentication information cached by the given connection expires. A value of zero indicates that the associated authentication information is valid for all time.
- u long packetsReceived - Number of packets received on this particular connection, and thus the number of incoming packets handled by the associated security object.
- u long packetsSent - Number of packets sent on this particular connection, and thus the number of outgoing packets handled by the associated security object.
- u long bytesReceived - Overall number of "payload" bytes received (i.e., packet bytes not associated with IP headers, UDP headers, and the security module's own header and trailer regions) on this connection.
- u long bytesSent - Overall number of "payload" bytes sent (i.e., packet bytes not associated with IP headers, UDP headers, and the security module's own header and trailer regions) on this connection.
- short spares[4] - Several shortword spares, reserved for future use.
- long sparel[8] - Several longword spares, reserved for future use.
Section 5.3.2: Protocol Objects
- The structures describing the main abstractions and entities provided by Rx, namely services, peers, connections and calls are covered in this section.
Section 5.3.2.1: struct rx service
- An Rx-based server exports services, or specific RPC interfaces that accomplish certain tasks. Services are identified by (host-address, UDP-port, serviceID) triples. An Rx service is installed and initialized on a given host through the use of the rx NewService() routine (See Section 5.6.3). Incoming calls are stamped with the Rx service type, and must match an installed service to be accepted. Internally, Rx services also carry string names for purposes of identification. These strings are useful to remote debugging and statistics-gathering programs. The use of a service ID allows a single server process to export multiple, independently-specified Rx RPC services.
- Each Rx service contains one or more security classes, as implemented by individual security objects. These security objects implement end-to-end security protocols. Individual peer-to-peer connections established on behalf of an Rx service will select exactly one of the supported security objects to define the authentication procedures followed by all calls associated with the connection. Applications are not limited to using only the core set of built-in security objects offered by Rx. They are free to define their own security objects in order to execute the specific protocols they require.
- It is possible to specify both the minimum and maximum number of lightweight processes available to handle simultaneous calls directed to an Rx service. In addition, certain procedures may be registered with the service and called at set times in the course of handling an RPC request.
- fields
- u short serviceId - The associated service number.
- u short servicePort - The chosen UDP port for this service.
- char *serviceName - The human-readable service name, expressed as a character
- string. osi socket socket - The socket structure or file descriptor used by this service.
- u short nSecurityObjects - The number of entries in the array of supported security objects.
- struct rx securityClass **securityObjects - The array of pointers to the ser vice's security class objects.
- long (*executeRequestProc)() - A pointer to the routine to call when an RPC request is received for this service.
- VOID (*destroyConnProc)() - A pointer to the routine to call when one of the server-side connections associated with this service is destroyed.
- VOID (*newConnProc)() - A pointer to the routine to call when a server-side connection associated with this service is created.
- VOID (*beforeProc)() - A pointer to the routine to call before an individual RPC call on one of this service's connections is executed.
- VOID (*afterProc)() - A pointer to the routine to call after an individual RPC call on one of this service's connections is executed.
- short nRequestsRunning - The number of simultaneous RPC calls currently in progress for this service.
- short maxProcs - This field has two meanings. first, maxProcs limits the total number of requests that may execute in parallel for any one service. It also guarantees that this many requests may be handled in parallel if there are no active calls for any other service.
- short minProcs - The minimum number of lightweight threads (hence requests) guaranteed to be simultaneously executable.
- short connDeadTime - The number of seconds until a client of this service will be declared to be dead, if it is not responding to the RPC protocol.
- short idleDeadTime - The number of seconds a server-side connection for this service will wait for packet I/O to resume after a quiescent period before the connection is marked as dead.
Section 5.3.2.2: struct rx connection
- An Rx connection represents an authenticated communication path, allowing multiple asynchronous conversations (calls). Each connection is identified by a connection ID. The low-order bits of the connection ID are reserved so they may be stamped with the index of a particular call channel. With up to RX MAXCALLS concurrent calls (set to 4 in this implementation), the bottom two bits are set aside for this purpose. The connection ID is not sufficient by itself to uniquely identify an Rx connection. Should a client crash and restart, it may reuse a connection ID, causing inconsistent results. In addition to the connection ID, the epoch, or start time for the client side of the connection, is used to identify a connection. Should the above scenario occur, a different epoch value will be chosen by the client, differentiating this incarnation from the orphaned connection record on the server side.
- Each connection is associated with a parent service, which defines a set of supported security models. At creation time, an Rx connection selects the particular security protocol it will implement, referencing the associated service. The connection structure maintains state about the individual calls being simultaneously handled.
- fields
- struct rx connection *next - Used for internal queueing.
- struct rx peer *peer - Pointer to the connection's peer information (see below).
- u long epoch - Process start time of the client side of the connection.
- u long cid - Connection identifier. The call channel (i.e., the index into the connection's array of call structures) may appear in the bottom bits.
- VOID *rock - Pointer to an arbitrary region of memory in support of the connection's operation. The contents of this area are opaque to the Rx facility in general, but are understood by any special routines used by this connection.
- struct rx call *call[RX MAXCALLS] - Pointer to the call channel structures, describing up to RX MAXCALLS concurrent calls on this connection.
- u long callNumber[RX MAXCALLS] - The set of current call numbers on each of the call channels.
- int timeout - Obsolete; no longer used.
- u char flags - Various states of the connection; see Section 5.2.4 for individual bit definitions.
- u char type - Whether the connection is a server-side or client-side one. See Section 5.2.5 for individual bit definitions.
- u short serviceId - The service ID that should be stamped on requests. This field is only used by client-side instances of connection structures.
- struct rx service *service - A pointer to the service structure associated with this connection. This field is only used by server-side instances of connection structures.
- u long serial - Serial number of the next outgoing packet associated with this connection.
- u long lastSerial - Serial number of the last packet received in association with this connection. This field is used in computing packet skew.
- u short secondsUntilDead - Maximum numer of seconds of silence that should be tolerated from the connection's peer before calls will be terminated with an RX CALL DEAD error.
- u char secondsUntilPing - The number of seconds between "pings" (keep-alive probes) when at least one call is active on this connection.
- u char securityIndex - The index of the security object being used by this connection. This number selects a slot in the security class array maintained by the service associated with the connection.
- long error - Records the latest error code for calls occurring on this connection.
- struct rx securityClass *securityObject - A pointer to the security object used by this connection. This should coincide with the slot value chosen by the securityIndex field described above.
- VOID *securityData - A pointer to a region dedicated to hosting any storage required by the security object being used by this connection.
- u short securityHeaderSize - The length in bytes of the portion of the packet header before the user's data that contains the security module's information.
- u short securityMaxTrailerSize - The length in bytes of the packet trailer, appearing after the user's data, as mandated by the connection's security module.
- struct rxevent *challengeEvent -Pointer to an event that is scheduled when the server side of the connection is challenging the client to authenticate itself.
- int lastSendTime - The last time a packet was sent on this connection.
- long maxSerial - The largest serial number seen on incoming packets.
- u short hardDeadTime - The maximum number of seconds that any call on this connection may execute. This serves to throttle runaway calls.
Section 5.3.2.3: struct rx peer
- For each connection, Rx maintains information describing the entity, or peer, on the other side of the wire. A peer is identified by a (host, UDP-port) pair. Included in the information kept on this remote communication endpoint are such network parameters as the maximum packet size supported by the host, current readings on round trip time to retransmission delays, and packet skew (see Section 1.2.7). There are also congestion control fields, ranging from descriptions of the maximum number of packets that may be sent to the peer without pausing and retransmission statistics. Peer structures are shared between connections whenever possible, and hence are reference-counted. A peer object may be garbage-collected if it is not actively referenced by any connection structure and a sufficient period of time has lapsed since the reference count dropped to zero.
- fields
- struct rx peer *next - Use to access internal lists.
- u long host - Remote IP address, in network byte order
- u short port - Remote UDP port, in network byte order
- short packetSize - Maximum packet size for this host, if known.
- u long idleWhen - When the refCount reference count field (see below) went to zero.
- short refCount - Reference count for this structure
- u char burstSize - Reinitialization size for the burst field (below).
- u char burst - Number of packets that can be transmitted immediately without pausing.
- struct clock burstWait - Time delay until new burst aimed at this peer is allowed.
- struct queue congestionQueue - Queue of RPC call descriptors that are waiting for a non-zero burst value.
- int rtt - Round trip time to the peer, measured in milliseconds.
- struct clock timeout - Current retransmission delay to the peer.
- int nSent - Total number of distinct data packets sent, not including retransmissions.
- int reSends - Total number of retransmissions for this peer since the peer structure instance was created.
- u long inPacketSkew - Maximum skew on incoming packets (see Section 1.2.7)
- u long outPacketSkew - Peer-reported maximum skew on outgoing packets (see Section 1.2.7).
Section 5.3.2.4: struct rx call
- This structure records the state of an active call proceeding on a given Rx connection. As described above, each connection may have up to RX MAXCALLS calls active at any one instant, and thus each connection maintains an array of RX MAXCALLS rx call structures. The information contained here is specific to the given call; "permanent" call state, such as the call number, is maintained in the connection structure itself.
- fields
- struct queue queue item header - Queueing information for this structure.
- struct queue tq - Queue of outgoing ("transmit") packets.
- struct queue rq - Queue of incoming ("receive") packets.
- char *bufPtr - Pointer to the next byte to fill or read in the call's current packet, depending on whether it is being transmitted or received.
- u short nLeft - Number of bytes left to read in the first packet in the reception queue (see field rq).
- u short nFree - Number of bytes still free in the last packet in the transmission queue (see field tq).
- struct rx packet *currentPacket - Pointer to the current packet being assembled or read.
- struct rx connection *conn - Pointer to the parent connection for this call.
- u long *callNumber - Pointer to call number field within the call's current packet.
- u char channel - Index within the parent connection's call array that describes this call.
- u char dummy1, dummy2 - These are spare fields, reserved for future use.
- u char state - Current call state. The associated bit definitions appear in Section 5.2.7.
- u char mode - Current mode of a call that is in RX STATE ACTIVE state. The associated bit definitions appear in Section 5.2.8.
- u char flags - Flags pertaining to the state of the given call. The associated bit definitions appear in Section 5.2.7.
- u char localStatus - Local user status information, sent out of band. This field is currently not in use, set to zero.
- u char remoteStatus - Remote user status information, received out of band. This field is currently not in use, set to zero.
- long error - Error condition for this call.
- u long timeout - High level timeout for this call
- u long rnext - Next packet sequence number expected to be received.
- u long rprev - Sequence number of the previous packet received. This number is used to decide the proper sequence number for the next packet to arrive, and may be used to generate a negative acknowledgement.
- u long rwind - Width of the packet receive window for this call. The peer must not send packets with sequence numbers greater than or equal to rnext + rwind.
- u long tfirst - Sequence number of the first unacknowledged transmit packet for this call.
- u long tnext - Next sequence number to use for an outgoing packet.
- u long twind - Width of the packet transmit window for this call. Rx cannot assign a sequence number to an outgoing packet greater than or equal to tfirst + twind.
- struct rxevent *resendEvent - Pointer to a pending retransmission event, if any.
- struct rxevent *timeoutEvent - Pointer to a pending timeout event, if any.
- struct rxevent *keepAliveEvent - Pointer to a pending keep-alive event, if this is an active call.
- struct rxevent *delayedAckEvent - Pointer to a pending delayed acknowledgement packet event, if any. Transmission of a delayed acknowledgement packet is scheduled after all outgoing packets for a call have been sent. If neither a reply nor a new call are received by the time the delayedAckEvent activates, the ack packet will be sent.
- int lastSendTime - Last time a packet was sent for this call.
- int lastReceiveTime - Last time a packet was received for this call.
- VOID (*arrivalProc)() - Pointer to the procedure to call when reply is received.
- VOID *arrivalProcHandle - Pointer to the handle to pass to the arrivalProc as its first argument.
- VOID *arrivalProcArg - Pointer to an additional argument to pass to the given arrivalProc.
- u long lastAcked - Sequence number of the last packet "hard-acked" by the receiver. A packet is considered to be hard-acked if an acknowledgement is generated after the reader has processed it. The Rx facility may sometimes "soft-ack" a windowfull of packets before they have been picked up by the receiver.
- u long startTime - The time this call started running.
- u long startWait - The time that a server began waiting for input data or send quota.
Section 5.3.3: Packet Formats
- The following sections cover the different data formats employed by the suite of Rx packet types, as enumerated in Section 5.2.11. A description of the most commonly-employed Rx packet header appears first, immediately followed by a description of the generic packet container and descriptor. The formats for Rx acknowledgement packets and debugging/statistics packets are also examined.
Section 5.3.3.1: struct rx header
- Every Rx packet has its own header region, physically located after the leading IP/UDP headers. This header contains connection, call, security, and sequencing information. Along with a type identifier, these fields allow the receiver to properly interpret the packet. In addition, every client relates its "epoch", or Rx incarnation date, in each packet. This assists in identifying protocol problems arising from reuse of connection identifiers due to a client restart. Also included in the header is a byte of user-defined status information, allowing out-of-band channel of communication for the higher-level application using Rx as a transport mechanism.
- fields
- u long epoch - Birth time of the client Rx facility.
- u long cid - Connection identifier, as defined by the client. The last RX CIDSHIFT bits in the cid field identify which of the server-side RX MAXCALLS call channels is to receive the packet.
- u long callNumber - The current call number on the chosen call channel.
- u long seq - Sequence number of this packet. Sequence numbers start with 0 for each new Rx call.
- u long serial - This packet's serial number. A new serial number is stamped on each packet transmitted (or retransmitted).
- u char type - What type of Rx packet this is; see Section 5.2.11 for the list of legal definitions.
- u char flags - Flags describing this packet; see Section 5.2.9 for the list of legal settings.
- u char userStatus - User-defined status information, uninterpreted by the Rx facility itself. This field may be easily set or retrieved from Rx packets via calls to the rx GetLocalStatus(), rx SetLocalStatus(), rx GetRemoteStatus(), and rx SetRemoteStatus() macros.
- u char securityIndex - Index in the associated server-side service class of the security object used by this call.
- u short serviceId - The server-provided service ID to which this packet is directed.
- u short spare - This field was originally a true spare, but is now used by the built-in rxkad security module for packet header checksums. See the descriptions of the related rx IsUsingPktChecksum(), rx GetPacketCksum(), and rx SetPacketCksum() macros.
Section 5.3.3.2: struct rx packet
- This structure is used to describe an Rx packet, and includes the wire version of the packet contents, where all fields exist in network byte order. It also includes acknowledgement, length, type, and queueing information.
- fields
- struct queue queueItemHeader - field used for internal queueing.
- u char acked - If non-zero, this field indicates that this packet has been tentatively (soft-) acknowledged. Thus, the packet has been accepted by the rx peer entity on the other side of the connection, but has not yet necessarily been passed to the true reader. The sender is not free to throw the packet away, as it might still get dropped by the peer before it is delivered to its destination process.
- short length - Length in bytes of the user data section.
- u char packetType - The type of Rx packet described by this record. The set of legal choices is available in Section 5.2.11.
- struct clock retryTime - The time when this packet should be retransmitted next.
- struct clock timeSent - The last time this packet was transmitted.
- struct rx header header - A copy of the internal Rx packet header.
- wire - The text of the packet as it appears on the wire. This structure has the following sub-fields:
- u long head[RX HEADER SIZE/sizeof(long)] The wire-level contents of IP, UDP, and Rx headers.
- u long data[RX MAX PACKET DATA SIZE/sizeof(long)] The wire form of the packet's "payload", namely the user data it carries.
Section 5.3.3.3: struct rx ackPacket
- This is the format for the data portion of an Rx acknowledgement packet, used to inform a peer entity performing packet transmissions that a subset of its packets has been properly received.
- fields
- u short bufferSpace - Number of packet buffers available. Specifically, the number of packet buffers that the ack packet's sender is willing to provide for data on this or subsequent calls. This number does not have to fully accurate; it is acceptable for the sender to provide an estimate.
- u short maxSkew - The maximum difference seen between the serial number of the packet being acknowledged and highest packet yet received. This is an indication of the degree to which packets are arriving out of order at the receiver.
- u long firstPacket - The serial number of the first packet in the list of acknowledged packets, as represented by the acks field below.
- u long previousPacket - The previous packet serial number received.
- u long serial - The serial number of the packet prompted the acknowledgement.
- u char reason - The reason given for the acknowledgement; legal values for this field are described in Section 5.2.13.
- u char nAcks - Number of acknowledgements active in the acks array immediately following.
- u char acks[RX MAXACKS] - Up to RX MAXACKS packet acknowledgements. The legal values for each slot in the acks array are described in Section 5.2.14. Basically, these fields indicate either positive or negative acknowledgements.
- All packets with serial numbers prior to firstPacket are implicitly acknowledged by this packet, indicating that they have been fully processed by the receiver. Thus, the sender need no longer be concerned about them, and may release all of the resources that they occupy. Packets with serial numbers firstPacket + nAcks and higher are not acknowledged by this ack packet. Packets with serial numbers in the range [firstPacket, firstPacket + nAcks) are explicitly acknowledged, yet their sender-side resources must not yet be released, as there is yet no guarantee that the receiver will not throw them away before they can be processed there.
- There are some details of importance to be noted. For one, receiving a positive acknowlegement via the acks array does not imply that the associated packet is immune from being dropped before it is read and processed by the receiving entity. It does, however, imply that the sender should stop retransmitting the packet until further notice. Also, arrival of an ack packet should prompt the transmitter to immediately retransmit all packets it holds that have not been explicitly acknowledged and that were last transmitted with a serial number less than the highest serial number acknowledged by the acks array. Note: The fields in this structure are always kept in wire format, namely in network byte order.
Section 5.3.4: Debugging and Statistics
- The following structures are defined in support of the debugging and statistics-gathering interfaces provided by Rx.
Section 5.3.4.1: struct rx stats
- This structure maintains Rx statistics, and is gathered by such tools as the rxdebug program. It must be possible for all of the fields placed in this structure to be successfully converted from their on-wire network byte orderings to the host-specific ordering.
- fields
- int packetRequests - Number of packet allocation requests processed.
- int noPackets[RX N PACKET CLASSES] - Number of failed packet requests, organized per allocation class.
- int socketGreedy - Whether the SO GREEDY setting succeeded for the Rx socket.
- int bogusPacketOnRead - Number of inappropriately short packets received.
- int bogusHost - Contains the host address from the last bogus packet received.
- int noPacketOnRead - Number of attempts to read a packet off the wire when there was actually no packet there.
- int noPacketBuffersOnRead - Number of dropped data packets due to lack of packet buffers.
- int selects - Number of selects waiting for a packet arrival or a timeout.
- int sendSelects - Number of selects forced when sending packets.
- int packetsRead[RX N PACKET TYPES] - Total number of packets read, classified by type.
- int dataPacketsRead - Number of unique data packets read off the wire.
- int ackPacketsRead - Number of ack packets read.
- int dupPacketsRead - Number of duplicate data packets read.
- int spuriousPacketsRead - Number of inappropriate data packets.
- int packetsSent[RX N PACKET TYPES] - Number of packet transmissions, broken down by packet type.
- int ackPacketsSent - Number of ack packets sent.
- int pingPacketsSent - Number of ping packets sent.
- int abortPacketsSent - Number of abort packets sent.
- int busyPacketsSent - Number of busy packets sent.
- int dataPacketsSent - Number of unique data packets sent.
- int dataPacketsReSent - Number of retransmissions.
- int dataPacketsPushed - Number of retransmissions pushed early by a negative acknowledgement.
- int ignoreAckedPacket - Number of packets not retransmitted because they have already been acked.
- int struct clock totalRtt - Total round trip time measured for packets, used to compute average time figure.
- struct clock minRtt - Minimum round trip time measured for packets. struct clock maxRtt - Maximum round trip time measured for packets.
- int nRttSamples - Number of round trip samples.
- int nServerConns - Number of server connections.
- int nClientConns - Number of client connections.
- int nPeerStructs - Number of peer structures.
- int nCallStructs - Number of call structures physically allocated (using the internal storage allocator routine).
- int nFreeCallStructs - Number of call structures which were pulled from the free queue, thus avoiding a call to the internal storage allocator routine.
- int spares[10] - Ten integer spare fields, reserved for future use.
Section 5.3.4.2: struct rx debugIn
- This structure defines the data format for a packet requesting one of the statistics collections maintained by Rx.
- fields
- long type - The specific data collection that the caller desires. Legal settings for this field are described in Section 5.2.16.2.
- long index - This field is only used when gathering information on Rx connections. Choose the index of the server-side connection record of which we are inquiring. This field may be used as an iterator, stepping through all the connection records, one per debugging request, until they have all been examined.
Section 5.3.4.3: struct rx debugStats
- This structure describes the data format for a reply to an RX DEBUGI GETSTATS debugging request packet. These fields are given values indicating the current state of the Rx facility.
- fields
- long nFreePackets - Number of packet buffers currently assigned to the free pool.
- long packetReclaims - Currently unused.
- long callsExecuted - Number of calls executed since the Rx facility was initialized.
- char waitingForPackets - Is Rx currently blocked waiting for a packet buffer to come free?
- char usedFDs - If the Rx facility is executing in the kernel, return the number of unix file descriptors in use. This number is not directly related to the Rx package, but rather describes the state of the machine on which Rx is running.
- char version - Version number of the debugging package.
- char spare1[1] - Byte spare, reserved for future use.
- long spare2[10] - Set of 10 longword spares, reserved for future use.
Section 5.3.4.4: struct rx debugConn
- This structure defines the data format returned when a caller requests information concerning an Rx connection. Thus, rx debugConn defines the external packaging of interest to external parties. Most of these fields are set from the rx connection structure, as defined in Section 5.3.2.2, and others are obtained by indirecting through such objects as the connection's peer and call structures.
- fields
- long host - Address of the host identified by the connection's peer structure.
- long cid - The connection ID.
- long serial - The serial number of the next outgoing packet associated with this connection.
- long callNumber[RX MAXCALLS] - The current call numbers for the individual call channels on this connection.
- long error - Records the latest error code for calls occurring on this connection.
- short port - UDP port associated with the connection's peer.
- char flags - State of the connection; see Section 5.2.4 for individual bit definitions.
- char type - Whether the connection is a server-side or client-side one. See Section 5.2.5 for individual bit definitions.
- char securityIndex - Index in the associated server-side service class of the security object being used by this call.
- char sparec[3] - Used to force alignment for later fields.
- char callState[RX MAXCALLS] - Current call state on each call channel. The associated bit definitions appear in Section 5.2.7.
- char callMode[RX MAXCALLS] - Current mode of all call channels that are in RX STATE ACTIVE state. The associated bit definitions appear in Section 5.2.8.
- char callFlags[RX MAXCALLS] - Flags pertaining to the state of each of the connection's call channels. The associated bit definitions appear in Section 5.2.7.
- char callOther[RX MAXCALLS] - Flag field for each call channel, where the presence of the RX OTHER IN flag indicates that there are packets present on the given call's reception queue, and the RX OTHER OUT flag indicates the presence of packets on the transmission queue.
- struct rx securityObjectStats secStats - The contents of the statistics related to the security object selected by the securityIndex field, if any.
- long epoch - The connection's client-side incarnation time.
- long sparel[10] - A set of 10 longword fields, reserved for future use.
Section 5.3.4.5: struct rx debugConn vL
- This structure is identical to rx debugConn defined above, except for the fact that it is missing the sparec field. This sparec field is used in rx debugConn to fix an alignment problem that was discovered in version L of the debugging/statistics interface (hence the trailing "tt vL tag in the structure name). This alignment problem is fixed in version M, which utilizes and exports the rx debugConn structure exclusively. Information regarding the range of version-numbering values for the Rx debugging/statistics interface may be found in Section 5.2.16.1.
Section 5.4: Exported Variables
- This section describes the set of variables that the Rx facility exports to its applications. Some of these variables have macros defined for the sole purpose of providing the caller with a convenient way to manipulate them. Note that some of these exported variables are never meant to be altered by application code (e.g., rx nPackets).
Section 5.4.1: rx connDeadTime
- This integer-valued variable determines the maximum number of seconds that a connection may remain completely inactive, without receiving packets of any kind, before it is eligible for garbage collection. Its initial value is 12 seconds. The rx SetRxDeadTime macro sets the value of this variable.
Section 5.4.2: rx idleConnectionTime
- This integer-valued variable determines the maximum number of seconds that a server connection may "idle" (i.e., not have any active calls and otherwise not have sent a packet) before becoming eligible for garbage collection. Its initial value is 60 seconds.
Section 5.4.3: rx idlePeerTime
- This integer-valued variable determines the maximum number of seconds that an Rx peer structure is allowed to exist without any connection structures referencing it before becoming eligible for garbage collection. Its initial value is 60 seconds.
Section 5.4.4: rx extraQuota
- This integer-valued variable is part of the Rx packet quota system (see Section 1.2.6), which is used to avoid system deadlock. This ensures that each server-side thread has a minimum number of packets at its disposal, allowing it to continue making progress on active calls. This particular variable records how many extra data packets a user has requested be allocated. Its initial value is 0.
Section 5.4.5: rx extraPackets
- This integer-valued variable records how many additional packet buffers are to be created for each Rx server thread. The caller, upon setting this variable, is applying some application-specific knowledge of the level of network activity expected. The rx extraPackets variable is used to compute the overall number of packet buffers to reserve per server thread, namely rx nPackets, described below. The initial value is 32 packets.
Section 5.4.6: rx nPackets
- This integer-valued variable records the total number of packet buffers to be allocated per Rx server thread. It takes into account the quota packet buffers and the extra buffers requested by the caller, if any.
- Note
- This variable should never be set directly; the Rx facility itself computes its value. Setting it incorrectly may result in the service becoming deadlocked due to insufficient resources. Callers wishing to allocate more packet buffers to their server threads should indicate that desire by setting the rx extraPackets variable described above.
Section 5.4.7: rx nFreePackets
- This integer-valued variable records the number of Rx packet buffers not currently used by any call. These unused buffers are collected into a free pool.
Section 5.4.8: rx stackSize
- This integer-valued variable records the size in bytes for the lightweight process stack. The variable is initially set to RX DEFAULT STACK SIZE, and is typically manipulated via the rx SetStackSize() macro.
Section 5.4.9: rx packetTypes
- This variable holds an array of string names used to describe the different roles for Rx packets. Its value is derived from the RX PACKET TYPES definition found in Section 5.2.11.
Section 5.4.10: rx stats
- This variable contains the statistics structure that keeps track of Rx statistics. The struct rx stats structure it provides is defined in Section 5.3.4.1.
Section 5.5: Macros
- Rx uses many macro definitions in preference to calling C functions directly. There are two main reasons for doing this:
- field selection: Many Rx operations are easily realized by returning the value of a particular structure's field. It is wasteful to invoke a C routine to simply fetch a structure's field, incurring unnecessary function call overhead. Yet, a convenient, procedure-oriented operation is still provided to Rx clients for such operations by the use of macros. For example, the rx ConnectionOf() macro, described in Section 5.5.1.1, simply indirects through the Rx call structure pointer parameter to deliver the conn field.
- Performance optimization: In some cases, a simple test or operation can be performed to accomplish a particular task. When this simple, straightforward operation fails, then a true C routine may be called to handle to more complex (and rarer) situation. The Rx macro rx Write(), described in Section 5.5.6.2, is a perfect example of this type of optimization. Invoking rx Write() first checks to determine whether or not the outgoing call's internal buffer has enough room to accept the specified data bytes. If so, it copies them into the call's buffer, updating counts and pointers as appropriate. Otherwise, rx Write() calls the rx WriteProc() to do the work, which in this more complicated case involves packet manipulations, dispatches, and allocations. The result is that the common, simple cases are often handled in-line, with more complex (and rarer) cases handled through true function invocations.
- The set of Rx macros is described according to the following categories.
- field selections/assignments
- Boolean operations
- Service attributes
- Security-related operations
- Sizing operations
- Complex operation
- Security operation invocations
Section 5.5.1: field Selections/Assignments
- These macros facilitate the fetching and setting of fields from the structures described Chapter 5.3.
Section 5.5.1.1: rx ConnectionOf()
- #define rx_ConnectionOf(call) ((call)->conn)
- Generate a reference to the connection field within the given Rx call structure. The value supplied as the call argument must resolve into an object of type (struct rx call *). An application of the rx ConnectionOf() macro itself yields an object of type rx peer.
Section 5.5.1.2: rx PeerOf()
- #define rx_PeerOf(conn) ((conn)->peer)
- Generate a reference to the peer field within the given Rx call structure. The value supplied as the conn argument must resolve into an object of type (struct rx connection *). An instance of the rx PeerOf() macro itself resolves into an object of type rx peer.
Section 5.5.1.3: rx HostOf()
- #define rx_HostOf(peer) ((peer)->host)
- Generate a reference to the host field within the given Rx peer structure. The value supplied as the peer argument must resolve into an object of type (struct rx peer *). An instance of the rx HostOf() macro itself resolves into an object of type u long.
Section 5.5.1.4: rx PortOf()
- #define rx_PortOf(peer) ((peer)->port)
- Generate a reference to the port field within the given Rx peer structure. The value supplied as the peer argument must resolve into an object of type (struct rx peer *). An instance of the rx PortOf() macro itself resolves into an object of type u short.
Section 5.5.1.5: rx GetLocalStatus()
- #define rx_GetLocalStatus(call, status) ((call)->localStatus)
- Generate a reference to the localStatus field, which specifies the local user status sent out of band, within the given Rx call structure. The value supplied as the call argument must resolve into an object of type (struct rx call *). The second argument, status, is not used. An instance of the rx GetLocalStatus() macro itself resolves into an object of type u char.
Section 5.5.1.6: rx SetLocalStatus()
- #define rx_SetLocalStatus(call, status) ((call)->localStatus = (status))
- Assign the contents of the localStatus field, which specifies the local user status sent out of band, within the given Rx call structure. The value supplied as the call argument must resolve into an object of type (struct rx call *). The second argument, status, provides the new value of the localStatus field, and must resolve into an object of type u char. An instance of the rx GetLocalStatus() macro itself resolves into an object resulting from the assignment, namely the u char status parameter.
Section 5.5.1.7: rx GetRemoteStatus()
- #define rx_GetRemoteStatus(call) ((call)->remoteStatus)
- Generate a reference to the remoteStatus field, which specifies the remote user status received out of band, within the given Rx call structure. The value supplied as the call argument must resolve into an object of type (struct rx call *). An instance of the rx GetRemoteStatus() macro itself resolves into an object of type u char.
Section 5.5.1.8: rx Error()
- #define rx_Error(call) ((call)->error)
- Generate a reference to the error field, which specifies the current error condition, within the given Rx call structure. The value supplied as the call argument must resolve into an object of type (struct rx call *). An instance of the rx Error() macro itself resolves into an object of type long.
Section 5.5.1.9: rx DataOf()
- #define rx_DataOf(packet) ((char *) (packet)->wire.data)
- Generate a reference to the beginning of the data portion within the given Rx packet as it appears on the wire. Any encryption headers will be resident at this address. For Rx packets of type RX PACKET TYPE DATA, the actual user data will appear at the address returned by the rx DataOf macro plus the connection's security header size. The value supplied as the packet argument must resolve into an object of type (struct rx packet *). An instance of the rx DataOf() macro itself resolves into an object of type (u long *).
Section 5.5.1.10: rx GetDataSize()
- #define rx_GetDataSize(packet) ((packet)->length)
- Generate a reference to the length field, which specifies the number of bytes of user data contained within the wire form of the packet, within the given Rx packet description structure. The value supplied as the packet argument must resolve into an object of type (struct rx packet *). An instance of the rx GetDataSize() macro itself resolves into an object of type short.
Section 5.5.1.11: rx SetDataSize()
- #define rx_SetDataSize(packet, size) ((packet)->length = (size))
- Assign the contents of the length field, which specifies the number of bytes of user data contained within the wire form of the packet, within the given Rx packet description structure. The value supplied as the packet argument must resolve into an object of type (struct rx packet *). The second argument, size, provides the new value of the length field, and must resolve into an object of type short. An instance of the rx SetDataSize() macro itself resolves into an object resulting from the assignment, namely the short length parameter.
Section 5.5.1.12: rx GetPacketCksum()
- #define rx_GetPacketCksum(packet) ((packet)->header.spare)
- Generate a reference to the header checksum field, as used by the built-in rxkad security module (See Chapter 3), within the given Rx packet description structure. The value supplied as the packet argument must resolve into an object of type (struct rx packet *). An instance of the rx GetPacketCksum() macro itself resolves into an object of type u short.
Section 5.5.1.13: rx SetPacketCksum()
- #define rx_SetPacketCksum(packet, cksum) ((packet)->header.spare = (cksum))
- Assign the contents of the header checksum field, as used by the built-in rxkad security module (See Chapter 3), within the given Rx packet description structure. The value supplied as the packet argument must resolve into an object of type (struct rx packet *). The second argument, cksum, provides the new value of the checksum, and must resolve into an object of type u short. An instance of the rx SetPacketCksum() macro itself resolves into an object resulting from the assignment, namely the u short checksum parameter.
Section 5.5.1.14: rx GetRock()
- #define rx_GetRock(obj, type) ((type)(obj)->rock)
- Generate a reference to the field named rock within the object identified by the obj pointer. One common Rx structure to which this macro may be applied is struct rx connection. The specified rock field is casted to the value of the type parameter, which is the overall value of the rx GetRock() macro.
Section 5.5.1.15: rx SetRock()
- #define rx_SetRock(obj, newrock) ((obj)->rock = (VOID *)(newrock))
- Assign the contents of the newrock parameter into the rock field of the object pointed to by obj. The given object's rock field must be of type (VOID *). An instance of the rx SetRock() macro itself resolves into an object resulting from the assignment and is of type (VOID *).
Section 5.5.1.16: rx SecurityClassOf()
- #define rx_SecurityClassOf(conn) ((conn)->securityIndex)
- Generate a reference to the security index field of the given Rx connection description structure. This identifies the security class used by the connection. The value supplied as the conn argument must resolve into an object of type (struct rx connection *). An instance of the rx SecurityClassOf() macro itself resolves into an object of type u char.
Section 5.5.1.17: rx SecurityObjectOf()
- #define rx_SecurityObjectOf(conn) ((conn)->securityObject)
- Generate a reference to the security object in use by the given Rx connection description structure. The choice of security object determines the authentication protocol enforced by the connection. The value supplied as the conn argument must resolve into an object of type (struct rx connection *). An instance of the rx SecurityObjectOf() macro itself resolves into an object of type (struct rx securityClass *).
Section 5.5.2: Boolean Operations
- The macros described in this section all return Boolean values. They are used to query such things as the whether a connection is a server-side or client-side one and if extra levels of checksumming are being used in Rx packet headers.
Section 5.5.2.1: rx IsServerConn()
- #define rx_IsServerConn(conn) ((conn)->type == RX_SERVER_CONNECTION)
- Determine whether or not the Rx connection specified by the conn argument is a server-side connection. The value supplied for conn must resolve to an object of type struct rx connection. The result is determined by testing whether or not the connection's type field is set to RX SERVER CONNECTION.
- Note
- Another macro, rx ServerConn(), performs the identical operation.
Section 5.5.2.2: rx IsClientConn()
- #define rx_IsClientConn(conn) ((conn)->type == RX_CLIENT_CONNECTION)
- Determine whether or not the Rx connection specified by the conn argument is a client-side connection. The value supplied for conn must resolve to an object of type struct rx connection. The result is determined by testing whether or not the connection's type field is set to RX CLIENT CONNECTION.
- Note
- Another macro, rx ClientConn(), performs the identical operation.
Section 5.5.2.2: rx IsUsingPktCksum()
- #define rx_IsUsingPktCksum(conn) ((conn)->flags & RX_CONN_USING_PACKET_CKSUM)
- Determine whether or not the Rx connection specified by the conn argument is checksum-ming the headers of all packets on its calls. The value supplied for conn must resolve to an object of type struct rx connection. The result is determined by testing whether or not the connection's flags field has the RX CONN USING PACKET CKSUM bit enabled.
Section 5.5.3: Service Attributes
- This section describes user-callable macros that manipulate the attributes of an Rx service. Note that these macros must be called (and hence their operations performed) before the given service is installed via the appropriate invocation of the associated rx StartServer() function.
Section 5.5.3.1: rx SetStackSize()
- rx_stackSize = (((stackSize) stackSize) > rx_stackSize) ? stackSize : rx_stackSize)
- Inform the Rx facility of the stack size in bytes for a class of threads to be created in support of Rx services. The exported rx stackSize variable tracks the high-water mark for all stack size requests before the call to rx StartServer(). If no calls to rx SetStackSize() are made, then rx stackSize will retain its default setting of RX DEFAULT STACK SIZE.
- In this macro, the first argument is not used. It was originally intended that thread stack sizes would be settable on a per-service basis. However, calls to rx SetStackSize() will ignore the service parameter and set the high-water mark for all Rx threads created after the use of rx SetStackSize(). The second argument, stackSize, specifies determines the new stack size, and should resolve to an object of type int. The value placed in the stackSize parameter will not be recorded in the global rx stackSize variable unless it is greater than the variable's current setting.
- An instance of the rx SetStackSize() macro itself resolves into the result of the assignment, which is an object of type int.
Section 5.5.3.2: rx SetMinProcs()
- #define rx_SetMinProcs(service, min) ((service)->minProcs = (min))
- Choose min as the minimum number of threads guaranteed to be available for parallel execution of the given Rx service. The service parameter should resolve to an object of type struct rx service. The min parameter should resolve to an object of type short. An instance of the rx SetMinProcs() macro itself resolves into the result of the assignment, which is an object of type short.
Section 5.5.3.3: rx SetMaxProcs()
- #define rx_SetMaxProcs(service, max) ((service)->maxProcs = (max))
- Limit the maximum number of threads that may be made available to the given Rx service for parallel execution to be max. The service parameter should resolve to an object of type struct rx service. The max parameter should resolve to an object of type short. An instance of the rx SetMaxProcs() macro itself resolves into the result of the assignment, which is an object of type short.
Section 5.5.3.4: rx SetIdleDeadTime()
- #define rx_SetIdleDeadTime(service, time) ((service)->idleDeadTime = (time))
- Every Rx service has a maximum amount of time it is willing to have its active calls sit idle (i.e., no new data is read or written for a call marked as RX STATE ACTIVE) before unilaterally shutting down the call. The expired call will have its error field set to RX CALL TIMEOUT. The operative assumption in this situation is that the client code is exhibiting a protocol error that prevents progress from being made on this call, and thus the call's resources on the server side should be freed. The default value, as recorded in the service's idleDeadTime field, is set at service creation time to be 60 seconds. The rx SetIdleTime() macro allows a caller to dynamically set this idle call timeout value.
- The service parameter should resolve to an object of type struct rx service. Also, the time parameter should resolve to an object of type short. finally, an instance of the rx SetIdleDeadTime() macro itself resolves into the result of the assignment, which is an object of type short.
Section 5.5.3.5: rx SetServiceDeadTime()
- #define rx_SetServiceDeadTime(service, seconds) ((service)->secondsUntilDead = (seconds))
- Note
- This macro definition is obsolete and should NOT be used. Including it in application code will generate a compile-time error, since the service structure no longer has such a field defined.
- See the description of the rx SetConnDeadTime() macro below to see how hard timeouts may be set for situations of complete call inactivity.
Section 5.5.3.6: rx SetRxDeadTime()
- #define rx_SetRxDeadTime(seconds) (rx_connDeadTime = (seconds))
- Inform the Rx facility of the maximum number of seconds of complete inactivity that will be tolerated on an active call. The exported rx connDeadTime variable tracks this value, and is initialized to a value of 12 seconds. The current value of rx connDeadTime will be copied into new Rx service and connection records upon their creation.
- The seconds argument determines the value of rx connDeadTime, and should resolve to an object of type int. An instance of the rx SetRxDeadTime() macro itself resolves into the result of the assignment, which is an object of type int.
Section 5.5.3.7: rx SetConnDeadTime()
- #define rx_SetConnDeadTime(conn, seconds) (rxi_SetConnDeadTime(conn, seconds))
- Every Rx connection has a maximum amount of time it is willing to have its active calls on a server connection sit without receiving packets of any kind from its peer. After such a quiescent time, during which neither data packets (regardless of whether they are properly sequenced or duplicates) nor keep-alive packets are received, the call's error field is set to RX CALL DEAD and the call is terminated. The operative assumption in this situation is that the client making the call has perished, and thus the call's resources on the server side should be freed. The default value, as recorded in the connection's secondsUntilDead field, is set at connection creation time to be the same as its parent service. The rx SetConnDeadTime() macro allows a caller to dynamically set this timeout value.
- The conn parameter should resolve to an object of type struct rx connection. Also, the seconds parameter should resolve to an object of type int. finally, an instance of the rx SetConnDeadTime() macro itself resolves into the a call to rxi SetConnDeadTime(), whose return value is void.
Section 5.5.3.8: rx SetConnHardDeadTime()
- #define rx_SetConnHardDeadTime(conn, seconds) ((conn)->hardDeadTime = (seconds))
- It is convenient to be able to specify that calls on certain Rx connections have a hard absolute timeout. This guards against protocol errors not caught by other checks in which one or both of the client and server are looping. The rx SetConnHardDeadTime() macro is available for this purpose. It will limit calls on the connection identified by the conn parameter to execution times of no more than the given number of seconds. By default, active calls on an Rx connection may proceed for an unbounded time, as long as they are not totally quiescent (see Section 5.5.3.7 for a description of the rx SetConnDeadTime()) or idle (see Section 5.5.3.4 for a description of the rx SetIdleDeadTime()).
- The conn parameter should resolve to an object of type (struct rx connection *). The seconds parameter should resolve to an object of type u short. An instance of the rx SetConnHardDeadTime() macro itself resolves into the result of the assignment, which is an object of type u short.
Section 5.5.3.9: rx GetBeforeProc()
- #define rx_GetBeforeProc(service) ((service)->beforeProc)
- Return a pointer of type (VOID *)() to the procedure associated with the given Rx service that will be called immediately upon activation of a server thread to handle an incoming call. The service parameter should resolve to an object of type struct rx service.
- When an Rx service is first created (via a call to the rx NewService() function), its beforeProc field is set to a null pointer. See the description of the rx SetBeforeProc() below.
Section 5.5.3.10: rx SetBeforeProc()
- #define rx_SetBeforeProc(service, proc) ((service)->beforeProc = (proc))
- Instruct the Rx facility to call the procedure identified by the proc parameter immediately upon activation of a server thread to handle an incoming call. The specified procedure will be called with a single parameter, a pointer of type struct rx call, identifying the call this thread will now be responsible for handling. The value returned by the procedure, if any, is discarded.
- The service parameter should resolve to an object of type struct rx service. The proc parameter should resolve to an object of type (VOID *)(). An instance of the rx SetBeforeProc() macro itself resolves into the result of the assignment, which is an object of type (VOID *)().
Section 5.5.3.11: rx GetAfterProc()
- #define rx_GetAfterProc(service) ((service)->afterProc)
- Return a pointer of type (VOID *)() to the procedure associated with the given Rx service that will be called immediately upon completion of the particular Rx call for which a server thread was activated. The service parameter should resolve to an object of type struct rx service.
- When an Rx service is first created (via a call to the rx NewService() function), its afterProc field is set to a null pointer. See the description of the rx SetAfterProc() below.
Section 5.5.3.12: rx SetAfterProc()
- #define rx_SetAfterProc(service, proc) ((service)->afterProc = (proc))
- Instruct the Rx facility to call the procedure identified by the proc parameter immediately upon completion of the particular Rx call for which a server thread was activated. The specified procedure will be called with a single parameter, a pointer of type struct rx call, identifying the call this thread just handled. The value returned by the procedure, if any, is discarded.
- The service parameter should resolve to an object of type struct rx service. The proc parameter should resolve to an object of type (VOID *)(). An instance of the rx SetAfterProc() macro itself resolves into the result of the assignment, which is an object of type (VOID *)().
Section 5.5.3.13: rx SetNewConnProc()
- #define rx_SetNewConnProc(service, proc) ((service)->newConnProc = (proc))
- Instruct the Rx facility to call the procedure identified by the proc parameter as the last step in the creation of a new Rx server-side connection for the given service. The specified procedure will be called with a single parameter, a pointer of type (struct rx connection *), identifying the connection structure that was just built. The value returned by the procedure, if any, is discarded.
- The service parameter should resolve to an object of type struct rx service. The proc parameter should resolve to an object of type (VOID *)(). An instance of the rx SetNewConnProc() macro itself resolves into the result of the assignment, which is an object of type (VOID *)().
- Note
- There is no access counterpart defined for this macro, namely one that returns the current setting of a service's newConnProc.
Section 5.5.3.14: rx SetDestroyConnProc()
- #define rx_SetDestroyConnProc(service, proc) ((service)->destroyConnProc = (proc))
- Instruct the Rx facility to call the procedure identified by the proc parameter just before a server connection associated with the given Rx service is destroyed. The specified procedure will be called with a single parameter, a pointer of type (struct rx connection *), identifying the connection about to be destroyed. The value returned by the procedure, if any, is discarded.
- The service parameter should resolve to an object of type struct rx service. The proc parameter should resolve to an object of type (VOID *)(). An instance of the rx SetDestroyConnProc() macro itself resolves into the result of the assignment, which is an object of type (VOID *)().
- Note
- There is no access counterpart defined for this macro, namely one that returns the current setting of a service's destroyConnProc.
Section 5.5.4: Security-Related Operations
- The following macros are callable by Rx security modules, and assist in getting and setting header and trailer lengths, setting actual packet size, and finding the beginning of the security header (or data).
Section 5.5.4.1: rx GetSecurityHeaderSize()
- #define rx_GetSecurityHeaderSize(conn) ((conn)->securityHeaderSize)
- Generate a reference to the field in an Rx connection structure that records the length in bytes of the associated security module's packet header data.
- The conn parameter should resolve to an object of type struct rx connection. An instance of the rx GetSecurityHeaderSize() macro itself resolves into an object of type u short.
Section 5.5.4.2: rx SetSecurityHeaderSize()
- #define rx_SetSecurityHeaderSize(conn, length) ((conn)->securityHeaderSize = (length))
- Set the field in a connection structure that records the length in bytes of the associated security module's packet header data.
- The conn parameter should resolve to an object of type struct rx connection. The length parameter should resolve to an object of type u short. An instance of the rx SetSecurityHeaderSize() macro itself resolves into the result of the assignment, which is an object of type u short.
Section 5.5.4.3: rx
GetSecurityMaxTrailerSize()
- #define rx_GetSecurityMaxTrailerSize(conn) ((conn)->securityMaxTrailerSize)
- Generate a reference to the field in an Rx connection structure that records the maximum length in bytes of the associated security module's packet trailer data.
- The conn parameter should resolve to an object of type struct rx connection. An instance of the rx GetSecurityMaxTrailerSize() macro itself resolves into an object of type u short.
Section 5.5.4.4: rx
SetSecurityMaxTrailerSize()
- #define rx_SetSecurityMaxTrailerSize(conn, length) ((conn)->securityMaxTrailerSize = (length))
- Set the field in a connection structure that records the maximum length in bytes of the associated security module's packet trailer data.
- The conn parameter should resolve to an object of type struct rx connection. The length parameter should resolve to an object of type u short. An instance of the rx SetSecurityHeaderSize() macro itself resolves into the result of the assignment, which is an object of type u short.
Section 5.5.5: Sizing Operations
- The macros described in this section assist the application programmer in determining the sizes of the various Rx packet regions, as well as their placement within a packet buffer.
Section 5.5.5.1: rx UserDataOf()
- #define rx_UserDataOf(conn, packet) (((char *) (packet)->wire.data) + (conn)->securityHeaderSize)
- Generate a pointer to the beginning of the actual user data in the given Rx packet, that is associated with the connection described by the conn pointer. User data appears immediately after the packet's security header region, whose length is determined by the security module used by the connection. The conn parameter should resolve to an object of type struct rx connection. The packet parameter should resolve to an object of type struct rx packet. An instance of the rx UserDataOf() macro itself resolves into an object of type (char *).
Section 5.5.5.2: rx MaxUserDataSize()
- #define rx_MaxUserDataSize(conn)
((conn)->peer->packetSize
-RX_HEADER_SIZE
-(conn)->securityHeaderSize
-(conn)->securityMaxTrailerSize)
- Return the maximum number of user data bytes that may be carried by a packet on the Rx connection described by the conn pointer. The overall packet size is reduced by the IP, UDP, and Rx headers, as well as the header and trailer areas required by the connection's security module.
- The conn parameter should resolve to an object of type struct rx connection. An instance of the rx MaxUserDataSize() macro itself resolves into the an object of type (u short).
Section 5.5.6: Complex Operations
- Two Rx macros are designed to handle potentially complex operations, namely reading data from an active incoming call and writing data to an active outgoing call. Each call structure has an internal buffer that is used to collect and cache data traveling through the call. This buffer is used in conjunction with reading or writing to the actual Rx packets traveling on the wire in support of the call. The rx Read() and rx Write() macros allow their caller to simply manipulate the internal data buffer associated with the Rx call structures whenever possible, thus avoiding the overhead associated with a function call. When buffers are either filled or drained (depending on the direction of the data flow), these macros will then call functions to handle the more complex cases of generating or receiving packets in support of the operation.
Section 5.5.6.1: rx Read()
- #define rx_Read(call, buf, nbytes)
((call)->nLeft > (nbytes) ?
bcopy((call)->bufPtr, (buf), (nbytes)),
(call)->nLeft -= (nbytes), (call)->bufPtr += (nbytes), (nbytes)
: rx_ReadProc((call), (buf), (nbytes)))
- Read nbytes of data from the given Rx call into the buffer to which buf points. If the call's internal buffer has at least nbytes bytes already filled, then this is done in-line with a copy and some pointer and counter updates within the call structure. If the call's internal buffer doesn't have enough data to satisfy the request, then the rx ReadProc() function will handle this more complex situation.
- In either case, the rx Read() macro returns the number of bytes actually read from the call, resolving to an object of type int. If rx Read() returns fewer than nbytes bytes, the call status should be checked via the rx Error() macro.
Section 5.5.6.2: rx Write()
- #define rx_Write(call, buf, nbytes)
((call)->nFree > (nbytes) ?
bcopy((buf), (call)->bufPtr, (nbytes)),
(call)->nFree -= (nbytes),
(call)->bufPtr += (nbytes), (nbytes)
: rx_WriteProc((call), (buf), (nbytes)))
- Write nbytes of data from the buffer pointed to by buf into the given Rx call. If the call's internal buffer has at least nbytes bytes free, then this is done in-line with a copy and some pointer and counter updates within the call structure. If the call's internal buffer doesn't have room, then the rx WriteProc() function will handle this more complex situation.
- In either case, the rx Write() macro returns the number of bytes actually written to the call, resolving to an object of type int. If zero is returned, the call status should be checked via the rx Error() macro.
Section 5.5.7: Security Operation Invocations
- Every Rx security module is required to implement an identically-named set of operations, through which the security mechanism it defines is invoked. This characteristic interface is reminiscent of the vnode interface defined and popularized for file systems by Sun Microsystems [4]. The structure defining this function array is described in Section 5.3.1.1.
- These security operations are part of the struct rx securityClass, which keeps not only the ops array itself but also any private data they require and a reference count. Every Rx service contains an array of these security class objects, specifying the range of security mechanisms it is capable of enforcing. Every Rx connection within a service is associated with exactly one of that service's security objects, and every call issued on the connection will execute the given security protocol.
- The macros described below facilitate the execution of the security module interface functions. They are covered in the same order they appear in the struct rx securityOps declaration.
Section 5.5.7.1: RXS OP()
#if defined(__STDC__) && !defined(__HIGHC__)
#define RXS_OP(obj, op, args)
((obj->ops->op_ ## op) ? (*(obj)->ops->op_ ## op)args : 0)
#else
#define RXS_OP(obj, op, args)
((obj->ops->op_op) ? (*(obj)->ops->op_op)args : 0)
#endif
- The RXS OP macro represents the workhorse macro in this group, used by all the others. It takes three arguments, the first of which is a pointer to the security object to be referenced. This obj parameter must resolve to an object of type (struct rx securityOps *). The second parameter identifies the specific op to be performed on this security object. The actual text of this op argument is used to name the desired opcode function. The third and final argument, args, specifies the text of the argument list to be fed to the chosen security function. Note that this argument must contain the bracketing parentheses for the function call's arguments. In fact, note that each of the security function access macros defined below provides the enclosing parentheses to this third RXS OP() macro.
Section 5.5.7.1: RXS Close()
- #define RXS_Close(obj) RXS_OP(obj, Close, (obj))
- This macro causes the execution of the interface routine occupying the op Close() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx immediately before a security object is discarded. Among the responsibilities of such a function might be decrementing the object's refCount field, and thus perhaps freeing up any space contained within the security object's private storage region, referenced by the object's privateData field.
- The obj parameter must resolve into an object of type (struct rx securityOps *). In generating a call to the security object's op Close() routine, the obj pointer is used as its single parameter. An invocation of the RXS Close() macro results in a return value identical to that of the op Close() routine, namely a value of type int.
Section 5.5.7.3: RXS NewConnection()
- #define RXS_NewConnection(obj, conn) RXS_OP(obj, NewConnection, (obj, conn))
- This macro causes the execution of the interface routine in the op NewConnection() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx immediately after a connection using the given security object is created. Among the responsibilities of such a function might be incrementing the object's refCount field, and setting any per-connection information based on the associated security object's private storage region, as referenced by the object's privateData field.
- The obj parameter must resolve into an object of type (struct rx securityOps *). The conn argument contains a pointer to the newly-created connection structure, and must resolve into an object of type (struct rx connection *).
- In generating a call to the routine located at the security object's op NewConnection() slot, the obj and conn pointers are used as its two parameters. An invocation of the RXS NewConnection() macro results in a return value identical to that of the op NewConnection() routine, namely a value of type int.
Section 5.5.7.4: RXS PreparePacket()
- #define RXS_PreparePacket(obj, call, packet)
RXS_OP(obj, PreparePacket, (obj, call, packet))
- This macro causes the execution of the interface routine in the op PreparePacket() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx each time it prepares an outward-bound packet. Among the responsibilities of such a function might be computing information to put into the packet's security header and/or trailer.
- The obj parameter must resolve into an object of type (struct rx securityOps *). The call argument contains a pointer to the Rx call to which the given packet belongs, and must resolve to an object of type (struct rx call *). The final argument, packet, contains a pointer to the packet itself. It should resolve to an object of type (struct rx packet *).
- In generating a call to the routine located at the security object's op PreparePacket() slot, the obj, call, and packet pointers are used as its three parameters. An invocation of the RXS PreparePacket() macro results in a return value identical to that of the op PreparePacket() routine, namely a value of type int.
Section 5.5.7.5: RXS SendPacket()
- #define RXS_SendPacket(obj, call, packet) RXS_OP(obj, SendPacket, (obj, call, packet))
- This macro causes the execution of the interface routine occupying the op SendPacket() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx each time it physically transmits an outward-bound packet. Among the responsibilities of such a function might be recomputing information in the packet's security header and/or trailer.
- The obj parameter must resolve into an object of type (struct rx securityOps *). The call argument contains a pointer to the Rx call to which the given packet belongs, and must resolve to an object of type (struct rx call *). The final argument, packet, contains a pointer to the packet itself. It should resolve to an object of type (struct rx packet *).
- In generating a call to the routine located at the security object's op SendPacket() slot, the obj, call, and packet pointers are used as its three parameters. An invocation of the RXS SendPacket() macro results in a return value identical to that of the op SendPacket() routine, namely a value of type int.
Section 5.5.7.6: RXS CheckAuthentication()
- #define RXS_CheckAuthentication(obj, conn) RXS_OP(obj, CheckAuthentication, (obj, conn))
- This macro causes the execution of the interface routine in the op CheckAuthentication() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx each time it needs to check whether the given connection is one on which authenticated calls are being performed. Specifically, a value of 0 is returned if authenticated calls are not being executed on this connection, and a value of 1 is returned if they are.
- The obj parameter must resolve into an object of type (struct rx securityOps *). The conn argument contains a pointer to the Rx connection checked as to whether authentication is being performed, and must resolve to an object of type (struct rx connection *).
- In generating a call to the routine in the security object's op CheckAuthentication() slot, the obj and conn pointers are used as its two parameters. An invocation of the RXS CheckAuthentication() macro results in a return value identical to that of the op CheckAuthentication() routine, namely a value of type int.
Section 5.5.7.7: RXS CreateChallenge()
- #define RXS_CreateChallenge(obj, conn) RXS_OP(obj, CreateChallenge, (obj, conn))
- This macro causes the execution of the interface routine in the op CreateChallenge() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx each time a challenge event is constructed for a given connection. Among the responsibilities of such a function might be marking the connection as temporarily unauthenticated until the given challenge is successfully met.
- The obj parameter must resolve into an object of type (struct rx securityOps *). The conn argument contains a pointer to the Rx connection for which the authentication challenge is being constructed, and must resolve to an object of type (struct rx connection *).
- In generating a call to the routine located at the security object's op CreateChallenge() slot, the obj and conn pointers are used as its two parameters. An invocation of the RXS CreateChallenge() macro results in a return value identical to that of the op CreateChallenge() routine, namely a value of type int.
Section 5.5.7.8: RXS GetChallenge()
- #define RXS_GetChallenge(obj, conn, packet) RXS_OP(obj, GetChallenge, (obj, conn, packet))
- This macro causes the execution of the interface routine occupying the op GetChallenge() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx each time a challenge packet is constructed for a given connection. Among the responsibilities of such a function might be constructing the appropriate challenge structures in the area of packet dedicated to security matters.
- The obj parameter must resolve into an object of type (struct rx securityOps *). The conn argument contains a pointer to the Rx connection to which the given challenge packet belongs, and must resolve to an object of type (struct rx connection *). The final argument, packet, contains a pointer to the challenge packet itself. It should resolve to an object of type (struct rx packet *).
- In generating a call to the routine located at the security object's op GetChallenge() slot, the obj, conn, and packet pointers are used as its three parameters. An invocation of the RXS GetChallenge() macro results in a return value identical to that of the op GetChallenge() routine, namely a value of type int.
Section 5.5.7.9: RXS GetResponse()
- #define RXS_GetResponse(obj, conn, packet) RXS_OP(obj, GetResponse, (obj, conn, packet))
- This macro causes the execution of the interface routine occupying the op GetResponse() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx on the server side each time a response to a challenge packet must be received.
- The obj parameter must resolve into an object of type (struct rx securityOps *). The conn argument contains a pointer to the Rx client connection that must respond to the authentication challenge, and must resolve to a (struct rx connection *) object. The final argument, packet, contains a pointer to the packet to be built in response to the challenge. It should resolve to an object of type (struct rx packet *).
- In generating a call to the routine located at the security object's op GetResponse() slot, the obj, conn, and packet pointers are used as its three parameters. An invocation of the RXS GetResponse() macro results in a return value identical to that of the op GetResponse() routine, namely a value of type int.
Section 5.5.7.10: RXS CheckResponse()
- #define RXS_CheckResponse(obj, conn, packet) RXS_OP(obj, CheckResponse, (obj, conn, packet))
- This macro causes the execution of the interface routine in the op CheckResponse() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx on the server side each time a response to a challenge packet is received for a given connection. The responsibilities of such a function might include verifying the integrity of the response, pulling out the necessary security information and storing that information within the affected connection, and otherwise updating the state of the connection.
- The obj parameter must resolve into an object of type (struct rx securityOps *). The conn argument contains a pointer to the Rx server connection to which the given challenge response is directed. This argument must resolve to an object of type (struct rx connection *). The final argument, packet, contains a pointer to the packet received in response to the challenge itself. It should resolve to an object of type (struct rx packet *).
- In generating a call to the routine located at the security object's op CheckResponse() slot, the obj, conn, and packet pointers are ued as its three parameters. An invocation of the RXS CheckResponse() macro results in a return value identical to that of the op CheckResponse() routine, namely a value of type int.
Section 5.5.7.11: RXS CheckPacket()
- #define RXS_CheckPacket(obj, call, packet) RXS_OP(obj, CheckPacket, (obj, call, packet))
- This macro causes the execution of the interface routine occupying the op CheckPacket() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx each time a packet is received. The responsibilities of such a function might include verifying the integrity of given packet, detecting any unauthorized modifications or tampering.
- The obj parameter must resolve into an object of type (struct rx securityOps *). The conn argument contains a pointer to the Rx connection to which the given challenge response is directed, and must resolve to an object of type (struct rx connection *). The final argument, packet, contains a pointer to the packet received in response to the challenge itself. It should resolve to an object of type (struct rx packet *).
- In generating a call to the routine located at the security object's op CheckPacket() slot, the obj, conn, and packet pointers are used as its three parameters. An invocation of the RXS CheckPacket() macro results in a return value identical to that of the op CheckPacket() routine, namely a value of type int.
- Please note that any non-zero return will cause Rx to abort all calls on the connection. Furthermore, the connection itself will be marked as being in error in such a case, causing it to reject any further incoming packets.
Section 5.5.7.12: RXS DestroyConnection()
- #define RXS_DestroyConnection(obj, conn) RXS_OP(obj, DestroyConnection, (obj, conn))
- This macro causes the execution of the interface routine in the op DestroyConnection() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx each time a connection employing the given security object is being destroyed. The responsibilities of such a function might include deleting any private data maintained by the security module for this connection.
- The obj parameter must resolve into an object of type (struct rx securityOps *). The conn argument contains a pointer to the Rx connection being reaped, and must resolve to a (struct rx connection *) object.
- In generating a call to the routine located at the security object's op DestroyConnection() slot, the obj and conn pointers are used as its two parameters. An invocation of the RXS DestroyConnection() macro results in a return value identical to that of the op DestroyConnection() routine, namely a value of type int.
Section 5.5.7.13: RXS GetStats()
- #define RXS_GetStats(obj, conn, stats) RXS_OP(obj, GetStats, (obj, conn, stats))
- This macro causes the execution of the interface routine in the op GetStats() slot in the Rx security object identified by the obj pointer. This interface function is invoked by Rx each time current statistics concerning the given security object are desired.
- The obj parameter must resolve into an object of type (struct rx securityOps *). The conn argument contains a pointer to the Rx connection using the security object to be examined, and must resolve to an object of type (struct rx connection *). The final argument, stats, contains a pointer to a region to be filled with the desired statistics. It should resolve to an object of type (struct rx securityObjectStats *).
- In generating a call to the routine located at the security object's op GetStats() slot, the obj, conn, and stats pointers are used as its three parameters. An invocation of the RXS GetStats() macro results in a return value identical to that of the op GetStats() routine, namely a value of type int.
Section 5.6: Functions
- Rx exports a collection of functions that, in conjuction with the macros explored in Section 5.5, allows its clients to set up and export services, create and tear down connections to these services, and execute remote procedure calls along these connections.
- This paper employs two basic categorizations of these Rx routines. One set of functions is meant to be called directly by clients of the facility, and are referred to as the exported operations. The individual members of the second set of functions are not meant to be called directly by Rx clients, but rather are called by the collection of defined macros, so they must still be lexically visible. These indirectly-executed routines are referred to here as the semi-exported operations.
- All Rx routines return zero upon success. The range of error codes employed by Rx is defined in Section 5.2.15.
Section 5.6.1: Exported Operations
Section 5.6.2: rx Init _ Initialize Rx
- int rx Init(IN int port)
- Description
- Initialize the Rx facility. If a non-zero port number is provided, it becomes the default port number for any service installed later. If 0 is provided for the port, a random port will be chosen by the system. The rx Init() function sets up internal tables and timers, along with starting up the listener thread.
- Error Codes
- RX ADDRINUSE The port provided has already been taken.
Section 5.6.3: rx NewService _ Create and install
a new service
- struct rx service *rx NewService(IN u short port; IN u short serviceId; IN char *serviceName; IN struct rx securityClass **securityObjects; IN int nSecurityObjects; IN long (*serviceProc)())
- Description
- Create and advertise a new Rx service. A service is uniquely named by a UDP port number plus a non-zero 16-bit serviceId on the given host. The port argument may be set to zero if rx Init() was called with a non-zero port number, in which case that original port will be used. A serviceName must also be provided, to be used for identification purposes (e.g., the service name might be used for probing for statistics). A pointer to an array of nSecurityObjects security objects to be associated with the new service is given in . securityObjects. The service's executeRequestProc() pointer is set to serviceProc.
- The function returns a pointer to a descriptor for the requested Rx service. A null return value indicates that the new service could not be created. Possible reasons include:
- The serviceId parameter was found to be zero.
- A port value of zero was specified at Rx initialization time (i.e., when rx init() was called), requiring a non-zero value for the port parameter here.
- Another Rx service is already using serviceId.
- Rx has already created the maximum RX MAX SERVICES Rx services (see Section 5.2.1).
- Error Codes
- (struct rx service *) NULL The new Rx service could not be created, due to one of the errors listed above.
Section 5.6.4: rx NewConnection _ Create a new
connection to a given service
- struct rx connection *rx NewConnection( IN u long shost, IN u short sport, IN u short sservice, IN struct rx securityClass *securityObject, IN int service SecurityIndex)
- Description
- Create a new Rx client connection to service sservice on the host whose IP address is contained in shost and to that host's sport UDP port. The corresponding Rx service identifier is expected in sservice. The caller also provides a pointer to the security object to use for the connection in securityObject, along with that object's serviceSecurityIndex among the security objects associated with service sservice via a previous rx NewService() call (see Section 5.6.3).
- Note
- It is permissible to provide a null value for the securityObject parameter if the chosen serviceSecurityIndex is zero. This corresponds to the pre-defined null security object, which does not engage in authorization checking of any kind.
- Error Codes
- — A pointer to an initialized Rx connection is always returned, unless osi Panic() is called due to memory allocation failure.
Section 5.6.5: rx NewCall _ Start a new call on
the given connection
- struct rx call *rx NewCall( IN struct rx connection *conn)
- Description
- Start a new Rx remote procedure call on the connection specified by the conn parameter. The existing call structures (up to RX MAXCALLS of them) are examined in order. The first non-active call encountered (i.e., either unused or whose call->state is RX STATE DALLY) will be appropriated and reset if necessary. If all call structures are in active use, the RX CONN MAKECALL WAITING flag is set in the conn->flags field, and the thread handling this request will sleep until a call structure comes free. Once a call structure has been reserved, the keep-alive protocol is enabled for it.
- The state of the given connection determines the detailed behavior of the function. The conn->timeout field specifies the absolute upper limit of the number of seconds this particular call may be in operation. After this time interval, calls to such routines as rx SendData() or rx ReadData() will fail with an RX CALL TIMEOUT indication.
- Error Codes
- — A pointer to an initialized Rx call is always returned, unless osi Panic() is called due to memory allocation failure.
Section 5.6.6: rx EndCall _ Terminate the given
call
- int rx EndCall(
- Parameters
-
IN | struct rx call *call, |
IN | long rc
) |
- Description
- Indicate that the Rx call described by the structure located at call is finished, possibly prematurely. The value passed in the rc parameter is returned to the peer, if appropriate. The final error code from processing the call will be returned as rx EndCall()'s value. The given call's state will be set to RX STATE DALLY, and threads waiting to establish a new call on this connection are signalled (see the description of the rx NewCall() in Section 5.6.5).
- Error Codes
- -1 Unspecified error has occurred.
Section 5.6.7: rx StartServer _ Activate installed
rx service(s)
- void rx StartServer( IN int donateMe)
- Description
- This function starts server threads in support of the Rx services installed via calls to rx NewService() (see Section 5.6.3). This routine first computes the number of server threads it must create, governed by the minProcs and maxProcs fields in the installed service descriptors. The minProcs field specifies the minimum number of threads that are guaranteed to be concurrently available to the given service. The maxProcs field specifies the maximum number of threads that may ever be concurrently assigned to the particular service, if idle threads are available. Using this information, rx StartServer() computes the correct overall number of threads as follows: For each installed service, minProcs threads will be created, enforcing the minimality guarantee. Calculate the maximum difference between the maxProcs and minProcs fields for each service, and create this many additional server threads, enforcing the maximality guarantee.
- If the value placed in the donateMe argument is zero, then rx StartServer() will simply return after performing as described above. Otherwise, the thread making the rx StartServer() call will itself begin executing the server thread loop. In this case, the rx StartServer() call will never return.
- Error Codes
- —None.
Section 5.6.8: rx PrintStats – Print basic
statistics to a file
- void rx PrintStats( IN FILE *file)
- Description
- Prints Rx statistics (basically the contents of the struct rx stats holding the statistics for the Rx facility) to the open file descriptor identified by file. The output is ASCII text, and is intended for human consumption.
- Note
- This function is available only if the Rx package has been compiled with the RXDEBUG flag.
- Error Codes
- —None.
Section 5.6.9: rx PrintPeerStats _ Print peer
statistics to a file
- void rx PrintPeerStats( IN FILE *file, IN struct rx peer *peer)
- Description
- Prints the Rx peer statistics found in peer to the open file descriptor identified by file. The output is in normal ASCII text, and is intended for human consumption.
- Note
- This function is available only if the Rx package has been compiled with the RXDEBUG flag.
- Error Codes
- —None.
Section 5.6.10: rx finalize _ Shut down Rx
gracefully
- void rx finalize()
- Description
- This routine may be used to shut down the Rx facility for either server or client applications. All of the client connections will be gracefully garbage-collected after their active calls are cleaned up. The result of calling rx finalize() from a client program is that the server-side entity will be explicitly advised that the client has terminated. This notification frees the server-side application from having to probe the client until its records eventually time out, and also allows it to free resources currently assigned to that client's support.
- Error Codes
- —None.
Section 5.6.11: Semi-Exported Operations
- As described in the introductory text in Section 5.6, entries in this lexically-visible set of Rx functions are not meant to be called directly by client applications, but rather are invoked by Rx macros called by users.
Section 5.6.12: rx WriteProc _ Write data to an
outgoing call
- int rx WriteProc( IN struct rx call *call, IN char *buf, IN int nbytes)
- Description
- Write nbytes of data from buffer buf into the Rx call identified by the call parameter. The value returned by rx WriteProc() reports the number of bytes actually written into the call. If zero is returned, then the rx Error() macro may be used to obtain the call status.
- This routine is called by the rx Write() macro, which is why it must be exported by the Rx facility.
- Error Codes
- Indicates error in the given Rx call; use the rx Error() macro to determine the call status.
Section 5.6.13: rx ReadProc _ Read data from an
incoming call
- int rx ReadProc( IN struct rx call *call, IN char *buf, IN int nbytes)
- Description
- Read up to nbytes of data from the Rx call identified by the call parameter into the buf buffer. The value returned by rx ReadProc() reports the number of bytes actually read from the call. If zero is returned, then the rx Error() macro may be used to obtain the call status.
- This routine is called by the rx Read() macro, which is why it must be exported by the Rx facility.
- Error Codes
- Indicates error in the given Rx call; use the rx Error() macro to determine the call status.
Section 5.6.1: Exported Operations
data on outgoing call
- void rx FlushWrite( IN struct rx call *call)
- Description
- Flush any buffered data on the given Rx call to the stream. If the call is taking place on a server connection, the call->mode is set to RX MODE EOF. If the call is taking place on a client connection, the call->mode is set to RX MODE RECEIVING.
- Error Codes
- —None.
Section 5.6.15: rx SetArrivalProc _ Set function
to invoke upon call packet arrival
- void rx SetArrivalProc( IN struct rx call *call, IN VOID (*proc)(), IN VOID *handle, IN VOID *arg)
- Description
- Establish a procedure to be called when a packet arrives for a call. This routine will be called at most once after each call, and will also be called if there is an error condition on the call or the call is complete. The rx SetArrivalProc() function is used by multicast Rx routines to build a selection function that determines which of several calls is likely to be a good one to read from. The implementor's comments in the Rx code state that, due to the current implementation, it is probably only reasonable to use rx SetArrivalProc() immediately after an rx NewCall(), and to only use it once.
- Error Codes
- —None.