= 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` 1. (#5085) `IReactorTCP.connectTCP` 1. '''SSL''' (but this might be automatic when `IReactorTCP` supports it) 1. `IReactorSSL.listenSSL` 1. `IReactorSSL.connectSSL` 1. (#5642) `StartTLS` wrapper endpoint so we can utilize #4859 and the nicer client TCP6 endpoint. 1. '''UDP''' 1. (#5086) `IReactorUDP.listenUDP` and `IUDPTransport.write` 1. (#5087) `IUDPTransport.connect` 1. '''Multicast''' 1. `IReactorMulticast.listenMulticast` 1. `IMulticastTransport.joinGroup` 1. `IMulticastTransport.leaveGroup` 1. Provide an API which can support either IPv4 or IPv6 (endpoints) or other arbitrary policies (#4470, #4859) 1. (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 1. 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 1. 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) 1. 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 1. 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). 1. Add a way to control name resolution with the endpoint APIs.