Subject: (IPng 6687) Namespace Pollution and the IPv6 Basic API

From: Chris Harding <[email-masked]>
Date: Tue, 03 Nov 1998 21:44:48 +0000

Hi -

Here, as promised, are my comments on namespace usage in the draft Basic
API to IPv6. I was asked to make them by XNET because XNET is concerned
about this issue. The details of the comments, which have not been seen by
other members of XNET, are however entirely my responsibility.

First, my apologies for making them at such a late stage. It is true that
some of the names used in the API were not finalised until recently, but
much of what follows is not affected by differences between this version
and the previous version. The main reason is that it has taken a
considerable amount of concentrated effort to go through the draft and the
relevant parts of the ISO C Standard and IEEE Std 1003.1 (POSIX), and
scheduling the necessary time has been hard. Be that as it may, this is
"last call", so I am calling while I can.

The remainder of this message contains:

   - a brief discussion of namespace pollution
   - a summary of namespace use in P1003.1g
   - a summary of additional namespace use in the draft Basic API to IPv6
   - requested changes that are necessary for the correctness of the draft
   - further requested changes that are not necessary for correctness but
     that would improve the draft from the point of view of namespace use.

Namespace Pollution
-------------------

The namespace pollution issue is discussed in section B.2.7.2 of IEEE Std
1003.1 (POSIX.1). This section contains the rationale for section 2.7.2,
which is where POSIX's mechanism for dealing with namespace pollution is
specified. The rationale runs to nearly 6 pages, and the following summary
is necessarily somewhat over-simplified. 

Briefly, implementations and applications share the C namespace, and rules
are needed to say who can use what. The "obvious" rule - that the
implementation takes what it needs and the application can have the rest -
doesn't work, because of three problems.

   1. If the application writer doesn't know what the implementation has used,
      the application can unwittingly re-use a name, and mysteriously fail to
      compile.

   2. Even if implementations document their namespace usage, an application
      that works with one implementation may fail with another implementation
      that uses namespace differently. So portability is compromised.

   3. Even if an application is written to work with all existing
implementations,
      a new version of the interface standard can use new names and break the
      application (and quite likely break implementations too).

The ISO C standard is very precise about which parts of the namespace a C
library can use. Most of the POSIX functions are in the forbidden part. To
keep conformance with ISO C, and to address the three problems listed
above, POSIX uses Feature Test Macros to control visibility of identifiers
to applications. Feature Test Macros have names in the part of the
namespace reserved by ISO to the implementation (eg. "_POSIX_SOURCE").
Unless a Feature Test Macro is defined by the application, the
implementation will not make any identifiers visible to the application
other than those allowed by ISO C. (This normally means that the
application can't use any of the services that ihe implementation can
provide). If the application defines a Feature Test Macro, and includes
header files governed by that macro, then the identifiers defined in those
headers are made visible to it, and the specification clearly states what
those identifiers can be. 

This statement typically consists of lists of reserved identifiers,
reserved prefixes, and reserved suffixes. The reasons for having reserved
prefixes are (a) to enable implementations to define identifiers not
explicitly listed in the standard (for example, to provide additional
non-standard facilities to the application), and (b) to enable new versions
of the standard to define additional identifiers within the reserved
namespace.

So, to regulate namespace use, a standard should define one or more Feature
Test Macros and say what header files are governed by them, and what
identifiers must - and what identifiers may - be made available by
inclusion of those header files when the macros are defined.

An added refinement is for symbol visibility to depend on what value the
macro is given. So the 1998 version of a standard (say) can say that when
the macro has value >= 1998 then a certain set of symbols are visible, and
the 1999 version can say that a bigger set is visible when the value is >=
1999.

Structure and union field names are in a slightly different category from
other identifiers. Each structure or union has its own namespace for field
names, but #defines can still interfere with them. POSIX says that an
implementation can add field names that are not protected by Feature Test
Macros, provided that this is done in such a way that a #define of one of
these names by the application will not affect the implementation. Although
it is possible for implementations to do this, it is rather complicated,
and it is probably best if the standard reserves a prefix (protected by a
Feature Test Macro) for each structure or union, so that implementations
can add fields easily.

It is good practice to keep the lists of reserved identifiers, prefixes and
suffixes in the standards as brief as possible. For example, there could be
just a single reserved prefix for each header. Standards are like sermons -
the shorter the better.

P1003.1g and Namespace
----------------------

The Feature Test Macro mechanism is used by P1003.1g. The following
identifiers are or may be made available by the implementation when Feature
Test Macro _POSIX_SOURCE is defined.

   When <arpa/in.h> is included:

     prefixes
        in_
        inet_

   When <netdb.h> is included:

     prefixes
        AI_
        EAI_
        ai_
        h_
        n_
        p_
        s_

     individual identifiers
        endhostent
        endnetent
        endprotoent
        endservent
        getaddrinfo
        gethostbyaddr
        gethostbyname
        getnetbyaddr
        getnetbyname
        getprotobyname
        getprotobynumber
        getservbyaddr
        getservbyport
        sethostent
        setnetent
        setprotoent
        setservent

   When <netinet/in.h> is included:

     prefixes
        IMPLINK_
        IN_
        INADDR_
        IP_
        IPPORT_
        IPPROTO_
        SOCK_
        in_
        s_
        sin_

     individual identifiers
        htonl
        htons
        ntohl
        ntohs

   When <sys/socket.h> is included:

     prefixes
        AF_ 
        CMSG_
        MSG_    
        PF_
        SO_
        SOCK_
        SOMAX
        cmsg_
        l_
        msg_
        sa_

     individual identifiers
        accept
        bind
        connect
        getpeername
        getsockname
        getsockopt
        isfdtype
        listen
        recv
        recvfrom
        recvmsg
        send
        sendmsg
        sendto
        setsockopt
        shutdown
        sockatmark
        socket
        socketpair

Namespace Usage in the Basic API
--------------------------------

The current draft of the Basic API to IPv6,
draft-ietf-ipngwg-bsd-api-new-03.txt, makes the following namespace use in
addition to that of P1003.1g.

   When <netinet/in.h> is included:

     prefixes
        IN6_
        IN6ADDR_
        IPV6_
        in6_ 
        in6addr_

     prefixes for field names
        ipv6mr_
        s6_
        sin6_

     individual identifiers
        SIN6_LEN
        INET_ADDRSTRLEN
        INET6_ADDRSTRLEN
        ipv6_mreq
        sockaddr_in6

   When <net/if.h> is included:

     prefix (also used for field names)
        if_

     individual identifier
        IFNAMSIZ

   When <netdb.h> is included:

     prefixes
        NI_

     individual identifiers
        freeaddrinfo
        freehostent
        gai_strerror
        getipnodebyaddr
        getipnodebyname
        getnameinfo

   When <sys/socket.h> is included:

     prefixes for field names
        _ss_
        _SS_
        ss_

     individual identifiers
        sockaddr_storage

Essential Changes
-----------------

The following changes should be made in order to correct incorrect
statements in or impressions given by the draft.

    i) On page 3, at the end of the first bullet in section 2, immediately
       after "Simply put, the API changes for IPv6 should not break existing
       programs." add "This will be achieved provided that the new symbols are
       protected by Feature Test Macros as described in IEEE Std 1003.1. 
       (Such Feature Test Macros are not defined by this RFC.)"

   ii) On page 5, at the end of the first paragraph of section 2.4, after
       "Additional, nonstandard members may also be defined by an
       implementation" add ", provided that they are protected by Feature Test
       Macros as described in IEEE Std 1003.1, or that user-defined macros
with
       the same names as the nonstandard members can not interfere with the
       correct interpretation of the program".

  iii) Either change all instances of the _ss_ prefix (eg to _Ss_ or __ss_) or
       remove the statement in section 3.10 on page 13 "The implementation-
       specific definitions and structure field names start with an
       underscore to denote implementation private namespace" (For some
reason,
       the ISO C standard [section 7.1.3] reserves identifiers beginning __
       or _[A-Z] for any use but only reserves other identifiers beginning
with
       underscore for use in the ordinary identifier and tag namespaces.)

Changes to Improve Namespace Usage
----------------------------------

The following changes are not needed for correctness but would "clean up" the
API from a namespace point of view, making it easier to implement, easier to
use, and easier to enhance. These changes do not functionally affect the API
in any way, they are simply changes of names.

   iv) Change all instances of "IN6ADDR_" to "IN6_ADDR_"

    v) Change all instances of "IPV6_" to "IN6_"

   vi) Change all instances of "in6addr_" to "in6_addr_"

  vii) Change "SIN6_LEN" to "IN6_SIN_LEN"

 viii) Change "INET_ADDRSTRLEN" to "IN_ADDRSTRLEN" and change
"INET6_ADDRSTRLEN"
       to "IN6_ADDRSTRLEN".

   ix) Change "ipv6_mreq" to "in6_mreq".

    x) Change all instances of "ipv6mr_" to "in6_mr_"

The effect of changes iv) through x) is that all new identifiers made visible
by including <netinet/in.h> would begin with IN6_, in6_, s6_, sin6_ or
sockaddr_,
which could be reserved prefixes. A further possible change in this area is
change xi).

   xi) Define the new IN6_*, in6_*, s6_* and sin6_* symbols and
sockaddr_in6 in
       a new header <netinet/in6.h> rather than in <netinet/in.h>.

  xii) Change "IFNAMESIZ" to "IF_NAMESIZ" ("IF_" could then be a reserved
prefix).

Regards,

Chris
+++++

-------------------------------------------------------------------------
           Chris Harding
  T H E    Development Manager
 O P E N   Apex Plaza, Forbury Road, Reading RG1 1AX, UK
G R O U P  Mailto:[email-masked]   Ph: +44 118 950 8311 x2262
           WWW: http://www.opengroup.org    Fx: +44 118 950 0110  

OSF/1, Motif, UNIX and the "X" device are registered trademarks in
the US and other countries, and IT DialTone and The Open Group are
trademarks of The Open Group.
-------------------------------------------------------------------------
--------------------------------------------------------------------
IETF IPng Working Group Mailing List
IPng Home Page:                      http://playground.sun.com/ipng
FTP archive:                      ftp://playground.sun.com/pub/ipng
Direct all administrative requests to [email-masked]
--------------------------------------------------------------------

---

From: [email-masked]
Date: Wed, 04 Nov 1998 22:48:03 -0500

Wrking Group colleagues this is my response to Chris Harding's input.

Please respond by Nov 11th to the list if you support this spec or
disagree with my response.  Silence is acceptance we keep the spec as is
and do not make these changes for this case.  But I do ask implementors
to please support not doing this if resultant mail frenzy begins.

Based on the Working Group input on Nov 11th we will need to finish our
last call (which is a week late now thanks to this very late input on
the very last day of the last call) and move this spec forward to
replace RFC 2133 Info RFC, if accepted by the Chairs.

I do not believe these changes are warranted and our namespace has been
tested in practice not theory.  I do not see the value of causing this
extra work for implementors of IPv6 and reject 98% of Chris's input.
The name space has already proved pollution does not exist on our
platforms from this WG.

In addition I recommend if XNET in its standards arena wishes to produce
an update to this work it may do so as part of its process.

But it is up to this working group to decide.  If you want these changes
I will do the editing and it will take me probably sometime, but I will
do it as expediently as possible if we have consensus.  And in this case
a rough consensus is simply not enough as it is too much work, as any
who implement this stuff will tell you, and I am one who implements it
too.

>Namespace Usage in the Basic API

We do not reference P1003.1g in any manner and it is my highly educated and
implementation recommendation to the IETF WG we not, except in the case
of getaddrinfo/getnameinfo(), and that was a consession on this working
groups part in the IETF as we don't own that spec.  We did move to the
datatypes for 1003.1 as a consensus but we have not adopted any
mandatory reqs and all datatypes are examples in this spec.

Many of our future implementations are not 1003.1 compliant nodes like
Routers, Embedded Systems and Devices.  1003.1 also has not seen the
light of day in the real world and most users and ISVs don't care who
write code apps for TCP/IP.  1003.1 may have been important had TCP/IP
lost the protocol wars cause then other standards bodies would have been
more relevant to networking in the real world. Today they are not except
at the datalink layer.

I would claim that the work we have done here for the Basic API is
bigger and more implemented than 1003.1 and POSIX itself.  The reason is
that the IETF implementors built this spec not a standards body.  This
is what we will use and have tested and interoperated against.  It may
not work in theory but it does in practice.

Our Basic API has both rough consensus and running code.  

>       (Such Feature Test Macros are not defined by this RFC.)"

We do not need this and we should not add this language.  Not all
implementors need comply to 1003.1 nor are interested in all cases in
doing so.  Especially the use of a 1003.1 Feature Test Macro.

My recommendation to the WG is to not accept this change request.

>       correct interpretation of the program".

Same as previous response.

>       underscore for use in the ordinary identifier and tag namespaces.)

We should adopt this input and fix section 3.10.

>Changes to Improve Namespace Usage

My recommendation to the Working Group is to not support this change
request and it is not needed or provides a 100% gurantee that we will
have no name space pollution.  Per the input below.

Except for IFNAMSIZ which was a problem for one implementor we have
already fixed it, as we have for all implementors.

Also the WG discussed long ago the issue of having a separate in6.h and
it was decided thru consensus that in6.h would not be called out in the
discussions.  An implementation can include an in6.h within in.h if it
deems that appropriate.

So I say "nay" to all requests except IFNAMSIZ.

=========================================================
   iv) Change all instances of "IN6ADDR_" to "IN6_ADDR_"

  xii) Change "IFNAMESIZ" to "IF_NAMESIZ" ("IF_" could then be a reserved
prefix).
=======================================

/jim