
Hi Jeff, --- Jeff Garland <jeff@crystalclearsoftware.com> 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