Out-of-band data
Out-of-band (OOB) data is user-specific data that only has meaning for connection-oriented (stream) sockets.
Stream data is generally received in the same order it is sent. OOB data is received independent of its position in the stream (independent of the order in which it was sent). This is possible because the data is marked in such a way that, when it is sent from program A to program B, program B is notified of its arrival.
OOB data is supported on AF_INET (SOCK_STREAM) and AF_INET6 (SOCK_STREAM) only.
OOB data is sent by specifying the MSG_OOB flag on the send(), sendto(), and sendmsg() APIs.
The transmission of OOB data is the same as the transmission of regular data. It is sent after any data that is buffered. In other words, OOB data does not take precedence over any data that might be buffered; data is transmitted in the order that it was sent.
On the receiving side, things are a little more complex:
- The sockets API keeps track of OOB data that is received on a system by
using an OOB marker. The OOB marker points to the last byte in the OOB data
that was sent. Note: The value that indicates which byte the OOB marker points to is set on a system basis (all applications use that value). This value must be consistent between the local and remote ends of a TCP connection. Socket applications that use this value must use it consistently between the client and server applications.
The SIOCATMARK ioctl() request determines if the read pointer is pointing to the last OOB byte.
Note: If multiple occurrences of OOB data are sent, the OOB marker points to the last OOB byte of the final OOB data occurrence. - Independent of whether OOB data is received inline, an input operation processes data up to the OOB marker, if OOB data was sent.
- A recv(), recvmsg(),
or recvfrom() API (with the MSG_OOB flag set) is used to
receive OOB data. An error of [EINVAL] is returned if one of the receive APIs
has been completed and one of the following situations occurs:
- The socket option SO_OOBINLINE is not set and there is no OOB data to receive.
- The socket option SO_OOBINLINE is set.
If the socket option SO_OOBINLINE is not set, and the sending program sent OOB data with a size greater than one byte, all the bytes but the last are considered normal data. (Normal data means that the receiving program can receive data without specifying the MSG_OOB flag.) The last byte of the OOB data that was sent is not stored in the normal data stream. This byte can only be retrieved by issuing a recv(), recvmsg(), or recvfrom() API with the MSG_OOB flag set. If a receive operation is issued with the MSG_OOB flag not set, and normal data is received, the OOB byte is deleted. Also, if multiple occurrences of OOB data are sent, the OOB data from the preceding occurrence is lost, and the position of the OOB data of the final OOB data occurrence is remembered.
If the socket option SO_OOBINLINE is set, then all of the OOB data that was sent is stored in the normal data stream. Data can be retrieved by issuing one of the three receive APIs without specifying the MSG_OOB flag (if it is specified, an error of [EINVAL] is returned). OOB data is not lost if multiple occurrences of OOB data are sent.
- OOB data is not discarded if SO_OOBINLINE is not set, OOB data has been received, and the user then sets SO_OOBINLINE on. The initial OOB byte is considered normal data.
- If SO_OOBINLINE is not set, OOB data was sent, and the receiving program issued an input API to receive the OOB data, then the OOB marker is still valid. The receiving program can still check if the read pointer is at the OOB marker, even though the OOB byte was received.