22.3 Datagram Truncation
On BSD-derived systems, when a UDP datagram
arrives that is larger than the application's buffer,
recvmsg sets the MSG_TRUNC flag in the
msg_flags member of the msghdr structure
(Figure 14.7). All
Berkeley-derived implementations that support the msghdr
structure with the msg_flags member provide this
notification.
This is an example of a flag that must be
returned from the kernel to the process. We mentioned in Section
14.3 that one design problem with the recv and
recvfrom functions is that their flags argument is an integer, which allows
flags to be passed from the process to the kernel, but not vice
versa.
Unfortunately, not all implementations handle a
larger-than-expected UDP datagram in this fashion. There are three
possible scenarios:
-
Discard the
excess bytes and return the MSG_TRUNC flag to the
application. This requires that the application call
recvmsg to receive the flag.
-
Discard the
excess bytes, but do not tell the application.
-
Keep the excess
bytes and return them in subsequent read operations on the
socket.
The POSIX specification specifies the first type
of behavior: discarding the excess bytes and setting the
MSG_TRUNC flag. Early releases of SVR4 exhibited the third
type of behavior.
Since there are such variations in how
implementations handle datagrams that are larger than the
application's receive buffer, one way to detect the problem is to
always allocate an application buffer that is one byte greater than
the largest datagram the application should ever receive. If a
datagram is ever received whose length equals this buffer, consider
it an error.
|