Line 12: | Line 12: | ||
Name resolution features are provided by the GNU C Library (glibc) which is not yet ready for proper IPv6 and dual-stack operation as you can see when performing your tests. The C library comes with its own testing tool <code>getent</code> that has a special database called <code>ahosts</code> that runs <code>getaddrinfo()</code>, the library function that translates names to objects with addressing information. For your testing it is best used together with tools like <code>strace</code>, <code>ltrace</code> or even <code>gdb</code> so that you know exactly what is happening behind the scenes. | Name resolution features are provided by the GNU C Library (glibc) which is not yet ready for proper IPv6 and dual-stack operation as you can see when performing your tests. The C library comes with its own testing tool <code>getent</code> that has a special database called <code>ahosts</code> that runs <code>getaddrinfo()</code>, the library function that translates names to objects with addressing information. For your testing it is best used together with tools like <code>strace</code>, <code>ltrace</code> or even <code>gdb</code> so that you know exactly what is happening behind the scenes. | ||
< | As the <code>getent</code> tool is very primitive, we created a tool called <code>getaddrinfo</code> just as the library function that handles a larger subset of the function's API. | ||
</ | |||
=== Name resolution input === | === Name resolution input === | ||
Line 55: | Line 18: | ||
When application requests addressing information for a hostname with an optional service name, the library returns a list of addressing information objects. The order of objects in the list is significant and depends on operating system configuration and connectivity. | When application requests addressing information for a hostname with an optional service name, the library returns a list of addressing information objects. The order of objects in the list is significant and depends on operating system configuration and connectivity. | ||
==== | ==== From the application ==== | ||
* nodename | * nodename | ||
Line 65: | Line 28: | ||
** ... | ** ... | ||
==== | ==== From local configuration and connectivity checks ==== | ||
* Files in <code>/etc/</code> including nsswitch, hosts, services and more | |||
* To what extend is IPv4 and IPv6 available | * To what extend is IPv4 and IPv6 available | ||
==== | ==== From the outside world ==== | ||
* DNS information | * DNS information | ||
Line 88: | Line 52: | ||
There are rules for sorting addressing information returned by <code>getaddrinfo()</code>. One of the basic features is to return global IPv6 destinations before global IPv4 destinations. But when the library detects that IPv6 connectivity is not available, the reverse applies. | There are rules for sorting addressing information returned by <code>getaddrinfo()</code>. One of the basic features is to return global IPv6 destinations before global IPv4 destinations. But when the library detects that IPv6 connectivity is not available, the reverse applies. | ||
=== Example tests === | |||
==== Dual-stack host, destination with global IPv4 and IPv6 ==== | |||
On a host with IPv4 and IPv6 connectivity we request addressing information of another host that is announced as dual-stack in DNS. | |||
<pre> | |||
$ getent ahosts www.nix.cz | |||
2a02:38::1001 STREAM info.nix.cz | |||
2a02:38::1001 DGRAM | |||
2a02:38::1001 RAW | |||
195.47.235.3 STREAM | |||
195.47.235.3 DGRAM | |||
195.47.235.3 RAW | |||
</pre> | |||
You can see that <code>getaddrinfo()</code> returned ''six'' items for ''two'' unique IP addresses with the IPv6 address sorted first. If you only expected only ''two'' items, one for each IP address, see [https://sourceware.org/bugzilla/show_bug.cgi?id=14990 upstream bug 14990]. | |||
==== IPv4-only host, destination with global IPv4 and IPv6 ==== | |||
We do the same on a host without IPv6 connectivity. | |||
<pre> | |||
$ getent ahosts www.nix.cz | |||
195.47.235.3 STREAM info.nix.cz | |||
195.47.235.3 DGRAM | |||
195.47.235.3 RAW | |||
2a02:38::1001 STREAM | |||
2a02:38::1001 DGRAM | |||
2a02:38::1001 RAW | |||
</pre> | |||
You can see that the result is the same as before except that IPv4 is sorted first. | |||
== Testing client applications == | == Testing client applications == | ||
== Testing server applications == | == Testing server applications == |
Revision as of 13:54, 13 July 2015
Testing IPv6 support and dualstack networking can be very tricky. The purpose of this document is to provide a live resource on testing situations arising from existance and usage of two network layer protocols.
Configuration
Base system components related to IPv6 and dual-stack operation:
- kernel
- glibc
Name resolution
Name resolution features are provided by the GNU C Library (glibc) which is not yet ready for proper IPv6 and dual-stack operation as you can see when performing your tests. The C library comes with its own testing tool getent
that has a special database called ahosts
that runs getaddrinfo()
, the library function that translates names to objects with addressing information. For your testing it is best used together with tools like strace
, ltrace
or even gdb
so that you know exactly what is happening behind the scenes.
As the getent
tool is very primitive, we created a tool called getaddrinfo
just as the library function that handles a larger subset of the function's API.
Name resolution input
When application requests addressing information for a hostname with an optional service name, the library returns a list of addressing information objects. The order of objects in the list is significant and depends on operating system configuration and connectivity.
From the application
- nodename
- servname
- protocol
- socktype
- flags
AI_CANONNAME
- ...
From local configuration and connectivity checks
- Files in
/etc/
including nsswitch, hosts, services and more - To what extend is IPv4 and IPv6 available
From the outside world
- DNS information
- Multicast DNS information
- LDAP information
Name resolution processing
What is requested
Not all information is requested at all times. Some information like canonical name must be explicitly requested by the application via AI_CANONNAME
flag. It may be desirable to suppress other requests by local configuration or connectivity checks, a notable example being suppression of DNS AAAA queries on hosts without global connectivity.
What is passed to the application
Not all information that is learnt via requests is presented to the application. It is typically filtered according to input from the application. It is sometimes also filtered according to connectivity checks but that has caused more problems than improvements.
How it is sorted
There are rules for sorting addressing information returned by getaddrinfo()
. One of the basic features is to return global IPv6 destinations before global IPv4 destinations. But when the library detects that IPv6 connectivity is not available, the reverse applies.
Example tests
Dual-stack host, destination with global IPv4 and IPv6
On a host with IPv4 and IPv6 connectivity we request addressing information of another host that is announced as dual-stack in DNS.
$ getent ahosts www.nix.cz 2a02:38::1001 STREAM info.nix.cz 2a02:38::1001 DGRAM 2a02:38::1001 RAW 195.47.235.3 STREAM 195.47.235.3 DGRAM 195.47.235.3 RAW
You can see that getaddrinfo()
returned six items for two unique IP addresses with the IPv6 address sorted first. If you only expected only two items, one for each IP address, see upstream bug 14990.
IPv4-only host, destination with global IPv4 and IPv6
We do the same on a host without IPv6 connectivity.
$ getent ahosts www.nix.cz 195.47.235.3 STREAM info.nix.cz 195.47.235.3 DGRAM 195.47.235.3 RAW 2a02:38::1001 STREAM 2a02:38::1001 DGRAM 2a02:38::1001 RAW
You can see that the result is the same as before except that IPv4 is sorted first.