Operations
A networking client typically connects to a server identified by connection information specified in its configuration or by the user. The general client procedure is to use name resolution service (often through the system C library) and use the result to negotiate a connection through the operating system kernel.
Name resolution phase
Client software retrieves a domain name from the user or from its configuration either as a verbatim value or by parsing a more complex configuration item like an URL or an e-mail address. Client software can often handle special values like literal IP addresses or empty host names. Most often this is the only configuration that is needed. Other name resolution input is built-in but can often also be tweaked by configuration or URL.
Name resolution typically consists of multiple actions. The most typical combination of actions is host name resolution using DNS
where A
and AAAA
are requested separately in order to get IPv4 and IPv6 addresses. Sequential or parallel queries can be used to handle that situation.
See Name resolution for more details.
Example: Jabber (XMPP client connection)
Identifier: user@example.net
Client extracts domain name example.net
from the configuration option above, resolves SRV
record _xmpp-client._tcp.example.net
to get the list of host names and then attempts to resolve A
and AAAA
records of those host names to get the list of IPv4 and IPv6 addresses to be attempted for connection.
You can use netresolve to mimic the above procedure:
netresolve --node example.net --service xmpp-client --srv --protocol tcp
Connection phase
Connection procedure can start after or during the name resolution phase and uses the name resolution results. The connection procedure can also be fully sequential (client attempts addresses in a given order until a successful connection is established) or using parallelization. The most prominent reason for parallel connection is to avoid waiting for a defunct protocol version by attempting an IPv4 address at the same time as an IPv6 address.
IPv6 address preference
Client software should generally prefer IPv6 addresses over IPv4 by default. It is possible to tweak address preference for applications using the libc resolver /etc/gai.conf
but many applications will simply ignore it. Also IPv6 addresses in the list of recursive DNS servers should be preferred over IPv4.
Checking tools
You can use strace, tcpdump or other tools to check application behavior depending on your needs. While strace is great in getting information about all network communication attempts, tcpdump can show you the contents of actual communication.
Test cases
Loopback
Connectivity | IPv4 | Any (loopback address wanted) |
---|---|---|
IPv6 | Any except disabled (loopback address required) |
What is tested
- Whether IPv6 loopback is preferred over IPv4 loopback.
- Whether the component is capable of working over IPv6.
Steps to reproduce
- Let the client connect to a localhost server.
- Check the communcation (using strace, netstat/ss or tcpdump).
Expected result
- Client connects to server using
::1
IPv6 address.
Note: If the client also connects using 127.0.0.1
due to parallel IPv4/IPv6 connection, it drops the connection
immediately.
Bad result
- Client doesn't attempt IPv6 loopback connection.
Dual-stack to dual-stack
Source connectivity | IPv4 | Global or masqueraded |
---|---|---|
IPv6 | Global | |
Target connectivity | IPv4 | Global |
IPv6 | Global |
What is tested
- Whether IPv6 is preferred over IPv4.
- Whether the component is capable of working over IPv6.
- Whether sequential or parallel DNS resolution is in use.
Steps to reproduce
- Let the client connect to a dual-stack server.
- Check all tested properties.
Expected result (sequential, IPv6 preferred)
- (resolver) Host requests AAAA record and receives a reply.
- Host connects via IPv6.
- No delays.
- (resolver) No A query.
Expected result (parallel, IPv6 preferred)
- Host requests A and AAAA records simultaneously and receives the AAAA reply.
- Host connects via IPv6.
- No delays, A reply is ignored if received.
Bad result
Not connecting to IPv6 address or attempting an IPv4 connection.
IPv6 to dual-stack
Source connectivity | IPv4 | None |
---|---|---|
IPv6 | Global | |
Target connectivity | IPv4 | Global |
IPv6 | Global |
What is tested
- Whether the component works well on IPv6 only host
Steps to reproduce
- Let the client connect to a dual-stack server.
- Check all tested properties.
Expected result
- Host requests AAAA record and receives a reply.
- Host connects via IPv6.
- No delays, no A query.
Bad result
Failure to connect to target via IPv6.
Bad result (only a minor issue)
Sending a redundant DNS A query.
Dual-stack to dual-stack with lost AAAA answer
Source connectivity | IPv4 | Global or masqueraded |
---|---|---|
IPv6 | Global | |
Target connectivity | IPv4 | Global |
IPv6 | Global | |
Other | AAAA request or reply is lost |
Same as above, except that the AAAA answer is lost by a broken DNS server.
What is tested
- Wheter the component reverts to IPv4 in reasonable time when AAAA answer gets lost.
Steps to reproduce
- Block IPv6 DNS packets on firewall.
- Let the client connect to a dual-stack server.
- Check all tested properties including the delay.
Expected result (sequential, IPv6 preferred)
- Host requests AAAA record and gives up after a delay (e.g. 15 seconds).
- Host requests A record and receives reply.
- Host connects via IPv4.
Expected result (parallel, IPv6 preferred)
- Host requests A and AAAA records simultaneously and receives the A reply.
- Host gives up waiting for AAAA record after a short delay (e.g. 300 milliseconds).
- Host connects via IPv4.
Bad result (parallel, first result wins)
- Host requests A and AAAA records simultaneously and receives the A reply.
- Host connects via IPv4.
- No delay.
Rationale: IPv6 should be preferred over IPv4 by default.
IPv4 to dual-stack with lost AAAA answer
Source connectivity | IPv4 | Global or masqueraded |
---|---|---|
IPv6 | Link-local (alternatively None or Disabled) | |
Target connectivity | IPv4 | Global |
IPv6 | Global | |
Other | AAAA request or reply is lost |
Same as above, except that the host doesn't have any IPv6 address except link-local and loopback.
What is tested
- Whether the component suppresses AAAA queries when lacking global IPv6 connectivity.
Steps to reproduce
- Block IPv6 DNS packets on firewall.
- Let the client connect to a dual-stack server.
- Check all tested properties including absence of a delay.
Expected result
- Host requests A record and receives reply.
- Host connects via IPv4.
- No delay, no AAAA query.
Bad result
- Host requests A and AAAA record and receives A reply.
- Host gives up waiting for AAAA reply.
- Host connects via IPv4 after an excessive delay.
Rationale: IPv4-only host should connect to IPv4 address without delay.
Dual-stack to dual-stack with lost IPv6 communication
Source connectivity | IPv4 | Global or masqueraded |
---|---|---|
IPv6 | Global | |
Target connectivity | IPv4 | Global |
IPv6 | Global | |
Other | Lost client-server IPv6 communication |
What is tested
- Whether the component reverts to IPv4 in reasonable time when local or remote network drops all IPv6 communication.
Steps to reproduce
- Let the client connect to a dual-stack server with lost IPv6 communication.
- Check all tested properties including the delay.
Expected result (sequential, IPv6 preferred)
- Host requests AAAA record and receives reply.
- Host attempts connecting to IPv6 and times out.
- Host requests A record and receives reply.
- Host connects via IPv4
Expected result (parallel DNS, IPv6 preferred)
- Host requests A and AAAA records simultaneously and waits for AAAA reply.
- Host attempts connecting to IPv6 and times out, receiving A reply in the meantime.
- Host connects via IPv4.
Expected result (parallel DNS, parallel TCP, IPv6 preferred)
- Host requests A and AAAA records simultaneously.
- Host attempts IPv4 and IPv6 connections upon receiving the respective records.
- IPv4 connection is established.
- IPv6 connection is given up after a short delay (e.g. 300 milliseconds).
- IPv4 connection is used.
Notes
There is no common bad result. But the sequential connection is highly suboptimal and therefore is not suitable for interactive applications.
Disabled IPv6 to dual-stack with lost IPv6 communication
Source connectivity | IPv4 | Global or masqueraded |
---|---|---|
IPv6 | Disabled | |
Target connectivity | IPv4 | Global |
IPv6 | Global | |
Other | Lost client-server IPv6 communication |
What is tested
- Whether the component works on a system with IPv6 disabled in the kernel.
Steps to reproduce
- Start the system with kernel command line option
ipv6.disable=1
. - Connect to a service.
Expected result
- Client connects to a service successfully.
Bad result
- Client fails to connect.
Note: You will probably see an error message coming from the socket()
libc call.