getsockopt()

Get options associated with a socket

Synopsis:

#include <sys/types.h>
#include <sys/socket.h>

int getsockopt( int s,
                int level,
                int optname,
                void * optval,
                socklen_t * optlen );

Arguments:

s
The file descriptor of the socket that the option is to be applied to, as returned by socket().
level
The protocol layer that the option is to be applied to. In most cases, it's a socket-level option and is indicated by SOL_SOCKET.
optname
The option for the socket file descriptor. For a list of options, see "Options," below.
optval
A pointer to the value of the option (in most cases, whether the option is to be turned on or off). If no option value is to be returned, optval may be NULL.

Most socket-level options use an int parameter for optval. Others, such as the SO_LINGER, SO_SNDTIMEO, and SO_RCVTIMEO options, use structures that also let you get data associated with the option.

optlen
A pointer to the length of the value of the option. This argument is a value-result parameter; initialize it to indicate the size of the buffer pointed to by optval.

Library:

libsocket

Use the -l socket option to qcc to link against this library.

Description:

The getsockopt() function gets options associated with a socket.

Manipulating socket options

When manipulating a socket option, you must specify the option's name (optname) and the level (level) at which the option resides.

To manipulate options at the socket-level, specify level as SOL_SOCKET. When manipulating options any other level, the value that you specify for level is represented by the protocol number of the appropriate protocol controlling the option. You can obtain the value in a variety of ways:

Note: The latter two ways might not work if you have customized /etc/protocols.

The optname parameter and any specified options are passed uninterpreted to the appropriate protocol module for interpretation. The <sys/socket.h> header file contains definitions for the socket-level options. Options at other protocol levels vary in format and name.

Note: Since levels (e.g. SOL_SOCKET, IPPROTO_IP and IPPROTO_TCP) and the options within the levels can vary, you need to ensure the proper headers are included for both. For example, when setting TCP_NODELAY:
int on = 1;
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));

the level IPPROTO_TCP is defined in <netinet/in.h>, whereas the TCP_NODELAY option is defined in <netinet/tcp.h>.

Options

This section describes some of the more common options and their corresponding level:

IPPROTO_IP:
IP_HDRINCL · IP_TOS
SOL_SOCKET:
SO_BINDTODEVICE · SO_BROADCAST · SO_DEBUG · SO_DONTROUTE · SO_ERROR · SO_KEEPALIVE · SO_LINGER · SO_OOBINLINE · SO_RCVBUF · SO_SNDBUF · SO_RCVLOWAT · SO_RCVTIMEO · SO_REUSEADDR · SO_REUSEPORT · SO_SNDLOWAT · SO_SNDTIMEO · SO_TIMESTAMP · SO_TYPE · SO_USELOOPBACK
IPPROTO_TCP
TCP_KEEPALIVE · TCP_NODELAY
Note: Except where noted, you can examine the state of the option by calling getsockopt(), and set the state by calling setsockopt().

IP_HDRINCL

level: IPPROTO_IP

Get or set the custom IP header that's included with your data. You can use it only for raw sockets. For example:

(socket(AF_INET, SOCK_RAW, ...)

IP_TOS

level: IPPROTO_IP

Get or set the type-of-service field in the IP header for SOCK_STREAM and SOCK_DGRAM sockets.

SO_BINDTODEVICE

level: SOL_SOCKET

Applies to setsockopt() only.

Allow packets to be sent or received on this specified interface only. If the interface specified conflicts with the parameters of bind(), or with the routing table, an error or undesired behavior may occur.

This option accepts the ifreq structure with the ifr_name member set to the interface name (e.g. en0). Currently, you can use this option only for UDP sockets.

SO_BROADCAST

level: SOL_SOCKET

Enable or disable the permission to transmit broadcast messages. You can use this option only for UDP sockets. For example:

(socket(AF_INET, SOCK_DGRAM, ...))

"Broadcast" was a privileged operation in earlier versions of the system.

SO_DEBUG

level: SOL_SOCKET

Enable or disable the recording of debug information in the underlying protocol modules.

SO_DONTROUTE

level: SOL_SOCKET

Enable or disable the bypassing of routing tables for outgoing messages. Indicates that outgoing messages should bypass the standard routing facilities. The messages are directed to the appropriate network interface according to the network portion of the destination address.

SO_ERROR

level: SOL_SOCKET

Applies to getsockopt() only.

Get any pending error on the socket and clears the error status. You can use it to check for asynchronous errors on connected datagram sockets or for other asynchronous errors.

SO_KEEPALIVE

level: SOL_SOCKET

Enable or disable the periodic (at least every 2 hours) transmission of messages on a connected socket. Should the connected party fail to respond to these messages, the connection is considered broken, and processes that are using the socket are notified via a SIGPIPE signal when they attempt to send data. See "Keepalive timing," below.

SO_LINGER

level: SOL_SOCKET

Controls the action that's taken when unsent messages are queued on socket when a close() is performed.

If it's enabled and the socket promises reliable delivery of data, the system blocks the process on the close() attempt until it's able to transmit the data or until it decides it can't deliver the information (a timeout period, termed the linger interval, is specified in the setsockopt() call when SO_LINGER is requested).

If it's disabled, the system processes the close() in a way that lets the process continue as quickly as possible.

The struct linger parameter (defined in <sys/socket.h>) specifies the desired state of the option in the l_onoff field and the linger interval in the l_linger field, in seconds. A value of 0 causes a reset on the socket when the application closes the socket.

SO_OOBINLINE

level: SOL_SOCKET

For protocols that support out-of-band data, allows or disallows out-of-band data to be placed in the normal data input queue as received. The data is accessible using the recv() or read() calls without the MSG_OOB flag. Some protocols always behave as if this option is set.

SO_RCVBUF and SO_SNDBUF

level: SOL_SOCKET

Gets or sets the normal buffer sizes allocated for output (SO_SNDBUF) and input (SO_RCVBUF) buffers. You can increase the buffer size for high-volume connections, or decrease it to limit the possible backlog of incoming data. The system places an absolute limit on these values and defaults them to at least 16K for TCP sockets.

SO_RCVLOWAT

level: SOL_SOCKET

Gets or sets the minimum count for input operations (default is 1). In general, receive calls block until any (nonzero) amount of data is received, and then return with the amount available or the amount requested, whichever is smaller.

If you set the value to be larger than the default, blocking receive calls will wait until they've received the low-water mark value or the requested amount, whichever is smaller. Receive calls may still return less than the low-water mark if: an error occurs, a signal is caught, or if the type of data next in the receive queue differs from that returned.

SO_RCVTIMEO

level: SOL_SOCKET

Gets or sets a timeout value for input operations. It accepts a struct timeval parameter (defined in <sys/time.h>) with the number of seconds and microseconds used to limit waits for input operations to complete.

In the current implementation, this timer is restarted each time additional data is received by the protocol, so the limit is in effect an inactivity timer. If a receive operation has been blocked for this much time without receiving additional data, it returns with a short count or, if no data was received, with the error EWOULDBLOCK.

SO_REUSEADDR

level: SOL_SOCKET

Enables or disables the reuse of duplicate addresses and port bindings. Indicates that the rules used in validating addresses supplied in a bind() call allows/disallows local addresses to be reused.

SO_REUSEPORT

level: SOL_SOCKET

Enables or disables duplicate address and port bindings. Complete duplicate bindings by multiple processes are allowed when they all set SO_REUSEPORT before binding the port. This option permits multiple instances of a program to each receive UDP/IP multicast or broadcast datagrams destined for the bound port. See the reuseport_unicast option of io-pkt to see how unicast packets are also received on all sockets bound to the same port.

SO_SNDLOWAT

level: SOL_SOCKET

Gets or sets the minimum count for output operations. In BSD, this count is typically 2048, but it is a calculated value in Neutrino. If you require a specific SO_SNDLOWAT, you must specify the count. Most output operations process all of the data supplied by the call, delivering data to the protocol for transmission and blocking as necessary for flow control. Nonblocking output operations will process as much data as permitted (subject to flow control without blocking), but will process no data if flow control doesn't allow the smaller of the low-water mark value or the entire request to be processed.

A select() operation that tests the ability to write to a socket returns true only if the low-water mark amount could be processed.

SO_SNDTIMEO

level: SOL_SOCKET

Gets or sets a timeout value for output operations. It accepts a struct timeval parameter (defined in <sys/time.h>) that includes the number of seconds and microseconds that are used to limit waits for output operations to complete. If a send operation has blocked for this much time, it returns with a partial count or with the error EWOULDBLOCK if data weren't sent.

This timer is restarted each time additional data is delivered to the protocol, implying that the limit applies to output portions ranging in size from the low-water mark to the high-water mark for output. Timeouts are restricted to 32 seconds or under.

SO_TIMESTAMP

level: SOL_SOCKET

Enables or disables the reception of a timestamp with datagrams. If enabled on a SOCK_DGRAM socket, the recvmsg() call returns a timestamp corresponding to when the datagram was received. The msg_control field in the msghdr structure points to a buffer that contains a cmsghdr structure followed by a struct timeval. The cmsghdr fields have the following values:

cmsg_len = sizeof(struct cmsghdr) + sizeof(struct timeval)
cmsg_level = SOL_SOCKET
cmsg_type = SCM_TIMESTAMP

SO_TYPE

level: SOL_SOCKET

Applies to getsockopt() only.

Gets the type of the socket (e.g. SOCK_STREAM). This information is useful for servers that inherit sockets on startup.

SO_USELOOPBACK

level: SOL_SOCKET

Enables or disables the sending process to receive its own routing messages.

TCP_KEEPALIVE

level: IPPROTO_TCP

Gets or sets the amount of time in seconds between keepalive probes (the default value is 2 hours). It accepts a struct timeval parameter with the number of seconds to wait between the keepalive probes. See "Keepalive timing," below.

TCP_NODELAY

level: IPPROTO_TCP

Don't delay sending in order to coalesce packets. Under most circumstances, TCP sends data when it's presented. When outstanding data hasn't yet been acknowledged, TCP gathers small amounts of output to be sent in a single packet once an acknowledgment is received.

Note: For a few clients (such as windowing systems that send a stream of mouse events that receive no replies), this packetization may cause significant delays. Therefore, TCP provides a boolean option, TCP_NODELAY, to defeat this algorithm.

Keepalive timing

Use the SO_KEEPALIVE option to turn on keepalive probes, and the TCP_KEEPALIVE option to set the amount of idle time before a probe is sent out (the default is 7200 seconds, or two hours).

You can set the number of probes to send out and the interval between probes by using the sysctl() function, which modifies or queries the state of the socket manager. The documentation for the sysctl utility includes information on identifiers related to keepcnt and keepintvl. The default number of unsuccessful probes before the socket is considered broken is 8, and the interval between probes defaults to 75 seconds.

Here's an example of turning on a socket keepalive with a 20-second idle time, then up to 3 probes, 5 seconds apart:

int mib[4];
int on=1, ival;
struct timeval tval;

mib[0] = CTL_NET;
mib[1] = AF_INET;
mib[2] = IPPROTO_TCP;
mib[3] = TCPCTL_KEEPCNT;
ival = 3; /* Number of keepalive probe attempts
             (default is 8) */
sysctl(mib, 4, NULL, NULL, &ival, sizeof(ival));

mib[0] = CTL_NET;
mib[1] = AF_INET;
mib[2] = IPPROTO_TCP;
mib[3] = TCPCTL_KEEPINTVL;
ival = 10; /* Half seconds between probe attempts;
              default is 150 (75 sec) */
sysctl(mib, 4, NULL, NULL, &ival, sizeof(ival));

memset(&tval, 0, sizeof(tval));
tval.tv_sec = 20;  /* Seconds of idle time before probing
                      starts (default is 7200) */
setsockopt(fdi, SOL_SOCKET, SO_KEEPALIVE, (void *) &on,
           sizeof(on));
setsockopt(fdi, IPPROTO_TCP, TCP_KEEPALIVE, (void *) &tval,
           sizeof(tval);
Note: Beware that the sysctl() calls above make system-wide changes that persist after the process finishes executing.

Returns:

0
Success.
-1
An error occurred (errno is set).

Errors:

EBADF
Invalid file descriptor s.
EDOM
Value was set out of range.
EFAULT
The address pointed to by optval isn't in a valid part of the process address space. For getsockopt(), this error may also be returned if optlen isn't in a valid part of the process address space.
EINVAL
The optval argument can't be NULL; optlen can't be 0.
ENOPROTOOPT
The option is unknown at the level indicated.

Classification:

POSIX 1003.1

Safety:  
Cancellation point No
Interrupt handler No
Signal handler No
Thread Yes