From: Christopher Kohlhoff (chris_at_[hidden])
Date: 2005-12-31 02:01:38


Hi Jeff,

--- Jeff Garland <jeff_at_[hidden]> wrote:

> A group of folks here in Phoenix got together and had a little
> asio 'review party'.

Times must be tough to need asio as an excuse for beer ;)

> As was discussed early on in the review asio doesn't currently
> support ipv6. However, going forward ipv6 support is critical
> for the "Phoenix Group". Given the current asio interfaces it
> seems clear that the extension will come in the form of
> another namespace -- presumably asio::ipv6. This means that
> client code will need to be modified to make the upgrade to
> ipv6. The need to modify code for ipv6 support was disliked by
> the group. It was the consensus of this group that it would
> be preferable to explore a solution that could support both
> ipv4 and ipv6 addresses seemlessly without changes to client
> code. Part of the rationale for this is that most applications
> don't directly configure the ip addresses in code, but rather
> read them from configurations. Hence it would be nice if the
> upgrade was as simple as swithching over the configuration.
> Thus the same compiled app could directly support ipv4 and
> ipv6.
>
> Thoughts, discussion?

I must preface this by saying I have virtually no IPv6
experience, so feel free to jump in and contribute or correct
details.

In the current design I think this could be accomplished by
adding a new asio::ip namespace that contains:

- An address class that can contain either IPv4 or IPv6 host
  addresses, with functions for converting to and from strings
  (much as asio::ipv4::address does already). It includes a
  function that tells the type of the contained address.

- A host class that contains host names and associated list of
  IPv4 and IPv6 addresses.

- A host_resolver class that resolves host names into a list of
  both IPv4 and IPv6 addresses (if a host supports both).

- A tcp class which is an implementation of the Protocol concept
  (as asio::ipv4::tcp is). However unlike asio::ipv4::tcp this
  one does not return constant values and does not have a
  default constructor. Instead it takes an enum indicating
  whether the protocol is for IPv4 or IPv6, and the values
  returned by its member functions vary accordingly.

- A tcp::endpoint class that contains an address object and a
  port number. The protocol_type typedef for this object is for
  the asio::ip::tcp class.

- The tcp::endpoint::protocol() member function returns a tcp
  object constructed for either IPv4 or IPv6 depending on the
  type of the address object that it contains.

- A similar implementation of this for the udp class.

Some examples:

// Binding to an IPv4 localhost address using a string:
asio::ip::address address("127.0.0.1");
asio::ip::endpoint endpoint(12345, address);
asio::datagram_socket socket(demuxer);
socket.open(endpoint.protocol());
socket.bind(endpoint);

// Same as above using IPv6.
asio::ip::address address("::1");
asio::ip::endpoint endpoint(12345, address);
asio::datagram_socket socket(demuxer);
socket.open(endpoint.protocol());
socket.bind(endpoint);

// Host resolution and connection.
asio::ip::host host;
asio::ip::host_resolver host_resolver(demuxer);
host_resolver.get_host_by_name(host, "foobar");
asio::ip::endpoint endpoint(12345, host.addresses(0));
asio::stream_socket socket(demuxer);
socket.connect(endpoint);

Assuming this works...

- Is it worth keeping separate ipv4 and ipv6 namespaces?
  Some applications may want to explicitly specify one or the
  other.

- How does this fit with Giovanni Deretta's suggestion of
  separate types for each protocol's socket? Does it mean having
  an asio::ip::tcp::socket type, for example? The issue is that
  the concrete protocol (IPv4 or IPv6) needs to be known before
  the socket object is opened.

Cheers,
Chris