与低级C API的IPv6兼容性问题

时间:2017-09-17 19:13:38

标签: objective-c c sockets

Apple需要IPv6兼容性。似乎有点过早,但我想有人必须强迫它被广泛采用。

我有一个客户端有一些遗留代码,由于这种不兼容性而不再被批准用于App Store。我没有自己编写软件,特别是从未触及过这部分代码。在低级别C网络方面,我不是一个忍者。

我告诉客户,部分问题是他们有一台仅支持IPv4的服务器并让我们将IPv4地址硬编码到该服务器。我将IPv4地址更新为域名,并告诉他们他们的服务器必须支持IPv6。因此,他们将它们全部移动,并在完成任何测试之前翻转开关。几天前我收到通知,他们在商店里的所有软件都不再有效。这就是我们所处的困境。

以下是我可以使用的一些潜在问题之一。

连接到端口的服务器不仅不响应IPv6,而且还有一些不兼容的低级API正在使用。

我遇到的第一件事是使用let timeStatus = document.getElementById('identifier'); timeStatus.innerHTML = 'new time'; 。显然这不支持IPv6。我一直试图用gethostbyname()修复它,但我的sockaddr并不完全相同。

我可以看到的第二个问题显然我需要使用getaddrinfo()而不是AF_UNSPEC。所以我试图以下列方式打开一个套接字:

AF_INET

我总是得到-1。

如果我使用int sockfd = socket(AF_UNSPEC, SOCK_STREAM, 0); 打开袜子,我会更进一步,但后来我遇到了这个问题:

AF_INET

所以otherAddr sockaddr * 0x618000220680 0x0000618000220680 sa_len __uint8_t '\x1c' sa_family sa_family_t '\x1e' sa_data char [14] "\x13\x88" otherAddrCast sockaddr * 0x7000052d3c28 0x00007000052d3c28 sa_len __uint8_t '\0' sa_family sa_family_t '\0' sa_data char [14] "\x13\x88\"Ԛ\\" 中的一些是相同的。如果我不将sa_data转换为sockaddr_in,则struct sockaddr*是相同的。

问题是我不知道大多数这意味着什么。帮助

编辑:这是我的代码。假设我只得到1个addr(因为我)

sa_data

1 个答案:

答案 0 :(得分:1)

您根本不应该AF_UNSPEC使用socket()。您必须使用AF_INET(IPv4)或AF_INET6(IPv6)。

您可以使用AF_UNSPEC hints输入参数getaddrinfo()来表示您愿意接受IPv4和IPv6地址作为输出。输出中的实际地址可以是AF_INETAF_INET6。或者,您可以将提示设置为AF_INET仅限IPv4输出。或AF_INET6仅用于IPv6输出。

您应该遍历getaddrinfo()返回的列表。对于列表中的每个地址:

  • 将其ai_familyai_socktypeai_protocol字段传递给socket()
  • 然后将其ai_addrai_addrlen字段传递给bind()(服务器)或connect()(客户端)。

对于为侦听服务器报告的所有地址以及为客户端报告的所有地址重复此操作,直到成功连接为止。

这样,您创建的每个套接字都匹配它正在使用的地址的IP版本,并且您正在将适当的匹配sockaddr_in(IPv4)或sockaddr_in6(IPv6)传递给{{1 }} / bind()

成功侦听服务器套接字或成功连接的客户端套接字后,如果需要使用connect()accept()getsockname()从套接字检索IP,请确保传递getpeername()结构以填充。sockaddr_storage足以容纳所有已定义的基于sockaddr_storage的结构(并且有很多)。如果成功,则可以根据其sockaddr字段(sockaddr_insockaddr_in6分别将其输入sa_familyAF_INET。其他类似功能也是如此,例如AF_INET6inet_pton()

更新:根据您显示的客户端代码,请尝试以下方式:

inet_ntop()