When a user program invokes the recv(),
recvfrom(), or recvmsg() functions on a TCP
socket, tcp recvmsg() is invoked within the kernel
(net/ipv4/tcp.c). Figure 2 is a flowchart of these
functions. tcp recvmsg() begins copying data from
the sk buff’s in the socket queue which point to the
actual data in the ring buffer. The function inspects the
first skb in the socket buffer and then copies data to the
user-space buffer. If the skb has more data than requested,
tcp recvmsg() leaves the remainder on the socket
buffer queue. If the user has requested more data than the
contents of the first skb, the skb is deallocated along with
its corresponding data on the ring buffer, and the above
steps continue with the next skb in the queue. By default,
tcp recvmsg() returns after reading all the requested
data from the socket buffer, deallocating all the skb’s that
have had their data completely received, and updating the
sequence number of the first byte to read on the socket.