GETSOCKOPT(2)
π GETSOCKOPT(2) π β System Calls Manual, bestie edition
okay so. this is the page for getsockopt and setsockopt, and it lives in section 2 (system calls) of the manual. yes the header says GETSOCKOPT(2) on both sides, that's just how manpages flex. sit down, hydrate, we're doing socket options π«Ά
β¨ NAME β¨
getsockopt, setsockopt β get and set options on sockets
π LIBRARY π
Standard C Library (libc, -lc)
πΈ SYNOPSIS πΈ
#include <sys/types.h>
#include <sys/socket.h>
int
getsockopt(int s, int level, int optname, void * restrict optval,
socklen_t * restrict optlen);
int
setsockopt(int s, int level, int optname, const void *optval,
socklen_t optlen);
π DESCRIPTION π
So getsockopt() and setsockopt() are the two system calls that mess with the options attached to a socket. and the way that options can exist at multiple protocol levels, like it's giving layered cake π β but they're always present at the topmost "socket" level. always. no cap.
When you're manipulating socket options you gotta specify two things: the level the option lives at, and the name of the option. To do it at the socket level, you set level to SOL_SOCKET. To do it at literally any other level, you pass the protocol number of whatever protocol controls that option. Like β say you want TCP to interpret the option? Then level should be the protocol number of TCP. see getprotoent(3). slay.
The optval and optlen arguments are how you actually get at the option values for setsockopt(). For getsockopt() they instead point at a buffer where the value(s) for the option(s) you asked for get returned. and for getsockopt(), optlen is a value-result argument β it starts out holding the size of the buffer that optval points to, and then on return it gets modified to show the actual size of the value that came back. iconic behavior honestly. If there's no option value being supplied or returned, optval can just be NULL.
The optname argument and any options you specify get passed uninterpreted to the appropriate protocol module to be interpreted. The include file <sys/socket.h> has the definitions for the socket level options, which are all listed below. Options at other protocol levels? different formats, different names β go consult the appropriate entries in section 4 of the manual. iykyk.
Most socket-level options use an int argument for optval. For setsockopt(), that argument should be non-zero to enable a boolean option, or zero if you're disabling it. SO_LINGER is the exception, it uses a struct linger argument defined in <sys/socket.h>, which specifies the desired state of the option and the linger interval (more on that below). SO_SNDTIMEO and SO_RCVTIMEO use a struct timeval argument, defined in <sys/time.h>.
The following options are recognized at the socket level. For protocol-specific options, go look at the protocol manual pages, e.g. ip(4) or tcp(4). Except where noted, each one can be examined with getsockopt() and set with setsockopt().
SO_DEBUGβ enables recording of debugging informationSO_REUSEADDRβ enables local address reuseSO_REUSEPORTβ enables duplicate address and port bindingsSO_REUSEPORT_LBβ enables duplicate address and port bindings with load balancingSO_KEEPALIVEβ enables keep connections aliveSO_DONTROUTEβ enables routing bypass for outgoing messagesSO_LINGERβ linger on close if data presentSO_BROADCASTβ enables permission to transmit broadcast messagesSO_OOBINLINEβ enables reception of out-of-band data in bandSO_SNDBUFβ set buffer size for outputSO_RCVBUFβ set buffer size for inputSO_SNDLOWATβ set minimum count for outputSO_RCVLOWATβ set minimum count for inputSO_SNDTIMEOβ set timeout value for outputSO_RCVTIMEOβ set timeout value for inputSO_ACCEPTFILTERβ set accept filter on listening socketSO_NOSIGPIPEβ controls generation ofSIGPIPEfor the socketSO_TIMESTAMPβ enables reception of a timestamp with datagramsSO_BINTIMEβ enables reception of a timestamp with datagramsSO_ACCEPTCONNβ get listening status of the socket (get only)SO_DOMAINβ get the domain of the socket (get only)SO_TYPEβ get the type of the socket (get only)SO_PROTOCOLβ get the protocol number for the socket (get only)SO_PROTOTYPEβ SunOS alias for the LinuxSO_PROTOCOL(get only)SO_ERRORβ get and clear error on the socket (get only)SO_SETFIBβ set the associated FIB (routing table) for the socket (set only)
The following options are recognized in FreeBSD:
SO_LABELβ get MAC label of the socket (get only)SO_PEERLABELβ get socket's peer's MAC label (get only)SO_LISTENQLIMITβ get backlog limit of the socket (get only)SO_LISTENQLENβ get complete queue length of the socket (get only)SO_LISTENINCQLENβ get incomplete queue length of the socket (get only)SO_USER_COOKIEβ set the'so_user_cookie'value for the socket (uint32_t, set only)SO_TS_CLOCKβ set specific format of timestamp returned bySO_TIMESTAMPSO_MAX_PACING_RATEβ set the maximum transmit rate in bytes per second for the socketSO_NO_OFFLOADβ disables protocol offloadsSO_NO_DDPβ disables direct data placement offload
SO_DEBUG enables debugging in the underlying protocol modules. π
SO_REUSEADDR says that the rules used for validating addresses supplied in a bind(2) system call should allow reuse of local addresses.
SO_REUSEPORT allows completely duplicate bindings by multiple processes β but only if they all set SO_REUSEPORT before binding the port. This option lets multiple instances of a program each receive UDP/IP multicast or broadcast datagrams destined for the bound port. team effort fr fr.
SO_REUSEPORT_LB also allows completely duplicate bindings by multiple processes, again only if they all set SO_REUSEPORT_LB before binding the port. Incoming TCP and UDP connections get distributed among the sharing processes based on a hash function of local port number, foreign IP address and port number. A maximum of 256 processes can share one socket. that's the limit bestie, no more.
SO_KEEPALIVE enables the periodic transmission of messages on a connected socket. If the connected party fails to respond to these messages, the connection is considered broken and processes using the socket get notified via a SIGPIPE signal when they attempt to send data. π
SO_DONTROUTE says outgoing messages should bypass the standard routing facilities. Instead, messages get directed to the appropriate network interface according to the network portion of the destination address. main character routing energy.
SO_LINGER controls what happens when unsent messages are queued on the socket and a close(2) is performed. If the socket promises reliable delivery of data and SO_LINGER is set, the system will block the process on the close(2) attempt until it's able to transmit the data, or until it decides it's unable to deliver the info. (the timeout period, called the linger interval, is specified in seconds in the setsockopt() system call when SO_LINGER is requested.) If SO_LINGER is disabled and a close(2) is issued, the system processes the close in a manner that lets the process continue as quickly as possible. bye bye speedrun πββοΈ
The option SO_BROADCAST requests permission to send broadcast datagrams on the socket. fun fact: broadcast was a privileged operation in earlier versions of the system. glow-up.
With protocols that support out-of-band data, the SO_OOBINLINE option requests that out-of-band data be placed in the normal data input queue as it's received; it's then accessible with recv(2) or read(2) calls without the MSG_OOB flag. Some protocols always behave as if this option is set. they're just like that.
SO_SNDBUF and SO_RCVBUF are options to adjust the normal buffer sizes allocated for output and input buffers, respectively. 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 maximum on these values, which is accessible through the sysctl(3) MIB variable "kern.ipc.maxsockbuf". don't try to fight the max, you won't win.
SO_SNDLOWAT is an option to set the minimum count for output operations. 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(2) operation testing the ability to write to a socket returns true only if the low water mark amount could be processed. The default value for SO_SNDLOWAT is set to a convenient size for network efficiency, often 1024.
SO_RCVLOWAT is an option to set the minimum count for input operations. In general, receive calls block until any (non-zero) amount of data is received, then return with the smaller of the amount available or the amount requested. The default value for SO_RCVLOWAT is 1. If SO_RCVLOWAT is set to a larger value, blocking receive calls normally wait until they've received the smaller of the low water mark value or the requested amount. Receive calls may still return less than the low water mark if an error occurs, a signal is caught, or the type of data next in the receive queue is different from that which was returned. rude but true.
SO_SNDTIMEO is an option to set a timeout value for output operations. It accepts a struct timeval argument with the number of seconds and microseconds 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 no data were sent. In the current implementation, this timer is restarted each time additional data are delivered to the protocol β meaning the limit applies to output portions ranging in size from the low water mark to the high water mark for output.
SO_RCVTIMEO is an option to set a timeout value for input operations. It accepts a struct timeval argument 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 are 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 with the error EWOULDBLOCK if no data were received.
okay and that's where part 1 wraps, but we're SO not done β more of this page is coming, don't go anywhere π¦
okay bestie we're back π and we're picking up right where we left off, mid-glow-up, mid-DESCRIPTION, no recap, let's GO πββοΈβ¨
SO_SETFIBβ lets you over-ride the default FIB (that's the routing table, iykyk πΊοΈ) for the socket you're holding. The value has to be from0to one less than whateversysctl net.fibshands back. No cap.SO_USER_COOKIEβ sets theuint32_tso_user_cookiefield inside the socket. The value is auint32_t, and kernel code that messes with traffic related to that socket can use it. The default for this field is0. Fr example, you can use the value as theskiptotarget or as a pipe number inipfw/dummynet. She's useful πSO_ACCEPTFILTERβ places anaccept_filter(9)on the socket, which filters incoming connections on a listening stream socket before they get presented toaccept(2). And once more for the people in the back: you must calllisten(2)on the socket before you try to install the filter, or elsesetsockopt()will just fail on you. Tragic but true π
struct accept_filter_arg {
char af_name[16];
char af_arg[256-16];
};
The optval argument should point to a struct accept_filter_arg that selects and configures the accept_filter(9). Fill af_name with the name of the accept filter your app wants to place on the listening socket. The optional af_arg gets passed along to the filter named in af_name, so you can hand over extra config options at attach time. And if you pass an optval of NULL? Bye bye filter, it's removed π«Ά
SO_NOSIGPIPEβ controls generation of theSIGPIPEsignal. You know the one, it's normally sent when you write to a connected socket whose other end has been closed, and the write comes back with theEPIPEerror. This option says "not today" β¨SO_TIMESTAMP/SO_BINTIMEβ if either is enabled on aSOCK_DGRAMsocket, therecvmsg(2)call may return a timestamp for when the datagram was received. May. Not will. Sometimes there's a resource shortage and it just doesn't, okay π Themsg_controlfield in themsghdrstructure points to a buffer holding acmsghdrstructure followed by astruct timevalforSO_TIMESTAMPand astruct bintimeforSO_BINTIME. Here's what thecmsghdrfields look like forTIMESTAMPby default:
cmsg_len = CMSG_LEN(sizeof(struct timeval));
cmsg_level = SOL_SOCKET;
cmsg_type = SCM_TIMESTAMP;
and for SO_BINTIME:
cmsg_len = CMSG_LEN(sizeof(struct bintime));
cmsg_level = SOL_SOCKET;
cmsg_type = SCM_BINTIME;
More timestamp types? Obsessed. You get them by following SO_TIMESTAMP with SO_TS_CLOCK, which requests a specific timestamp format to come back instead of SCM_TIMESTAMP when SO_TIMESTAMP is enabled. These SO_TS_CLOCK values are recognized in FreeBSD πΈ
SO_TS_REALTIME_MICROβ realtime (SCM_TIMESTAMP,struct timeval), the default πSO_TS_BINTIMEβ realtime (SCM_BINTIME,struct bintime)SO_TS_REALTIMEβ realtime (SCM_REALTIME,struct timespec)SO_TS_MONOTONICβ monotonic time (SCM_MONOTONIC,struct timespec)
SO_ACCEPTCONN, SO_TYPE, SO_PROTOCOL (and its alias SO_PROTOTYPE) and SO_ERROR are the read-only girlies β options used only with getsockopt(). Let's break it down:
SO_ACCEPTCONNβ returns whether the socket is currently accepting connections, aka whether or notlisten(2)was ever invoked on it.SO_TYPEβ returns the type of the socket, likeSOCK_STREAM. Super handy for servers that inherit sockets on startup π§SO_PROTOCOLβ returns the protocol number for the socket, forAF_INETandAF_INET6address families.SO_ERRORβ returns any pending error on the socket and clears the error status. Use it to check for asynchronous errors on connected datagram sockets, or for other asynchronous errors. Note that clearing part, bestie, it's giving "look but also it's gone now" πSO_LABELβ returns the MAC label of the socket.SO_PEERLABELβ returns the MAC label of the socket's peer. Heads up: your kernel must be compiled with MAC support. Seemac(3)for the details.SO_LISTENQLIMITβ returns the maximal number of queued connections, as set bylisten(2).SO_LISTENQLENβ returns the number of unaccepted complete connections.SO_LISTENINCQLENβ returns the number of unaccepted incomplete connections.SO_MAX_PACING_RATEβ instructs the socket and the underlying network adapter layers to limit the transfer rate to the given unsigned 32-bit value, in bytes per second. Slow it down, queen πSO_NO_OFFLOADβ disables support for protocol offloads. At present, this stops TCP sockets from using TCP offload engines.SO_NO_DDPβ disables support for one specific TCP offload known as direct data placement (DDP). DDP is an offload supported by Chelsio network adapters that lets reassembled TCP data streams be received via zero-copy into user-supplied buffers usingaio_read(2). Fancy β¨
π« RETURN VALUES π«
Upon successful completion, the value 0 is returned. Otherwise the value -1 is returned and the global variable errno is set to indicate the error. That's it, that's the whole vibe check π
π¨ ERRORS π¨
The getsockopt() and setsockopt() system calls succeed unless:
[EBADF]β the argument s is not a valid descriptor.[ENOTSOCK]β the argument s is a file, not a socket. (girl what π)[ENOPROTOOPT]β the option is unknown at the level indicated.[EFAULT]β the address pointed to by optval is not in a valid part of the process address space. Forgetsockopt(), this error may also be returned if optlen is not in a valid part of the process address space.[EINVAL]β installing anaccept_filter(9)on a non-listening socket was attempted. (we told you tolisten(2)first!! π)[ENOMEM]β a memory allocation failed that was required to service the request.
The setsockopt() system call may also return this one:
[ENOBUFS]β insufficient resources were available in the system to perform the operation.
π SEE ALSO π
ioctl(2), listen(2), recvmsg(2), socket(2), getprotoent(3), mac(3), sysctl(3), ip(4), ip6(4), sctp(4), tcp(4), protocols(5), sysctl(8), accept_filter(9), bintime(9)
Go read them, bestie, they're all part of the lore ππ
π¦ HISTORY π¦
The getsockopt() and setsockopt() system calls appeared in 4.2BSD. Ancient. Iconic. Still running the world π
π BUGS π
Several of the socket options should be handled at lower levels of the system. That's it, that's the bug. Not me exposing the whole architecture π
and that's the whole page, bestie!! π«Ά this one comes to you from the Debian crew, dated June 03, 2020, and it's GETSOCKOPT(2) β part 2 of 2, completed, slayed, no notes βπβ¨
π¦ where this page comes from
- debian bookworm: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- debian trixie: freebsd-manpages 12.2-2 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu jammy: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu noble: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu questing: freebsd-manpages 12.2-2
- ubuntu resolute: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu stonking: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- Copyright (c) 1983, 1991, 1993 The Regents of the University of California. All rights reserved
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms