Previous section.
Technical Standard: Networking Services (XNS), Issue 5.2 Draft 2.0
Copyright © 1999 The Open Group
The Use of Options in XTI
Generalities
The functions
t_accept(),
t_connect(),
t_listen(),
t_optmgmt(),
t_rcvconnect(),
t_rcvudata(),
t_rcvuderr()
and
t_sndudata()
contain an
opt
argument of type
struct netbuf
as an input or output parameter.
This argument is used to convey options between the transport user and the
transport provider.
There is no general definition about the possible contents of options.
There are general XTI options and those that are specific for
each transport provider.
Some options allow the user to tailor his communication needs, for instance by
asking for high throughput or low delay.
Others allow the fine-tuning of the
protocol behaviour so that communication with unusual characteristics can be
handled more effectively.
Other options are for debugging purposes,
or to request that certain operations should be performed.
Options values have meaning to, and are defined by,
the protocol level in which they apply.
In some cases, option values can be negotiated by a transport user.
This includes the simple case where the transport user can simply
enforce its use.
Often, the transport provider or even the remote transport user may have the
right to negotiate a value of lesser quality than a proposed one,
that is, a delay may become longer, or a throughput may become lower.
It is useful to differentiate between options with end-to-end significance
(sometimes referred to as association-related1
and those that are not.
Association-related options are intimately related to the particular
transport connection or datagram transmission.
If the calling user specifies
such an option, some ancillary information is transferred across
the network in most cases.
The interpretation and further processing of this information is
protocol-dependent.
For instance, in an ISO connection-mode communication,
the calling user may specify quality-of-service parameters on connection
establishment.
These are first processed and possibly lowered by the local
transport provider, then sent to the remote transport provider that may
degrade them again, and finally conveyed to the called user that makes the
final selection and transmits the selected values back to the caller.
Options without end-to-end significance
do not contain information destined for the remote transport user.
Some have purely local relevance, for example, an option that enables debugging.
Others influence the transmission, for instance the option that sets the
T_IP time-to-live field, or T_TCP_NODELAY (see
Use of XTI with Internet Protocols).
Local options are negotiated solely between the transport user and the local
transport provider.
The distinction between these two categories of options is
visible in XTI through the following relationship:
on output, the functions
t_listen()
and
t_rcvudata()
return options with end-to-end significance only.
The functions
t_rcvconnect()
and
t_rcvuderr()
may return options of both categories. On input, options of both categories
may be specified with
t_accept()
and
t_sndudata().
The functions
t_connect()
and
t_optmgmt()
can process and return both categories of options.
Options can be further distinguished between those which maintain a
persistent value and those which are requests to perform actions
to which the option values are effectively parameters.
For each action that it supports and that maintains a
persistent value, the transport provider has a default value.
These defaults are sufficient for the majority
of communication relations.
Hence, a transport user should only request
options actually needed to perform the task,
and leave all others at their default value.
This chapter describes the general framework for the use of options.
This framework is obligatory for all transport providers.
The specific options that are legal
for use with a specific transport provider are described in the
provider-specific appendices (see
Use of XTI with ISO Transport Protocols
and
Use of XTI with Internet Protocols).
General XTI options are described in
t_optmgmt.
The Format of Options
Options are conveyed via an
opt
argument of
struct netbuf.
Each option in the buffer specified is of the form
struct t_opthdr
possibly followed by an option value.
A transport provider embodies a stack of protocols.
The
level
field of
struct t_opthdr
identifies the XTI level or a protocol of the transport provider
such as T_TCP or ISO 8073:1986.
The
name
field identifies the option within the level, and
len
contains its
total length, that is, the length of the option header
t_opthdr
plus the length of the option value.
The
status
field is used by the XTI level or the transport provider to indicate
success or failure of a negotiation
(see
Retrieving Information about Options
and
t_optmgmt).
Several options can be concatenated. The option user has, however to
ensure that each options header and value part starts at a boundary
appropriate for the architecture-specific alignment rules. The macros
T_OPT_FIRSTHDR(nbp), T_OPT_NEXTHDR(nbp, tohp), T_OPT_DATA(tohp)
are provided for that purpose. These macros are defines in
the man-page for
t_optmgmt()(
see
t_optmgmt).
T_OPT_FIRSTHDR is useful for finding
an appropriately aligned start of the option buffer.
T_OPT_NEXTHDR is useful for moving to the start
of the next appropriately aligned
option in the option buffer. Note that
OPT_NEXTHDR is also available for backward compatibility
requirements. T_OPT_DATA is useful for finding the start of
the data part in the option buffer where the contents of its
values start on an appropriately aligned boundary.
The length of the option buffer is given by
opt.len.
The alignment characters are included in the length.
The Elements of Negotiation
This section describes the general rules governing the passing and
retrieving of options and the error conditions that can occur.
Unless explicitly restricted, these rules
apply to all functions that allow the exchange of options.
Multiple Options and Options Levels
When multiple options are specified in an option buffer on input,
different rules apply to the levels that may be specified, depending
on the function call.
Multiple options specified on input to
t_optmgmt()
must address
the same option level.
Options specified on input to
t_connect(),
t_accept()
and
t_sndudata()
can address different levels.
Illegal Options
Only legal options can be negotiated; illegal options cause failure.
An option is illegal if the following applies:
-
The length specified in
t_opthdr.len
exceeds the remaining size
of the option buffer (counted from the beginning of the option).
-
The option value is illegal. The legal values are defined for each option.
(See
t_optmgmt
and the protocol specific appendices where options are
described for specific protocols).
If an illegal option is passed to XTI, the following will happen:
-
If an illegal option is passed to
t_optmgmt()
then the function fails with
t_errno
set to [TBADOPT].
-
If an illegal option is passed to
t_accept()
or
t_connect()
then either the function fails with
t_errno
set to [TBADOPT] or the
connection establishment fails at a later stage, depending on
when the implementation detects the illegal option.
-
If an illegal option is passed to
t_sndudata()
then either the
function fails with
t_errno
set to {TBADOPT] or it successfully
returns but a T_UDERR event occurs to indicate that the datagram
was not sent.
If the transport user passes multiple options in one call and one of them is
illegal, the call fails as described above. It is, however, possible that
some or even all of the submitted legal options were successfully
negotiated.
The transport user can check the current status by a call to
t_optmgmt()
with the T_CURRENT flag set (see
t_optmgmt).
Specifying an option level unknown to the transport provider does
not cause failure in calls to
t_connect(),
t_accept()
or
t_sndudata();
the option is discarded in these cases. The function
t_optmgmt()
fails with [TBADOPT].
Specifying an option name that is unknown to or not supported by the
protocol selected by the option level does not cause failure.
The option is discarded in calls to
t_connect(),
t_accept()
or
t_sndudata().
The function
t_optmgmt()
returns T_NOTSUPPORT in the
status
field of the option.
Initiating an Option Negotiation
A transport user initiates an option negotiation when calling
t_connect(),
t_sndudata()
or
t_optmgmt()
with the flag T_NEGOTIATE set.
The negotiation rules for these functions depend on
whether an option request is an absolute requirement or not.
This is explicitly defined for each option
(see
t_optmgmt
and the protocol specific appendices where options are
described for specific protocols).
In case of an ISO transport provider, for example, the option that requests
use of expedited data is not an absolute requirement. On the other hand, the
option that requests protection could be an absolute requirement.
- Note:
- The notion "absolute requirement" originates from the
quality-of-service parameters in ISO 8072:1986.
Its use is extended here to all options.
If the proposed option value is an absolute requirement, three outcomes are
possible:
-
The negotiated value is the same as the proposed one.
When the result of the negotiation is retrieved, the
status
field in
t_opthdr
is set to T_SUCCESS.
-
The negotiation is rejected if the option is supported but the proposed
value cannot be negotiated.
This leads to the following behaviour:
-
t_optmgmt()
successfully returns, but the returned option has its
status
field set to T_FAILURE.
-
Any attempt to establish a connection aborts; a T_DISCONNECT event occurs,
and a synchronous call to
t_connect()
fails with [TLOOK].
-
t_sndudata()
fails with [TLOOK] or successfully returns, but a T_UDERR event occurs to
indicate that the datagram was not sent.
If multiple options are submitted in one call and one of them is rejected,
XTI behaves as just described.
Although the connection establishment or the datagram
transmission fails, options successfully negotiated before some option was
rejected retain their negotiated values. There is no roll-back mechanism (see
Option Management of a Transport Endpoint).
The function
t_optmgmt()
attempts to negotiate each option. The
status
fields of the returned options indicate success (T_SUCCESS) or
failure (T_FAILURE).
-
If the local transport provider does not support the option at all,
t_optmgmt()
reports T_NOTSUPPORT in the
status
field.
The functions
t_connect()
and
t_sndudata()
ignore this option.
If the proposed option value is not an absolute requirement, two outcomes
are possible:
Unsupported options
do not cause functions to fail or a connection to abort,
since different vendors possibly implement different subsets of options.
Furthermore, future enhancements of XTI
might encompass additional options that are unknown to earlier
implementations of transport providers.
The decision whether or not the missing support of an option
is acceptable for the communication is left to the transport user.
The transport provider does not check for multiple occurrences of the same
option, possibly with different option values.
It simply processes the options in the option buffer one after the other.
However, the user should not make any assumption about the order of processing.
Not all options are independent of one another. A requested option value
might conflict with the value of another option that was specified in the same
call or is currently effective (see
Option Management of a Transport Endpoint).
These conflicts may not be detected at once, but later they
might lead to unpredictable results.
If detected at negotiation time, these conflicts are resolved
within the rules stated above.
The outcomes may thus be quite different and depend on whether
absolute or non-absolute requests are involved in the conflict.
Conflicts are usually detected at the time a connection is established or a
datagram is sent. If options are negotiated with
t_optmgmt(),
conflicts are usually not detected at this time, since independent processing
of the requested options must allow for temporal inconsistencies.
When called, the functions
t_connect()
and
t_sndudata()
initiate a negotiation of
all
options with end-to-end significance according to the rules of this section.
Options not explicitly specified in the function calls themselves
are taken from an internal option buffer that contains the values of a
previous negotiation (see
Option Management of a Transport Endpoint).
Responding to a Negotiation Proposal
In connection-mode communication, some protocols give the peer transport
users the opportunity to negotiate characteristics of the transport
connection to be established.
These characteristics are options with end-to-end significance.
With the connection indication, the called user receives (via
t_listen())
a proposal about the option values that should be effective for this
connection. The called user can accept this proposal or weaken it by choosing
values of lower quality (for example, longer delays than proposed). The
called user can, of course, refuse the connection establishment altogether.
The called user responds to a negotiation proposal via
t_accept().
If the called transport user tries to negotiate an option of higher quality
than proposed, the outcome depends on the protocol to which that
option applies.
Some protocols may reject the option, some protocols take other
appropriate action described in protocol-specific appendices.
If an option is rejected, the following error occurs:
-
-
The connection fails; a T_DISCONNECT event occurs.
It depends on timing and implementation conditions whether the
t_accept()
call still succeeds or fails with [TLOOK].
If multiple options are submitted with
t_accept()
and one of them is rejected, the connection fails as described above.
Options that could be successfully negotiated before the
erroneous option was processed retain their negotiated value.
There is no roll-back mechanism (see
Option Management of a Transport Endpoint).
The response options can be specified with the
t_accept()
call. Alternatively, they can be specified by calling
t_optmgmt()
and passing it the file
descriptor that will subsequently be passed as
resfd
to
t_accept()
to identify the responding endpoint (see
Option Management of a Transport Endpoint.
In case of conflict between option settings
made by calls to
t_optmgmt()
and
t_accept()
at different times, the latest settings when
t_accept()
is called shall prevail. Note that the response to a negotiation
proposal is activated when
t_accept()
is called. A
t_optmgmt()
call with erroneous option values as
described above shall succeed; the connection aborts at the time
t_accept()
is called.
The connection also fails if the selected option values lead to
contradictions.
The function
t_accept()
does not check for multiple specification of an option (see
Initiating an Option Negotiation).
Unsupported options are ignored.
Retrieving Information about Options
This section describes how a transport user can retrieve information about
options.
To be explicit, a transport user must be able to:
-
know the result of a negotiation (for example, at the end of a connection
establishment)
-
know the proposed option values under negotiation (during connection
establishment)
-
retrieve option values sent by the remote transport user for notification
only (for example, T_IP options)
-
check option values currently effective for the transport endpoint.
To this end, the functions
t_connect(),
t_listen(),
t_optmgmt(),
t_rcvconnect(),
t_rcvudata()
and
t_rcvuderr()
take an output argument
opt
of
struct netbuf.
The transport user has to supply a buffer where the options shall be
written to;
opt.buf
must point to this buffer, and
opt.maxlen
must contain the buffer's size.
The transport user can set
opt.maxlen
to zero to indicate that no options are to be retrieved.
Which options are returned depend on the function call involved:
- t_connect() (synchronous mode) and t_rcvconnect()
The functions return the values of all options with end-to-end significance
that were received with the connection response and the negotiated
values of those options without end-to-end significance that had been
specified on input. However, options specified on input in the
t_connect()
call that are not supported or refer to an unknown option level are discarded
and not returned on output.
The status field of each option returned with
t_connect()
or
t_rcvconnect()
indicates if the proposed value (T_SUCCESS)
or a degraded value (T_PARTSUCCESS) has been negotiated.
The status field of received ancillary information
(for example, T_IP
options) that is not subject to negotiation is always set to
T_SUCCESS.
- t_listen()
- The received options with end-to-end significance are related to the incoming
connection (identified by the sequence number), not to the listening endpoint.
(However, the option values currently effective for the listening endpoint
can affect the values retrieved by
t_listen(),
since the transport provider might be involved in the negotiation process,
too.) Thus, if the same options are specified in a call to
t_optmgmt()
with action T_CURRENT,
t_optmgmt()
will usually not return the same values.
The number of received options may be variable for subsequent connection
indications, since many options with end-to-end significance are only
transmitted on explicit demand by the calling user
(for example, T_IP options or ISO 8072:1986 throughput).
It is even possible that no options at all are returned.
The
status
field is irrelevant.
- t_rcvudata()
- The received options with end-to-end significance are related to the incoming
datagram, not to the transport endpoint
fd.
Thus, if the same options are specified in a call to
t_optmgmt()
with action T_CURRENT,
t_optmgmt()
will usually not return the same values.
The number of options received may vary from call to call.
The
status
field is irrelevant.
- t_rcvuderr()
- The returned options are related to the options input at the
previous
t_sndudata()
call that produced the error. Which options are returned and which values
they have depend on the specific error condition.
The
status
field is irrelevant.
- t_optmgmt()
- This call can process and return both categories of options.
It acts on options related to the specified transport endpoint,
not on options related to a connection indication or an incoming datagram.
A detailed description is given in
t_optmgmt.
Privileged and Read-only Options
Privileged
options or option values are those that may be requested by
privileged users only.
The meaning of privilege is hereby implementation-defined.
Read-only
options serve for information purposes only.
The transport user may be allowed to read the option value but
not to change it.
For instance, to select the
value of a protocol timer or the maximum length of a protocol data unit
may be too subtle to leave to the transport user,
though the knowledge about this value might be of some interest.
An option might be read-only for all users or solely for non-privileged users.
A privileged option might be inaccessible or read-only for
non-privileged users.
An option might be negotiable in some XTI states and read-only in other
XTI states.
For instance, the ISO quality-of-service options are
negotiable in the states T_IDLE and T_INCON and read-only in all other states
(except T_UNINIT).
If a transport user requests negotiation of a read-only option, or a
non-privileged user requests illegal access to a privileged option, the
following outcomes are possible:
-
t_optmgmt()
successfully returns, but the returned option has its
status
field set to T_NOTSUPPORT if a privileged option was requested illegally,
and to T_READONLY if modification of a read-only option was requested.
-
If negotiation of a read-only option is requested,
t_accept()
or
t_connect()
either fail with [TACCES], or
the connection establishment aborts and a T_DISCONNECT event occurs.
If the connection aborts, a synchronous call to
t_connect()
fails with [TLOOK].
It depends on timing and implementation conditions whether a
t_accept()
call still succeeds or fails with [TLOOK].
If a privileged option is illegally requested, the option is quietly ignored.
(A non-privileged user shall not be able to select an option
which is privileged or unsupported.)
-
If negotiation of a read-only option is requested,
t_sndudata()
may return [TLOOK] or successfully return,
but a T_UDERR event occurs to indicate that the datagram was not sent.
If a privileged option is illegally requested, the option is quietly ignored.
(A non-privileged user shall not be able to select an option
which is privileged or unsupported.)
If multiple options
are submitted to
t_connect(),
t_accept()
or
t_sndudata()
and a read-only option is rejected, the connection or the datagram
transmission fails as described.
Options that could be successfully negotiated before the
erroneous option was processed retain their negotiated values.
There is no roll-back mechanism (see also
Option Management of a Transport Endpoint).
Option Management of a Transport Endpoint
This section describes how option management works during the lifetime of a
transport endpoint.
Each transport endpoint is (logically) associated with an internal option
buffer. When a transport endpoint is created, this buffer is filled with a
system default value for each supported option.
Depending on the option,
the default may be `OPTION ENABLED', `OPTION DISABLED' or
denote a time span, etc.
These default settings are appropriate for most uses.
Whenever an option value is modified in the course of an option
negotiation, the modified value is written to this buffer and
overwrites the previous one.
At any time, the buffer contains all option values that are
currently effective for this transport endpoint.
The current value of an option
can be retrieved at any time by calling
t_optmgmt()
with the flag T_CURRENT set. Calling
t_optmgmt()
with the flag T_DEFAULT set yields the system default for the specified option.
A transport user can negotiate new option values by calling
t_optmgmt()
with the flag T_NEGOTIATE set. The negotiation follows the rules described in
The Elements of Negotiation.
Some options may be modified only in specific XTI states and are read-only in
other XTI states. Many options with end-to-end significance,
for instance, may not be
changed in the state T_DATAXFER, and an attempt to do so will fail (see
Privileged and Read-only Options).
The legal states for each option are specified with its definition.
As usual, options with end-to-end significance
take effect at the time a connection is
established or a datagram is transmitted. This is the case if they
contain information that is transmitted across the network or determine
specific transmission characteristics.
If such an option is modified by a call to
t_optmgmt(),
the transport
provider checks whether the option is supported and negotiates a
value according to its current knowledge.
This value is written to the internal option buffer.
The final negotiation takes place if the connection is established or the
datagram is transmitted.
This can result in a degradation of the option value or even in a
negotiation failure.
The negotiated values are written to the internal option buffer.
Some options may be changed in the state T_DATAXFER, for example,
those specifying buffer sizes.
Such changes might affect the transmission characteristics and
lead to unexpected side effects (for example, data loss if a buffer size was
shortened) if the user does not care.
The transport user can explicitly specify both categories of
options on input when calling
t_connect(),
t_accept()
or
t_sndudata().
The options are at first locally negotiated option-by-option,
and the resulting values written to the internal option buffer.
The modified option buffer is then used if a further negotiation step
across the network is required, as for instance in connection-oriented
ISO communication.
The newly negotiated values are then written to the internal option buffer.
At any stage, a negotiation failure can lead to an abort of the
transmission.
If a transmission aborts, the option buffer will preserve the
content it had at the time the failure occurred.
Options that could be negotiated just before the error occurred
are written back to the option buffer, whether the XTI call fails or
succeeds.
It is up to the transport user to decide which options it explicitly
specifies on input when calling
t_connect(),
t_accept()
or
t_sndudata().
The transport user need not pass options at all, by setting the
len field of the function's input
opt
argument to zero.
The current content of the internal option buffer is then used for
negotiation without prior modification.
The negotiation procedure for options at the time of a
t_connect(),
t_accept()
or
t_sndudata()
call always obeys the rules in
Initiating an Option Negotiation
and
Responding to a Negotiation Proposal,
whether the options were explicitly specified during the call or
implicitly taken from the internal option buffer.
The transport user should not make assumptions about the order in
which options are processed during negotiation.
A value in the option buffer is only modified as a result of a successful
negotiation of this option.
It is, in particular, not changed by a connection release.
There is no history mechanism that would restore the
buffer state existing prior to the connection establishment or the
datagram transmission.
The transport user must be aware that a connection establishment or a
datagram transmission may change the internal option buffer, even if each
option was originally initialised to its default value.
Supplements
This section contains supplementary remarks and a short summary.
The Option Value T_UNSPEC
Some options may not have a fully specified value all the time.
An ISO transport provider, for instance, that supports several
protocol classes, might not have a preselected preferred class
before a connection establishment is initiated.
At the time of the connection request, the
transport provider may conclude from the destination address,
quality-of-service parameters and other
locally available information which preferred class it should use.
A transport user asking for the default value of the preferred class option
in state T_IDLE would get the value T_UNSPEC.
This value indicates that the transport provider did not yet select a value.
The transport user could negotiate another value as the preferred class,
for example, T_CLASS2.
The transport provider would then be forced to initiate a connection
request with class 2 as the preferred class.
An XTI implementation may also return the value T_UNSPEC if it can
currently not access the option value.
This may happen, for example, in the state T_UNBND in systems where
the protocol stacks reside on separate controller cards and not in
the host.
The implementation may never return T_UNSPEC if the option is not
supported at all.
If T_UNSPEC is a legal value for a specific option, it
may be used by the user on input, too.
It is used to indicate that it is left to the provider to
choose an appropriate value.
This is especially useful in complex options as ISO throughput,
where the option value has an internal structure (see T_TCO_THROUGHPUT in
Use of XTI with ISO Transport Protocols).
The transport user may leave some fields unspecified by selecting this value.
If the user proposes T_UNSPEC, the transport provider is free to
select an appropriate value.
This might be the default value, some other explicit value, or T_UNSPEC.
Each option where it is legal to use T_UNSPEC specifies its use as
part of its description.
The info Argument
The functions
t_open()
and
t_getinfo()
return values representing
characteristics of the transport provider in the argument
info.
The value of
info->options
is used by
t_alloc()
to allocate storage for an option buffer to be used in an XTI call. The value
is sufficient for all uses.
In general,
info->options
also includes the size of privileged options, even
if these are not read-only for non-privileged users.
Alternatively, an implementation can choose to return different values in
info->options
for privileged and non-privileged users.
The values in
info->etsdu,
info->tsdu,
info->connect
and
info->discon
may be modified as soon as the T_DATAXFER state is entered.
Calling
t_optmgmt()
need not influence these values (see
t_optmgmt).
Summary
-
The format of an option
is defined by a header
struct t_opthdr,
followed by an option value.
-
On input, several options can be specified in an input
opt
argument.
Each option must begin on a t_uscalar_t boundary.
-
There are options with end-to-end significance and options
without end-to-end significance.
On output, the functions
t_listen()
and
t_rcvudata()
return options with end-to-end significance only.
The functions
t_rcvconnect()
and
t_rcvuderr()
may return
options of both categories.
On input, options of both categories may be specified with
t_accept()
and
t_sndudata().
The functions
t_connect()
and
t_optmgmt()
can process and return both categories of options.
-
A transport endpoint is (logically) associated with an internal
option buffer, where the currently effective values are stored.
Each successful negotiation of an option modifies this buffer,
regardless of whether the call initiating the negotiation succeeds or fails.
-
When calling
t_connect(),
t_accept()
or
t_sndudata(),
the transport user can choose to submit the currently effective option values
by setting the
len
field of the input
opt
argument to zero.
-
If a connection is accepted via
t_accept(),
the explicitly specified option values together with
the currently effective option values of
resfd,
not of
fd,
matter in this negotiation step.
-
The options returned by
t_rcvuderr()
are those negotiated with the outgoing datagram that produced the error. If
the error occurred during option negotiation, the returned option might
represent some mixture of partly negotiated and not-yet negotiated options.
Portability Aspects
An application programmer who writes XTI programs faces two portability
aspects:
-
portability across protocol profiles
-
portability across different system platforms (possibly from
different vendors).
Options are intrinsically coupled with a definite protocol or protocol profile.
Making explicit use of them therefore degrades portability across protocol
profiles.
Different vendors might offer transport providers with different option
support. This is due to different implementations and product policies. The
lists of options on the
t_optmgmt()
manual page and
in the protocol-specific appendices are maximal
sets but do not necessarily reflect common implementation practice.
Vendors will implement subsets that suit their needs.
Making careless use of options therefore endangers portability across
different system platforms.
Every implementation of a protocol profile accessible by XTI can be used with
the default values of options.
Applications can thus be written that do not care about options at all.
An application program that processes options retrieved from an XTI function
should discard options it does not know in order to lessen its dependence
from different system platforms and future XTI releases with possibly
increased option support.
Footnotes
- 1.
- The term "association" is used to denote a pair of communicating
transport users, that is, the communication has end-to-end significance.