[AFS3-std] Re: first draft: ubik update proposal

Jeffrey Hutzelman jhutz@cmu.edu
Sun, 06 Feb 2011 16:50:52 -0500


On Sat, 2011-02-05 at 17:12 +0100, Hartmut Reuter wrote:
> Derrick Brashear wrote:
> > On Sat, Feb 5, 2011 at 4:09 AM, Jeffrey Hutzelman<jhutz@cmu.edu>  wrote:
> >> --On Friday, February 04, 2011 10:14:23 AM -0600 Andrew Deason
> >> <adeason@sinenomine.net>  wrote:
> >>
> >>> On Fri, 4 Feb 2011 09:32:53 -0500
> >>> Derrick Brashear<shadow@gmail.com>  wrote:
> >>>
> >>>> struct UbikInterfaceInfo {
> >>>>         afsUUID uuid;
> >>>>         struct sockaddr_storage hostAddr[UBIK_MAX_INTERFACE_ADDR];
> >>>> };
> >>>
> >>> I thought struct sockaddr_storage can be different on different
> >>> implementations, and isn't guaranteed to store ~everything, just the
> >>> representations that host supports. This is something I've been a little
> >>> unclear about, actually; is there any existing standard for transmitting
> >>> generalized network addresses across platforms? Or does everyone just
> >>> come up with their own?
> >>
> >> Indeed, sockaddr_storage is an API artifact, and certainly not suitable for
> >> use in an Rx RPC signature.  The appropriate thing here is some kind of
> >> discriminated union.  We should probably define such a type as an extension
> >> to the "standard" types supported by Rx, rather than doing it in Ubik and
> >> again in VL and again in RXAFSCB and so on and so on.
> >
> > to that end, may i propose that rx define a type e.g.
> > typedef struct
> > {
> >    /* The discriminator for the union below. */
> >    rx_addrtype_t addr_type;
> >    union
> >    {
> >      /* IPv4 address, in network byte order. */
> >      struct in_addr ipv4;
> >
> >      /* IPv6 address, in network byte order. */
> >      struct in6_addr ipv6;
> >    } addr;
> > } rxaddr_t;
> 
> 
> This will not work because in6_addr is a union and xdr cannot handle unions 
> unless you have a switch variable which says which branch of the union should be 
> used. 16 bytes are not the same as 4 int32 if you have different endianess!

More generally, it won't work because in_addr and in6_addr are types
that come from the local system headers.  Rx interfaces need to restrict
themselves to the primitive types supported by Rx and any aggregate
types defined as part of the interface.  This is a wire protocol, not an
API, so you have to nail down exactly what the bits on the wire are.

I think the right thing here is to extend Rx itself to define a new base
type which is a discriminated union along the lines of struct sockaddr,
but where the discriminator values and the encoding of each address type
are defined as part of the spec, rather than coming from system
libraries.  Implementations would be free to represent this type to
applications as a struct sockaddr pointer, even though the wire encoding
is not that of a struct sockaddr; this is along the same lines as the
existing UUID type and the vector aggregate types.  If we are careful
about choosing the encoding, this would also allow for better
interoperability going forward, by allowing us to define the type such
that a discriminator value (address family) unknown to the receiver
doesn't cause the decode to fail, as it must with an ordinary union.
This will likely become important when we define interfaces that contain
lists of server addresses.

An open question is whether what we really want is a socket address type
(including a port number) or merely a layer 3 address type.  I'm
inclined to prefer the latter, since in cases where we need more, a port
number alone won't be sufficient (we'll also need a transport/protocol,
and some transports will require more than a port number).


-- Jeff