A complete set of DNS related tests in IPv6 environment

A complete set of DNS related tests in IPv6 environment

[[271457]]


Dong Tao, senior operation and maintenance engineer of NetEase Games, mainly focuses on the operation and development of NetEase Group's DNS.
Zhang Xinjie, head of the DNS team of NetEase Group, is responsible for the architectural design and ecological construction of NetEase's domain name system.

1. IPv6 Support Report

Introduction to IPv6

IPv6 (Internet Protocol version 6) is a network layer protocol for packet switching internetworks. It is an Internet Protocol version designed by IETF (Internet Engineering Task Force, IETF for short) to replace IPv4.

With the development of electronic technology and network technology, computer networks have become closely related to people's lives. Perhaps every electronic device around us needs to be connected to the network, and the number of IPv4 addresses can no longer meet the needs. The application of IPv6 will completely solve these problems. IPv6 consists of 128 bits. In terms of order of magnitude alone, the address capacity of IPv6 is about 8×10 28 times that of IPv4, reaching 2 128 (about 3.4 × 10 38 ). This not only solves the problem of the number of network address resources, but also provides a foundation for the development of the Internet of Things.

An IPv6 address is expressed as 32 hexadecimal numbers, consisting of two logical parts: a 64-bit network prefix and a 64-bit host address. The host address is usually automatically generated based on the physical address and is called EUI-64 (or 64-bit Extended Unique Identifier). For example, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344 is a legal IPv6 address.

IPv6 Global Deployment Update

  • In 2008, the European Union issued the "European Action Plan for Deploying IPv6"

  • In 2009, Japan released the IPv6 Action Plan

  • In 2010, the US government released the IPv6 Action Plan

  • In 2010, South Korea released the "Next Generation Internet Protocol (IPv6) Promotion Plan"

  • In 2012, the Canadian government released the Canadian Government IPv6 Strategy.

  • In 2017, the General Office of the State Council issued the Action Plan for Promoting Large-Scale Deployment of Internet Protocol Version 6 (IPv6).

Operating system IPv6 support

Application software IPv6 support

Client Software

1. Browser

Server Software

1. Program development software

2. Database

Summarize

Undoubtedly, the next generation Internet IPv6 is an important supporting protocol for the basic network in the era of interconnection of all things and intelligence. However, it will take a very long time to fully and smoothly transition from a giant network with only IPv4 protocol to a pure IPv6 network. According to the statistical data in the report, various basic software and application software have basically supported IPv6. Now in the domestic environment, the basic environment of IPv6 needs to be improved. For this reason, the Ministry of Industry and Information Technology has also issued

Action Plan for Promoting Large-Scale Deployment of Internet Protocol Version 6 (IPv6) (http://www.miit.gov.cn/n1146290/n4388791/c6166476/content.html)

Promote all units to accelerate support for IPv6.

The data source of the IPv6 support report is: The IPv6 support report released by the Next Generation National Internet Center in November 2017

(https://www.ipv6ready.org.cn/public/download/ipv6.pdf), interested students can view the original text.

2. DNS related tests in IPv6 environment

Background

Noun Introduction

  • A Record

 A 记录是一个域名指向IPv4 地址的解析结果,即最常见的记录类型, 例如ipv6test.ntes53.netease.com. 1800 IN A 123.58.166.70
  • AAAA Records

 AAAA 是一个域名指向IPv6 地址的解析结果。如果想要一个域名解析到IPv6 地址,则需要设置此种类型的解析结果。同一个域名可以同时有A 与AAAA 两种记录类型, 例如ipv6test.ntes53.netease.com. 1800 IN AAAA 2403:c80:100:3000::7b3a:a646
  • Caching DNS Server

 用户直接使用的DNS 服务器,各种平台、操作系统上直接设置的DNS 服务器,常见的有8.8.8.8, 114.114.114.114
  • Authoritative DNS Server

 用于域名的管理。权威DNS 服务器只对自己所拥有的域名进行域名解析,对于不是自己的域名则拒绝应答。例如网易的权威DNS 服务器只会响应网易域名的请求,对于其他域名,则拒绝应答。
  • Dual-stack network environment

 双栈网络环境即客户端或服务器同时拥有IPv4、IPv6 两种网络环境,可以简单的理解为机器上既有IPv4 地址又有IPv6 地址

Test scenario

All the tests below use the same procedures as those in the test method.

1. In the current pure IPv4 environment, the impact of adding only AAAA (IPv6) records on existing programs

Assume that there is already a program (C program, Python program, browser, etc.) that accesses a service through a domain name, and everything works fine in an IPv4 environment. After adding an AAAA record to this domain name, test the impact on the current program.

Domain name resolution

HTTP Request

Client

in conclusion

  • When an AAAA record is added to the existing A record type of a domain name, the original program works normally.

2. Test program behavior in client IPv6/v4 dual stack environment

Assume that the user's environment is a dual-stack environment, and assume that a service provides external services through a domain name. Test the behavior of the program in this case.

Domain name resolution

HTTP Request

Client

in conclusion

  • When both A and AAAA records exist for a domain name and the network type is a dual-stack network, most programs work properly. The only exception is when the program uses the gethostbyname function and options inet6 is configured in resolv.conf When the program returns an incorrect parsing result

  • RFC and most implementations will prioritize using IPv6 addresses to establish connections

  • In a dual-stack environment, the client obtains the same resolution results using IPv4 and IPv6 cache DNS servers.

3. Test whether the client can work normally in a pure IPv6 environment

Assume that the user only has an IPv6 address and DNS also uses an IPv6 address (DNS must have a dual-stack environment, because many authoritative servers do not have IPv6 addresses and cannot work properly in a pure IPv6 environment). Assume that a service provides services to the outside world through a domain name (with both A and AAAA records). Test whether the service can be accessed normally.

Domain name resolution

HTTP Request

Client

in conclusion
When a domain name has both an A record and an AAAA record:

  • If gethostbyname is used in a program, the program may get an incorrect resolution result, depending on the configuration of resolv.conf (when option inet6 is configured, an incorrect resolution result will be obtained)

  • Windows In this case, some applications do not work properly. If you specify to use IPv6 socket, the program works normally.

  • According to the official description of Android, versions after Android 6.0 already support IPv6. However, according to the survey of Android phones from most domestic manufacturers, currently few domestic Android phones can natively support IPv6.

4. DNS resolution test

Here we test the resolution links that are preferentially used by cache servers and authoritative servers in various network environments.

in conclusion
When both the authoritative server and the cache server support IPv6, the cache server will use the IPv6 link for resolution first, and the IPv4 link will be used for resolution in other cases.

in conclusion

  • After testing and verification, gethostbyname does not support IPv6. Using this function may result in incorrect results or the program may throw an exception. It is recommended to use the getaddrinfo function instead of this function.

  • For a domain name that already has an A record, after adding an AAAA record, regardless of the network environment between the client and the server:

    • In most cases, it works fine for both the client and the server.

    • The following situation may cause a work abnormality:
      This function returns incorrect results when C's gethostbyname is used and options inet6 is configured in resolv.conf

  • After testing, the priorities of IPv4 and IPv6 in dual-stack networks are as follows:

    • Prioritize using IPv6 to initiate resolution requests

    • Prioritize IPv6 requests to establish connections (TCP, UDP)

    • Prioritize resolution of A address records

References

  • How to choose between IPv4 and IPv6 in Windows 8: Connecting with IPv6 in Windows 8
    (https://blogs.msdn.microsoft.com/b8/2012/06/05/connecting-with-ipv6-in-windows-8/)

  • Windows fallback mechanism when IPv6 is not available: Is there any setting for connection timeout when IPv6 fallback to IPv4?
    (https://social.technet.microsoft.com/Forums/en-US/d09e938a-a594-4766-8898-3926a81fc5dc/is-there-any-setting-for-connection-timeout-when-ipv6-fallback-to-ipv4?forum=w7itpronetworking)

  • The currently widely used IPv4 and IPv6 preference algorithm is Happy Eyeballs
    (https://en.wikipedia.org/wiki/Happy_Eyeballs):

    • Currently, the projects using this algorithm are: Chrome, Opera 12.10, Firefox version 13, OS X, cURL

    • This algorithm will give priority to IPv6 links.

    • The principle of this algorithm can be found in RFC 6555 (Happy Eyeballs: Success with Dual-Stack Hosts)
      (https://tools.ietf.org/html/rfc6555)

    • The simplified workflow of this algorithm is as follows:

    1. When the client is in a dual-stack environment, the client will initiate a resolution request for the domain name A record and AAAA record to the cache DNS server and receive the resolution result, corresponding to 1-4 in the following figure

    2. After the client obtains the resolved address, it will use both IPv4 and IPv6 links to try to establish a connection, corresponding to 6-7 in the figure below. When the IPv6 link is established before the IPv4 link, or the IPv4 link has been established, but within a short time interval, the IPv6 link also successfully establishes a connection, then in these two cases the client should use the IPv6 link to complete subsequent network requests, corresponding to 8-12 in the figure.

Test Method

Resolve domain name

C/C++

  • gethostbyname

Linux

  1. #include <stdio.h>
  2. #include <netdb.h>
  3. #include <arpa/inet.h>
  4.  
  5. int main( void )
  6. {
  7. int i = 0 ;
  8. char str[ 32 ] = { 0 };
  9. struct hostent* phost = NULL;
  10.  
  11. phost = gethostbyname( "IPv6test.ntes53.netease.com" );
  12. printf( "%s" , inet_ntoa(*((struct in_addr*)phost->h_addr)));
  13.          
  14. return   0 ;
  15. }

Windows

  1. #include <winsock.h>
  2. #include <Windows.h>
  3. #include <stdio.h>
  4.  
  5. #pragma comment (lib, "ws2_32.lib" )
  6.  
  7. int main( void ) {
  8. WSADATA wsaData = { 0 ,};
  9. struct in_addr addr = { 0 ,};
  10. struct hostent *res;
  11. int i = 0 ;
  12.  
  13. WSAStartup(MAKEWORD( 2 , 2 ), &wsaData);
  14.  
  15. res = gethostbyname( "IPv6test.ntes53.netease.com." );
  16. while (res->h_addr_list[i] != 0 ) {
  17. addr.s_addr = *(u_long *) res->h_addr_list[i++];
  18. printf( "IP Address: %s\n" , inet_ntoa(addr));
  19. }
  20.  
  21. WSACleanup();
  22. }

getaddrinfo

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <netdb.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <arpa/inet.h>
  8.  
  9. int lookup_host ()
  10. {
  11. struct addrinfo hints, *res;
  12. int errcode;
  13. char addrstr[ 100 ];
  14. void *ptr;
  15.  
  16. memset (&hints, 0 , sizeof (hints));
  17. hints.ai_family = AF_INET;
  18.  
  19. errcode = getaddrinfo ( "IPv6test.ntes53.netease.com" , NULL, &hints, &res);
  20. if (errcode != 0 )
  21. {
  22. perror ( "getaddrinfo" );
  23. return - 1 ;
  24. }
  25. while (res)
  26. {
  27. inet_ntop (res->ai_family, res->ai_addr->sa_data, addrstr, 100 );
  28. switch (res->ai_family)
  29. {
  30. case AF_INET:
  31. ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
  32. break ;
  33. case AF_INET6:
  34. ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
  35. break ;
  36. }
  37. inet_ntop (res->ai_family, ptr, addrstr, 100 );
  38. printf ( "IPv%d address: %s (%s)\n" , res->ai_family == PF_INET6 ? 6 : 4 ,
  39. addrstr, res->ai_canonname);
  40. res = res->ai_next;
  41. }
  42. return   0 ;
  43. }
  44. int main ( void )
  45. {
  46. lookup_host();
  47. }

windows

  1. #define WIN32_LEAN_AND_MEAN
  2. #define _WIN32_WINNT 0x501  
  3. #include <windows.h>
  4. #include <winsock2.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <sys/types.h>
  9. #include <ws2tcpip.h>
  10.  
  11. #pragma comment (lib, "Ws2_32.lib" )
  12.  
  13. // int iResult;  
  14. WSADATA wsaData;
  15. int iResult = WSAStartup(MAKEWORD( 2 , 2 ), &wsaData);
  16.  
  17. int inet_pton( int af, const   char *src, void *dst)
  18. {
  19. struct sockaddr_storage ss;
  20. int size = sizeof(ss);
  21. char src_copy[INET6_ADDRSTRLEN+ 1 ];
  22.  
  23. ZeroMemory(&ss, sizeof(ss));
  24. /* stupid non-const API */  
  25. strncpy (src_copy, src, INET6_ADDRSTRLEN+ 1 )
  26. src_copy[INET6_ADDRSTRLEN] = 0 ;
  27.  
  28. if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0 ) {
  29. switch (af) {
  30. case AF_INET:
  31. *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
  32. return   1 ;
  33. case AF_INET6:
  34. *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
  35. return   1 ;
  36. }
  37. }
  38. return   0 ;
  39. }
  40. const   char *inet_ntop( int af, const   void *src, char *dst, socklen_t size)
  41. {
  42. struct sockaddr_storage ss;
  43. unsigned long s = size;
  44. ZeroMemory(&ss, sizeof(ss));
  45. ss.ss_family = af;
  46. switch (af) {
  47. case AF_INET:
  48. ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
  49. break ;
  50. case AF_INET6:
  51. ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src;
  52. break ;
  53. default :
  54. return NULL;
  55. }
  56. /* cannot direclty use &size because of strict aliasing rules */  
  57. return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0 )?
  58. dst : NULL;
  59. }
  60. int lookup_host ()
  61. {
  62. struct addrinfo hints, *res;
  63. int errcode;
  64. char addrstr[ 100 ];
  65. void *ptr;
  66. memset (&hints, 0 , sizeof (hints));
  67. hints.ai_family = AF_INET6;
  68. errcode = getaddrinfo ( "IPv6test.ntes53.netease.com" , NULL, &hints, &res);
  69. if (errcode != 0 )
  70. {
  71. perror ( "getaddrinfo" );
  72. printf( "%d" ,errcode);
  73. return - 1 ;
  74. }
  75. while (res)
  76. {
  77. // inet_ntop (res->ai_family, res->ai_addr->sa_data, addrstr, 100);  
  78. sockaddr_in in1;
  79. memcpy(&in1.sin_addr, res->ai_addr->sa_data, sizeof(res));
  80. switch (res->ai_family)
  81. {
  82. case AF_INET:
  83. ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
  84. break ;
  85. case AF_INET6:
  86. ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
  87. break ;
  88. }
  89. inet_ntop(res->ai_family, ptr, addrstr, 100 );
  90. // sockaddr_in6 in;  
  91. // memcpy(&in.sin6_addr, ptr, sizeof(ptr));  
  92. printf ( "IPv%d address: %s (%s)\n" , res->ai_family == PF_INET6 ? 6 : 4 ,
  93. addrstr, res->ai_canonname);
  94. //printf ("IPv%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4,  
  95. // inet_ntoa(in.sin6_addr), res->ai_canonname);  
  96. res = res->ai_next;
  97. }
  98. return   0 ;
  99. }
  100. int main ( void )
  101. {
  102. printf( "start\n" );
  103. lookup_host();
  104. }
  105. }

Python

  • socket.gethostbyname

  1. import socket
  2. result = socket.gethostbyname( "IPv6test.ntes53.netease.com" )
  3. print result
  • getaddrinfo
  1. import socket
  2. result = socket.getaddrinfo( "IPv6test.ntes53.netease.com" , 0 , socket.AF_INET6)
  3. print result
  4. result = socket.getaddrinfo( "IPv6test.ntes53.netease.com" , 0 , socket.AF_INET)
  5. print result
  6. result = socket.getaddrinfo( "IPv6test.ntes53.netease.com" , 0 , socket.AF_UNSPEC)
  7. print result

When socktype is not specified, this value defaults to socket.AF_UNSPEC .

HTTP Request

Python

requests package

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

C++

  1. #include <stdio.h>  
  2. #include <curl/curl.h>  
  3.  
  4. int main( void )
  5. {
  6. CURL *curl;
  7. CURLcode res;
  8.  
  9. curl = curl_easy_init();
  10. if (curl) {
  11. curl_easy_setopt(curl, CURLOPT_URL, "http://IPv6test.ntes53.netease.com:8000" );
  12. /* example.com is redirected, so we tell libcurl to follow redirection */   
  13. curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  14. // curl_easy_setopt(curl, CURL_IPRESOLVE_V6, 1L); // Use IPv6 address  
  15. // curl_easy_setopt(curl, CURL_IPRESOLVE_V4, 1L); // Use IPv4 address  
  16. // curl_easy_setopt(curl, CURL_IPRESOLVE_WHATEVER, 1L); // Get the IPv4 or IPv6 address allowed by the system  
  17. /* Perform the request, res will get the return code */   
  18. res = curl_easy_perform(curl);
  19. /* Check for errors */   
  20. if (res != CURLE_OK)
  21. fprintf(stderr, "curl_easy_perform() failed: %s\n" ,
  22. curl_easy_strerror(res));
  23.  
  24. /* always cleanup */   
  25. curl_easy_cleanup(curl);
  26. }
  27. return 0;
  28. }

<<:  Although there are nearly 100 5G terminals, they are not even the tip of the iceberg.

>>:  Can 6G technology directly skip 5G technology?

Recommend

Just-in-time infrastructure: Infrastructure at the speed of business

Enterprises are under increasing pressure to deli...

JD Interview: What are the differences between Cookie, Session and Token?

As one of the three giants of traditional e-comme...

The arrival of the fourth largest operator, what can it change?

On October 12, China Broadcasting Network Co., Lt...

What exactly does edge computing mean?

The word "edge" has been given a new de...

The Role of Machine Learning and AIOps in Network Performance Management

Before the pandemic brought a shift in business o...

5G is coming: analyzing the fronthaul solution of high-density wireless systems

The LTE era of wireless communications has been f...

What happens when SDN meets 5G?

SDN is a profound change to traditional IP networ...

Why is 5G suddenly not popular anymore?

In the past two days, an article about the curren...