Summary

  • RFC 2133 kept core socket call signatures because they already accepted an opaque address pointer and its length; applications still needed PF_INET6, sockaddr_in6 and new conversion and lookup routines.
  • It made two different compatibility promises: old PF_INET applications would continue to reach IPv4 nodes, while new PF_INET6 applications could represent an IPv4 node with an IPv4-mapped IPv6 address. Neither promise proves an IPv6 peer or a successful service.

Imagine a service restarted under a new executable while retaining an open socket. The new process knows the accept() call perfectly well. What it may not know is whether the address returned by that call is shaped like sockaddr_in or sockaddr_in6. The trouble lies in the contract around a familiar verb, not in the verb's spelling. That handoff problem is unusually visible in the April 1997 RFC 2133, an Informational proposal later obsoleted by RFC 2553.

The document started with a practical asymmetry. IPv4 addresses occupied 32 bits; IPv6 addresses occupied 128. Existing code commonly knew the size of an IPv4 address even if the socket calls were supposed to be transport independent. The core functions already passed protocol addresses as opaque pointers alongside lengths. Their syntax could remain. But sockaddr_in, even with unused bytes, could not contain a full IPv6 address together with family and port. The authors therefore defined AF_INET6, PF_INET6 and sockaddr_in6, and described new name and text conversion functions. The 4.3BSD and 4.4BSD structure variants themselves differed in family and length layout. A fixed-size buffer or careless cast was a migration hazard the stable call signature could not remove.

The first compatibility promise protected the past. Systems implementing the proposed API were to preserve source and binary compatibility for the original API. Old programs using PF_INET and sockaddr_in should keep communicating with IPv4 nodes. That did not convert those binaries into IPv6 applications. The second promise concerned new software: a PF_INET6 program could place an IPv4 peer into a sockaddr_in6 as ::FFFF:<IPv4-address> and use the same call vocabulary. This mapped form is an application representation of an IPv4 address. Treating the notation as proof that the peer or the packets were IPv6 would confuse an API envelope with a network observation.

The wildcard and loopback examples further narrow the inference. RFC 2133 gave IPv6 its own unspecified and loopback address forms. A wildcard bind lets the system choose an address in that call's context; a loopback target stays local. Neither tells an observer which remote families a real deployment accepts or whether a service has passed an application test. The RFC specified interfaces, not a measurement of deployed programs.

Its most revealing exception sits in the handoff. Unix could pass an open socket across exec() or between processes. A receiving program expecting the other address family might decode a returned address incorrectly. The historical IPV6_ADDRFORM option let software change whether subsequent calls exposed a PF_INET or PF_INET6 view. Downgrading to PF_INET was restricted: every associated nonwildcard address had to be IPv4-mapped. That condition shows the limit of compatibility more sharply than a list of unchanged functions. The kernel could alter the view of a descriptor only when its existing address state allowed it. This is a feature of the obsolete 1997 proposal, not advice to depend on that option today.

Local interfaces add another layer. RFC 2133 described kernel-assigned interface indexes and functions such as if_nametoindex; its multicast options could choose an outgoing interface or join a group on one. An index establishes a local selection in a particular system. It does not show that a group packet arrived elsewhere, that a remote host joined, or that an application consumed it. Similarly, getaddrinfo() could produce a usable address structure, yet name resolution alone did not demonstrate a completed connection.

The historical achievement was a disciplined split: preserve existing IPv4 behavior, offer IPv6-aware programs a larger address contract, and distinguish mapped representation from peer behavior. The article's evidence boundary follows the running-system question in Lu Heng's essay: a specification describes possible operations; observed implementation and outcome require separate proof. That essay supplies an editorial perspective, not technical evidence for the socket details.

Sources: RFC 2133, its RFC Editor status record, and RFC 2553.