Once a socket has been created as type
SOCK SEEK STREAM, the normal recv() and
recvmsg() functions can be used as usual. A new
function, seek recv(), is implemented as a syscall and
takes the following arguments:
ssize t seek recv(int s, void
*buf, size t len, int flags,
size t offset);
The arguments are identical to the recv() function, with
the offset variable added to specify the number of bytes to
offset into the stream. This offset is always relative to the
first byte which would be received through a recv() call.
Since seek recv() modifies the msghdr structure
and then calls the generic sock recvmsg function, it is
also possible to use the standard recvmsg() library function
for seeking receives. The msg seek variable has been
added to the msghdr to specify the seek offset; by modifying
the msghdr structure passed into recvmsg(), it is
possible to do a seeking receive without invoking the new
function.
To be able to seek past large messages, the maximum receive
buffer size must be increased. This is controlled by the
net.core.rmem max system variable (sysctl). This
will set the maximum receive buffer that can be specified using
the setsockopt() function. Therefore, the sysctl
should be set to a reasonably large number of bytes, and the
receive buffer should be increased as necessary within the
user-space program. When the receive buffer becomes full,
normal TCP actions are performed, and the seeking receive
call returns an error. If new packets are received while the
socket buffer is full, they will be dropped and retransmitted
by the sender according to normal TCP flow control [1].
The program must respond to the socket buffer full error by
removing some of the data left in the buffer to free up more
space in the kernel.