pub struct MemInfo {
pub so_rcvbuf: u32,
pub max_datagram_size: u32,
pub alloc: u32,
}Expand description
§Warning
I don’t have a good understanding of the Unix Domain Sockets, thus take the following documentation with a huge grain of salt.
§Documentation
§UNIX_DIAG_MEMINFO vs INET_DIAG_SK_MEMINFO
MemInfo represent an UNIX_DIAG_MEMINFO NLA. This NLA has the
same structure than INET_DIAG_SKMEMINFO, but since Unix sockets
don’t actually use the network stack, many fields are not relevant
and are always set to 0. According to iproute2 commit
51ff9f2453d066933f24170f0106a7deeefa02d9, only three attributes can have non-zero values.
§Particularities of UNIX sockets
One particularity of UNIX sockets is that they don’t really have a
send queue: when sending data, the kernel finds the destination
socket and enqueues the data directly in its receive queue (which
see also this StackOverflow
answer). For
instance in unix_dgram_sendmsg() in net/unix/af_unix.c we
have:
// `other` refers to the peer socket here
skb_queue_tail(&other->sk_receive_queue, skb);Another particularity is that the kernel keeps track of the memory
using the sender’s sock.sk_wmem_alloc attribute. The receiver’s
sock.sk_rmem_alloc is always zero. Memory is allocated when data
is written to a socket, and is reclaimed when the data is read
from the peer’s socket.
Last but not least, the way unix sockets handle incoming
connection differs from the TCP sockets. For TCP sockets, the
queue used to store pending connections is
sock.sk_ack_backlog. But UNIX sockets use the receive queue to
store them. They can do that because a listening socket only
receive connections, they do not receive actual data from other
socket, so there is no ambiguity about the nature of the data
stored in the receive queue.
Fields§
§so_rcvbuf: u32Value of SO_RCVBUF, although it does not have any effect on
Unix Domain Sockets. As per man unix(7):
The
SO_SNDBUFsocket option does have an effect for UNIX domain sockets, but theSO_RCVBUFoption does not.
This attribute corresponds to sock.sk_rcvbuf in the kernel.
max_datagram_size: u32Maximum size in in bytes of a datagram, as set by
SO_SNDBUF. As per man unix(7):
For datagram sockets, the
SO_SNDBUFvalue imposes an upper limit on the size of outgoing datagrams. This limit is calculated as the doubled (seesocket(7)) option value less 32 bytes used for overhead.
This attribute corresponds to sock.sk_sndbuf in the kernel.
alloc: u32Memory currently allocated for the data sent but not yet read
from the receiving socket(s). The memory is tracked using the
sending socket sock.sk_wmem_queued attribute in the kernel.
Note that this quantity is a little larger than the actual
data being sent because it takes into account the overhead of
the sk_buffs used internally:
/* in net/core/sock.c, sk_wmem_alloc is set in
skb_set_owner_w() with: */
refcount_add(skb->truesize, &sk->sk_wmem_alloc);
/* truesize is set by __alloc_skb() in net/core/skbuff.c
by: */
skb->truesize = SKB_TRUESIZE(size);
/* and SKB_TRUESIZE is defined as: */
#define SKB_TRUESIZE(X) ((X) + \
SKB_DATA_ALIGN(sizeof(struct sk_buff)) + \
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))