Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Feb 2014 17:29:27 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Eitan Adler <eadler@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r261454 - head/lib/libc/net
Message-ID:  <20140204164703.S1229@besplex.bde.org>
In-Reply-To: <201402040301.s1431XgK027156@svn.freebsd.org>
References:  <201402040301.s1431XgK027156@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140204164703.S1229>