wiki:IPv6

Version 14 (modified by itamar, 18 months ago) (diff)

Add mention of StartTLS endpoint ticket.

Plan

This is distilled from #3014 and personal correspondence.

  1. Support IPv6 when explicitly requested (reactor methods) (ie, when an IPv6 address literal is given)
    1. TCP
      1. (#5084) IReactorTCP.listenTCP
      2. (#5085) IReactorTCP.connectTCP
    2. SSL (but this might be automatic when IReactorTCP supports it)
      1. IReactorSSL.listenSSL
      2. IReactorSSL.connectSSL
      3. (#5642) StartTLS wrapper endpoint so we can utilize #4859 and the nicer client TCP6 endpoint.
    3. UDP
      1. (#5086) IReactorUDP.listenUDP and IUDPTransport.write
      2. (#5087) IUDPTransport.connect
    4. Multicast
      1. IReactorMulticast.listenMulticast
      2. IMulticastTransport.joinGroup
      3. IMulticastTransport.leaveGroup
  2. Provide an API which can support either IPv4 or IPv6 (endpoints) or other arbitrary policies (#4470, #4859)
  3. (In the year 2525) Deprecate current hostname-based APIs which do not support IPv6 in favor of endpoints

Other related tickets:

  1. DNS resolver support: #4362

Non-goals

  1. Transparently support IPv6 in existing APIs for existing applications
  2. Implement additional high-level policies (connection attempt order, concurrent connection attempts, address families to try to resolve) in the reactor APIs

Low Level

IReactorTCP.connectTCP will be extended with these (backwards-compatible) changes:

  1. An IPv6 address literal, optionally(?) with a percent-embedded scopeid will be allowed as the value of the host parameter
  2. The bindAddress parameter will accept 4-tuples. The first element is an address like the above, the other three are port number, flow info, and scope id.
    1. (Maybe bindAddress values shouldn't be tuples but should be nice structured objects instead)
  3. If host is IPv6, bindAddress must be as well, and vice versa.

(jknight comment: bindAddress should accept a 2-tuple, just like with ipv4: host/port. flow id needs a lot more work before it can be supported...you can't just use arbitrary numbers, you need to wrap the kernel api for allocating them, and enable them on the socket. http://xpg.dk/projects/linux-ipv6-flow-label-mangement-api. Scope-id is implicit in the first argument (address), just like it is in connectTCP's host parameter, so doesn't need to be specified separately)

IReactorTCP.listenTCP will be extended with these (backwards compatible) changes:

  1. interface will accept an IPv6 address literal value like the one described above
  2. The default listen address will still be INADDR_ANY (this is a non-change; pass "::" if you want IPv6 servers, or see the high level APIs)

IReactorUDP.listenUDP will be extended in an analogous way to IReactorTCP.listenTCP.

IUDPTransport.write and IUDPTransport.connect:

  1. For UDP ports listening on ipv6 addresses only, will be extended to accept a value for addr which is a 4-tuple like the one described above.

IMulticastTransport.joinGroup and leaveGroup are similarly extended. setOutgoingInterface, who knows?

For the APIs mentioned above which can accept hostnames instead of IP address literals, no IPv6 name resolution (hosts file, dns, etc) will be attempted when a hostname is supplied.

High Level

Introduce HostnameClientEndpoint. This endpoint takes a hostname and a port number. The hostname is resolved using getaddrinfo (#4362) and a connection attempted to each address (perhaps serially, perhaps concurrently, perhaps concurrently with a staggered start) and stops after a connection attempt succeeds. Internally this will find an IPv4 or IPv6 address to try and then pass it to IReactorTCP.connectTCP.

Introduce AllLocalInterfacesServerEndpoint. This endpoint binds to all local interfaces on some port and returns an aggregate IListeningPort implementation that can deal with the multiple underlying ports.

Other

  1. Add a way to query getaddrinfo asynchronously (#4362).
  2. Add a way to control name resolution with the endpoint APIs.