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

Steve Simmons scs@umich.edu
Mon, 7 Feb 2011 11:34:46 -0500


On Feb 5, 2011, at 11:12 AM, 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:
>>>=20
>>>> On Fri, 4 Feb 2011 09:32:53 -0500
>>>> Derrick Brashear<shadow@gmail.com>  wrote:
>>>>=20
>>>>> struct UbikInterfaceInfo {
>>>>>        afsUUID uuid;
>>>>>        struct sockaddr_storage hostAddr[UBIK_MAX_INTERFACE_ADDR];
>>>>> };
>>>>=20
>>>> 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?
>>>=20
>>> 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.
>>=20
>> 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;
>>=20
>>     /* IPv6 address, in network byte order. */
>>     struct in6_addr ipv6;
>>   } addr;
>> } rxaddr_t;
>=20
>=20
> 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!

This is kind of ugly, but might be representable in xdr (which I'm =
moderately ignorant of):

typedef struct
{
  /* The discriminator for the union below. */
  rx_addrtype_t addr_type;
  addr char addr_buf[ sizeof(struct in6_addr) ];
} rxaddr_t;

> typedef enum
> {
>   /* IPv4 address */
>   RX_IPV4 =3D 0x1,
>   /* IPv6 address */
>   RX_IPV6 =3D 0x2
> } rx_addrtype_t;


It would clearly need a couple of helper functions so we could do things =
like

  struct rxaddr_t address;
  struct in_addr ipv4addr;
  struct in6_addr ipv6addr;

  switch ( address.addr_type) {
    case RX_IPV4:
      addrbuf2ipv4( address, &ipv4addr );
      break;
    case RX_IPV6:
      addrbuf2ipv6( address, &ipv6addr );
      break;
    default:
      whoops();
  }

and matching ipv{4,6}addr2addrbuf() functions. In the best of all =
worlds, these would be mostly simple calls to memcpy().

Steve=