彩神3分快3助手一份完整的 IPv6 环境下 DNS 相关测试

  • 时间:
  • 浏览:22
  • 来源:5分时时彩官方

 


董涛,网易游戏高级运维工程师,主要工作方向为网易集团 DNS 的运维与开发。

张欣接,网易集团 DNS 团队负责人,负责网易域名系统的整理及生态建设。

一、IPv6 支持度报告

IPv6 简介

IPv6(In彩神3分快3助手te彩神3分快3助手rnet Protocol version 6,互联网通信协议第 6 版)是用于数据包交换互联网彩神3分快3助手络的网络层协议,是 IETF(互联网工程任务小组 Internet Engineering Task Force,简称 IETF)设计的用来替代 IPv4 协议的互联网协议版本。

随着电子技术及网络技术的发展,计算机网络导致 与朋友的生活密切相关,导致 身边的每一样电子设备都需要连入网络,IPv4 的地址数量导致 无法满足。IPv6 的应用将彻底处理哪此问题报告 。IPv6 由 128 比特位构成,单从数量级上来说,IPv6 所拥有的地址容量是 IPv4 的约 8×10 28 倍,达到 2 128(约 3.4 × 10 38)个。这不但处理了网络地址资源数量的问题报告 ,同时也为物联网的发展提供了基础。

IPv6 地址的表达形式采用 32 个十六进制数,由有有好几个 多 逻辑帕累托图组成:有有好几个 多 64 位的网络前缀和有有好几个 多 64 位的主机地址,主机地址通常根据物理地址自动生成,叫做 EUI-64(导致 64- 位扩展唯一标识)。例如 801:0db8:85a3:08d3:1319:8a2e:0370:7344 是有有好几个 多 合法的 IPv6 地址。

IPv6 全球部署更新

  • 808 年,欧盟发布了“欧洲部署 IPv6 行动计划”

  • 809 年,日本发布《IPv6 行动计划》

  • 2010 年,美国政府发布 IPv6 行动计划

  • 2010 年,韩国发布“下一代互联网协议(IPv6) 有助计划”

  • 2012 年,加拿大政府发布了《加拿大政府 IPv6 战略》

  • 2017 年,国务院办公厅印发《推进互联网协议第六版(IPv6)规模部署行动计划》

操作系统 IPv6 支持度

应用软件 IPv6 支持度

客户端软件

1、浏览器

服务器软件

1、进程开发软件

2、数据库

总结

毋庸置疑,下一代互联网 IPv6 是万物互连,智能化时代基础网络的重要支撑协议,可不都里能 从有有好几个 多 只拥有 IPv4 协议的巨型网络要全面、平稳地过渡到有有好几个 多 纯 IPv6 网络需要一段极为漫长的时间。从报告统计的数据来看,各种基础软件和应用软件都已基本支持 IPv6。现在在国内的环境下,IPv6 的基础环境还需要完善,为此工信部也发布了

《推进互联网协议第六版(IPv6)规模部署行动计划》(http://www.miit.gov.cn/n1146290/n4388791/c6166476/content.html)

推动各单位加快支持 IPv6。

IPv6 支持度报告的数据来源是:下一代国家互联网中心在 2017 年 11 月发布的 IPv6 支持度报告

(https://www.ipv6ready.org.cn/public/download/ipv6.pdf), 感兴趣的同学能可不都里能 了查看原文。

二、IPv6 环境下 DNS 相关测试

背景介绍

名词简介

  • A 记录

A 记录是有有好几个

多

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

AAAA 是有有好几个

多

域名指向 IPv6 地址的解析结果。导致

我应该

有有好几个

多

域名解析到 IPv6 地址,则需要设置此种类型的解析结果。同有有好几个

多

域名能可不都里能

了同时有 A 与 AAAA 三种记录类型, 例如 ipv6test.ntes53.netease.com. 1800 IN AAAA 2403:c80:80:800::7b3a:a646
  • 缓存 DNS 服务器

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

  • 权威 DNS 服务器

用于域名的管理。权威 DNS 服务器只对我本人所拥有的域名进行域名解析,对于是是不是

我本人的域名则拒绝应答。例如网易的权威 DNS 服务器只会响应网易域名的请求,对于某些域名,则拒绝应答。

  • 双栈网络环境

双栈网络环境即客户端或服务器同时拥有 IPv4、IPv6 三种网络环境,能可不都里能

了简单的理解为机器上既有 IPv4 地址又有 IPv6 地址

测试场景

下文中所有测试使用的进程均为测试法律法律依据中的进程

1.目前纯 IPv4 环境下,仅新增 AAAA(IPv6) 记录可不都里能 ,对已有进程的影响

假定导致 处于了有有好几个 多 进程(C 进程、python 进程、浏览器等),通过域名访问某个服务,现在在 IPv4 环境下一切工作正常。当给你这人 域名增加了 AAAA 记录可不都里能 ,测试对目前的进程的影响。

域名解析

HTTP 请求

客户端

结论

  • 当在某域名原有的 A 记录类型的基础上新增 AAAA 记录后,原有的进程工作正常

2.客户端 IPv6/v4 双栈环境下,测试进程的行为

假定用户的环境是双栈环境,假定有有好几个 多 服务通过域名对外提供服务,测试你这人 情况表下进程的行为。

域名解析

HTTP 请求

客户端

结论

  • 当域名同时处于 A 与 AAAA 记录,可不都里能 网络类型为双栈网络时,绝大多数进程工作正常。仅有三种情况表例外,即进程中使用了 gethostbyname 函数,同时 resolv.conf 中配置了 options inet6 时,此时进程会返回错误的解析结果

  • RFC 以及绝大多数实现法律法律依据,均回优先使用 IPv6 地址建立连接

  • 双栈环境下,客户端使用 IPv4 与 IPv6 缓存 DNS 服务器获取的解析结果是一致的

3. 客户端纯 IPv6 环境下,测试能可不都里能 了正常工作

假定用户可不都里能 了 IPv6 地址,DNS 也是使用 IPv6 地址 (DNS 需要有双栈环境,导致 现在可不都里能 有权威服务器这么 IPv6 地址,纯 IPv6 环境下无法正常工作),假定有有好几个 多 服务通过域名(同时拥有 A、AAAA 记录)对外提供服务,测试服务是是不是能可不都里能 了正常访问。

域名解析

HTTP 请求

客户端

结论

当某域名即处于 A 记录 又处于 AAAA 记录时:

  • 导致 进程中使用了 gethostbyname 时,进程导致 会拿到错误的解析结果,取决于 resolv.conf 的配置(当配置了 option inet6 时,会获取到错误的解析结果)

  • Windows 在你这人 情况表下,帕累托图应用工作不正常。在指定使用 IPv6 socket 的情况表下,进程工作正常。

  • 根据安卓官方的描述,Android 6.0 可不都里能 的版本导致 支持 IPv6,可不都里能 根据对国内大多数厂商的安卓手机的调研,目前国内安卓手机很少能可不都里能 了原生支持 IPv6

4. DNS 解析测试

这里测试了缓存服务器和权威服务器在各种网络环境下,优先使用的解析链路。

结论

当权威服务器和缓存服务器均支持 ipv6 时,缓存服务器优先使用 ipv6 链路进行解析,某些情况表均使用 ipv4 链路进行解析。

结论

  • 经过测试与查证,gethostbyname 不支持 IPv6,使用此函数导致 会拿到错误的结果导致 进程抛出异常。建议使用 getaddrinfo 函数取代此函数

  • 目前导致 处于 A 记录的域名,加进 AAAA 记录后,不管客户端与服务端的网络环境如可:

    • 绝大多数情况表下对客户端与服务端工作正常

    • 下面三种情况表下会出现工作异常:

      当使用了 C 的 gethostbyname 可不都里能 在 resolv.conf 中配置了 options inet6时,此函数返回错误的结果

  • 经过测试,双栈网络下 IPv4 与 IPv6 的优先级:

    • 优先使用 IPv6 发起解析请求

    • 优先使用 IPv6 请求建立连接 (TCP, UDP)

    • 优先解析 A 地址记录

参考资料

  • Windows 8 IPv4 与 IPv6 选折 的法律法律依据:Connecting with IPv6 in Windows8

    (https://blogs.msdn.microsoft.com/b8/2012/06/05/connecting-with-ipv6-in-windows-8/)

  • Windows 当 IPv6 不可用后的回退机制: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)

  • 目前广泛使用的 IPv4 与 IPv6 优先选折 算法为 Happy Eyeballs

    (https://en.wikipedia.org/wiki/Happy_Eyeballs):

    • 目前使用此算法的项目有:Chrome, Opera 12.10, Firefox version 13, OS X, cURL

    • 此算法会优先选折 IPv6 链路使用

    • 此算法的原理可参考 RFC 6555(Happy Eyeballs: Success with Dual-Stack Hosts)

      (https://tools.ietf.org/html/rfc6555)

    • 此算法的简略工作流程如下:

    1. 当客户端是双栈环境时,客户端会向缓存 DNS 服务器发起域名 A 记录与 AAAA 记录的解析请求,并受到解析结果,对应下图中的 1-4

    2. 客户端获取到解析地址后,会同时使用 IPv4 与 IPv6 三种链路尝试建立连接,对应下图中的 6-7。当 IPv6 链路比 IPv4 链路先建立连接,导致 IPv4 导致 建立连接,可不都里能 在很短的时间间隔内,IPv6 也成功建立连接后,则这三种情况表下客户端应该使用 IPv6 链路完成后续的网络请求,对应图中的 8-12

测试法律法律依据

解析域名

C/ C ++

  • gethostbyname

Linux

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

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(22), &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(); 

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.       struct addrinfo hints, *res; 
  11.       int errcode; 
  12.       char addrstr[80]; 
  13.       void *ptr; 
  14.  
  15.       memset (&hints, 0, sizeof (hints)); 
  16.       hints.ai_family = AF_INET; 
  17.  
  18.       errcode = getaddrinfo ("IPv6test.ntes53.netease.com", NULL, &hints, &res); 
  19.       if (errcode != 0
  20.         { 
  21.           perror ("getaddrinfo"); 
  22.           return -1
  23.         } 
  24.       while (res) 
  25.         { 
  26.           inet_ntop (res->ai_family, res->ai_addr->sa_data, addrstr, 80); 
  27.           switch (res->ai_family) 
  28.             { 
  29.             case AF_INET: 
  30.               ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; 
  31.               break
  32.             case AF_INET6: 
  33.               ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; 
  34.               break
  35.             } 
  36.           inet_ntop (res->ai_family, ptr, addrstr, 80); 
  37.           printf ("IPv%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4
  38.                   addrstr, res->ai_canonname); 
  39.           res = res->ai_next; 
  40.         } 
  41.       return 0
  42.     } 
  43.     int main (void
  44.         lookup_host(); 
  45.     } 

windows

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

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 

当不指定 socktype 时,此值默认为 socket.AF_UNSPEC

HTTP 请求

Python

requests 包

  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.   CURL *curl; 
  6.   CURLcode res; 
  7.  
  8.   curl = curl_easy_init(); 
  9.   if(curl) { 
  10.     curl_easy_setopt(curl, CURLOPT_URL, "http://IPv6test.ntes53.netease.com:8000"); 
  11.       
  12.     curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); 
  13.        
  14.        
  15.        
  16.       
  17.     res = curl_easy_perform(curl); 
  18.       
  19.     if(res != CURLE_OK) 
  20.       fprintf(stderr, "curl_easy_perform() failed: %s\n"
  21.               curl_easy_strerror(res)); 
  22.  
  23.       
  24.     curl_easy_cleanup(curl); 
  25.   } 
  26.   return 0; 
 

【编辑推荐】

【责任编辑:

张燕妮

TEL:(010)68476806】



点赞 0