Operations 17 min read

IPv6 Support Report and DNS Testing in Dual‑Stack Environments

This technical report presents an IPv6 adoption overview, global deployment status, operating‑system and application IPv6 support, and a series of DNS and network‑stack tests—including dual‑stack scenarios, code examples, and conclusions on best practices such as using getaddrinfo over gethostbyname.

NetEase Game Operations Platform
NetEase Game Operations Platform
NetEase Game Operations Platform
IPv6 Support Report and DNS Testing in Dual‑Stack Environments

IPv6 Support Report and DNS Testing

Dong Tao, senior operations engineer at NetEase Games, and Zhang Xinjie, head of the NetEase DNS team, introduce the purpose of the report: to evaluate IPv6 adoption and DNS behavior in various environments.

1. IPv6 Support Report

IPv6 Overview

IPv6 is the successor to IPv4, designed by the IETF. With 128‑bit addresses it provides roughly 3.4×10 38 addresses, solving the address exhaustion problem and laying the foundation for the Internet of Things.

Global Deployment Updates

2008 – EU IPv6 Action Plan

2009 – Japan IPv6 Action Plan

2010 – US IPv6 Action Plan

2010 – Korea Next‑Generation Internet Protocol Promotion Plan

2012 – Canada IPv6 Strategy

2017 – China Ministry of Industry and Information Technology (MIIT) IPv6 Deployment Action Plan

Operating‑System IPv6 Support

Application IPv6 Support

Client Software

Browser support is illustrated with screenshots.

Server Software

Development tools, databases, and other server components are shown to have basic IPv6 compatibility.

2. DNS Tests in IPv6 Environments

Background

A Record : maps a domain to an IPv4 address.

AAAA Record : maps a domain to an IPv6 address.

Cache DNS Server : e.g., 8.8.8.8, 114.114.114.114.

Authoritative DNS Server : answers only for zones it owns.

Dual‑Stack Network : hosts have both IPv4 and IPv6 addresses.

Test Scenarios

1. Adding AAAA Record in a Pure IPv4 Environment

When an AAAA record is added to a domain that already has an A record, existing programs continue to work correctly.

2. Dual‑Stack Client Environment

In a dual‑stack client, both A and AAAA queries are issued. Most programs prefer IPv6, but a few edge cases (e.g., using gethostbyname with options inet6 in resolv.conf ) may return incorrect results.

3. Pure IPv6 Client Environment

When only IPv6 connectivity is available, services that expose both A and AAAA records remain reachable as long as the DNS infrastructure also supports IPv6.

DNS Resolution Test

Cache servers prefer IPv6 when both IPv4 and IPv6 answers are available; otherwise they fall back to IPv4.

Conclusions

gethostbyname does not support IPv6 and may produce wrong results; use getaddrinfo instead.

Adding AAAA records to existing domains is safe for the majority of clients and servers.

In dual‑stack networks, IPv6 is preferred for connection establishment (Happy Eyeballs algorithm, RFC 6555).

Cache and authoritative DNS servers follow the same preference rules.

Reference Materials

Windows 8 IPv4/IPv6 selection: Connecting with IPv6 in Windows 8

IPv6 fallback mechanisms in Windows: IPv6 fallback discussion

Happy Eyeballs algorithm (RFC 6555) and its implementation in browsers and cURL.

Test Methods

Domain Resolution

C / C++ – gethostbyname

#include
#include
#include
int main(void) {
    int i = 0;
    char str[32] = {0};
    struct hostent *phost = NULL;
    phost = gethostbyname("IPv6test.ntes53.netease.com");
    printf("%s", inet_ntoa(*((struct in_addr*)phost->h_addr)));
    return 0;
}

Windows – gethostbyname

#include
#include
#include
#pragma comment(lib, "ws2_32.lib")
int main(void) {
    WSADATA wsaData = {0};
    struct in_addr addr = {0};
    struct hostent *res;
    int i = 0;
    WSAStartup(MAKEWORD(2,2), &wsaData);
    res = gethostbyname("IPv6test.ntes53.netease.com.");
    while (res->h_addr_list[i] != 0) {
        addr.s_addr = *(u_long *)res->h_addr_list[i++];
        printf("IP Address: %s\n", inet_ntoa(addr));
    }
    WSACleanup();
    return 0;
}

getaddrinfo (C)

#include
#include
#include
#include
#include
#include
#include
int lookup_host() {
    struct addrinfo hints, *res;
    int errcode;
    char addrstr[100];
    void *ptr;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    errcode = getaddrinfo("IPv6test.ntes53.netease.com", NULL, &hints, &res);
    if (errcode != 0) {
        perror("getaddrinfo");
        return -1;
    }
    while (res) {
        inet_ntop(res->ai_family, res->ai_addr->sa_data, addrstr, 100);
        switch (res->ai_family) {
            case AF_INET:  ptr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; break;
            case AF_INET6: ptr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; break;
        }
        inet_ntop(res->ai_family, ptr, addrstr, 100);
        printf("IPv%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4, addrstr, res->ai_canonname);
        res = res->ai_next;
    }
    return 0;
}
int main(void) {
    lookup_host();
    return 0;
}

Python – socket.gethostbyname

import socket
result = socket.gethostbyname("IPv6test.ntes53.netease.com")
print(result)

Python – socket.getaddrinfo

import socket
result = socket.getaddrinfo("IPv6test.ntes53.netease.com", 0, socket.AF_INET6)
print(result)
result = socket.getaddrinfo("IPv6test.ntes53.netease.com", 0, socket.AF_INET)
print(result)
result = socket.getaddrinfo("IPv6test.ntes53.netease.com", 0, socket.AF_UNSPEC)
print(result)

Python – requests

import requests
response = requests.get("http://IPv6test.ntes53.netease.com:8000", stream=True)
print(response.raw._fp.fp._sock.getpeername())

C++ – libcurl

#include
#include
int main(void) {
    CURL *curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://IPv6test.ntes53.netease.com:8000");
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        // curl_easy_setopt(curl, CURL_IPRESOLVE_V6, 1L);
        // curl_easy_setopt(curl, CURL_IPRESOLVE_V4, 1L);
        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK)
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        curl_easy_cleanup(curl);
    }
    return 0;
}

Network Interaction Diagram

DNS Server                Client                Server
               |                         |
1.  <--www.example.com A?-----|                         |
2.  <--www.example.com AAAA?---|                         |
3.  ---192.0.2.1------------->|                         |
4.  ---2001:db8::1----------->|                         |
5.                         |                         |
6.                         |==TCP SYN, IPv6=======>|
7.                         |--TCP SYN, IPv4------->|
8.                         |<=TCP SYN+ACK, IPv6====|
9.                         |<-TCP SYN+ACK, IPv4----|
10.                        |==TCP ACK, IPv6=======>|
11.                        |--TCP ACK, IPv4------->|
12.                        |--TCP RST, IPv4------->|

The report concludes that IPv6 adoption is progressing, dual‑stack environments behave as expected, and developers should migrate to IPv6‑aware APIs such as getaddrinfo to avoid legacy pitfalls.

IPv6dnsnetwork testingDual-StackHappy Eyeballsgetaddrinfo
NetEase Game Operations Platform
Written by

NetEase Game Operations Platform

The NetEase Game Automated Operations Platform delivers stable services for thousands of NetEase titles, focusing on efficient ops workflows, intelligent monitoring, and virtualization.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.