On Tue, 4 Feb 2014, Eitan Adler wrote:
Log:
libc/net: Fix some issues in inet6_opt_init() (from RFC 3542):
* The RFC says (in section 10.1) that only when extbuf is not NULL,
extlen shall be checked, so don't perform this check when NULL is
passed.
* socklen_t is unsigned, so checking extlen for less than zero is
not needed.
Why be so unportable? socklen_t is not necessarily unsigned. It
should be signed, and was signed int in BSD, but was broken during
development of POSIX.1-2001. FreeBSD apparently tracked the buggy
development version and changed from int to u_int32_t in 1999.
From POSIX.1-2001-draft7:
12409 The <sys/socket.h> header shall define the type socklen_t,
which is an integer type of width of
12410 at least 32 bits; see APPLICATION USAGE.
[APPLICATION USAGE "recommends" that values stored in socklen_t not be larger
than 2**31-1. It doesn't spell out that this is because socklen_t might be
a signed type. Note that "width" is a technical tyem for integer types, and
is satisfied by signed 32-bit ints although these have only 31 useful bits.]
7456 B.2.10.6 Socket Types
7457 The type socklen_t was invented to cover the range of
implementations seen in the field. The
7458 intent of socklen_t is to be the type for all lengths that are
naturally bounded in size; that is, that
7459 they are the length of a buffer which cannot sensibly become of
massive size: network addresses,
7460 host names, string representations of these, ancillary data,
control messages, and socket options
[2**31-1 is massive. 2**16-1 would just be a bit too small.]
7461 are examples. Truly boundless sizes are represented by size_t
as in read( ), write( ), and so on.
[Nonsense. 2**31-1 is massive for read/write buffer sizes too, and size_t is
far from being able to represent truly boundless sizes.]
7462 All socklen_t types were originally (in BSD UNIX) of type int.
During the development of
7463 IEEE Std 1003.1-200x, it was decided to change all buffer
lengths to size_t, which appears at face
7464 value to make sense. When dual mode 32/64-bit systems came
along, this choice unnecessarily
7465 complicated system interfaces because size_t (with long) was a
different size under ILP32 and
7466 LP64 models. Reverting to int would have happened except that
some implementations had
7467 already shipped 64-bit-only interfaces. The compromise was a
type which could be defined to be
7468 any size by the implementation: socklen_t.
It was too late to fix the breakage for read/write. It was not too
late to require plain int again for socklen_t. POSIX.1 requires 32-bit
ints, so int for socklen_t was large enough. Strangely, POSIX only
requires 16 bits for size_t and ssize_t. This makes some sense since
it allows API's burdened by using typedefed types to use the best
machine-dependent type (portable applications have the burden of using
the typedefed types no matter what the implementation chooses). OTOH,
if the API uses a basic type like int, then it has to be large enough
to work for all implementations, so int can't be 16 bits.
Bruce
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"