Ios-about iOS app support IP6

Source: Internet
Author: User
Tags sin htons

First, ipv6-only support is what?

The first IPV6, is the expansion of the IPV4 address space. At present, when we use the iOS device to connect to the WiFi, 4G, 3G and other networks, the device is assigned to the address is IPV4 address, but as operators and enterprises gradually deployed IPV6 Dns64/nat64 Network, the device assigned address will become IPV6 address, These networks are known as ipv6-only networks and can still be used to get the content provided by the IPV4 address. The client requests the domain name resolution to the server, first through the DNS64 server to query the address of the IPV6, if the query is not, then to the DNS server to query the IPV4 address, the DNS64 server to synthesize a IPV6 address, and eventually return a IPV6 address to the client. :

In Mac OS 10.11+ dual-nic Mac Machine (Ethernet port + Wireless card), we can test whether the application supports Ipv6-only network by simulating the network environment of such a local IPv6 dns64/nat64, the approximate principle is as follows:

Reference: Https://developer.apple.com/library/mac/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview /understandingandpreparingfortheipv6transition/understandingandpreparingfortheipv6transition.html#//apple_ref/ Doc/uid/tp40010220-ch213-sw1
Second, how does Apple audit support ipv6-only?

First 1th: This is said to support Ipv6-only network, in fact, let the application in the IPV6 Dns64/nat64 network environment can still run normally. But considering that our actual network environment is still a IPV4 network, the application needs to be able to ensure availability in both IPV4 and IPV6 environments. From this point, Apple does not scan IPV4 's proprietary API to deny auditing because IPV4 APIs and IPV6 API calls both exist in the code (but to reduce the risk of audit rejection, it is recommended to replace the IPV4 proprietary API with IPV6 's compatible API).

Second 2nd: Apple's official statement iOS9 began to support the transition to IPV6, where ios9.2+ supported the IPV4 address synthesized by getaddrinfo method IPV6 address (the ability to synthesize IPV6 addresses were Added to getaddrinfo in IOS 9.2 and OS X 10.11.2). The reachability library provided in the IOS8 system, when switching from IPV4 to IPV6 network, or from IPV6 network to IPV4, is unable to monitor the network status changes. Some developers also ask Apple's audit department for these bugs, and the answer is that they only need to ensure IPV6 compatibility on Apple's newest system.

Finally 3rd: As long as the application of mainstream support IPV6, through the Apple audit can. For modules that do not support IPV6, it takes a while for our IPV6 network to be deployed and will not affect the use of our users for a short period of time. But with the deployment of the 4G network IPV6, this part of the module still needs to be gradually arranged to support the manpower.

Add 4th: If the application has been using the IPV4 address directly through the nsurlconenction or Nsurlsession for network requests (generally requires the server to allow, and the client needs to disguise host in the header), tested, IPV6 network environment, Systems that use IPV4 addresses directly on iOS9 and above still have normal access, and are not accessible in iOS8.4 and below; Apple's explanations and suggestions are this:

Note:in IOS 9 and OS X 10.11 and later, Nsurlsession and cfnetwork automatically synthesize IPv6 addresses from IPV4 Lite RALs locally on devices operating on Dns64/nat64 networks. However, you should still work to rid your code of IP address literals.

Third, how can application support Ipv6-only?

For how to support the Ipv6-only, the official gave the following criteria: (This is not explained here, you can see the reference link above)

1. Use high-level Networking frameworks;
2. Don ' t use IP address literals;
3. Check Source Code for IPv6 Dns64/nat64 incompatibilities;
4. Use the System APIs to synthesize IPv6 Addresses;
Does 3.1 nsurlconnection support IPV6?

The official remark made us wonder: using high-level networking APIs such as Nsurlsession and the Cfnetwork frameworks and you connect by name, You should not need to change anything for your apps to work with IPV6 addresses

Only the nsurlsession and Cfnetwork APIs do not need to be changed, but there is no mention of nsurlconnection. From the references above, we see that nsurlsession, nsurlconnection, and Cocoa's URL loading system, can guess Nsurlconnection is iOS9 on IPV6.

Application inside the API network request, everyone will generally choose afnetworking to send the request, because of historical reasons, the application of the code is basically a deep reference to the Afhttprequestoperation class, So at present, the API network requests need to send through nsurlconnection, so we must confirm whether Nsurlconnection supports IPV6. After testing, Nsurlconnection is supporting IPV6 on the latest iOS9 systems.

3.2 Cocoa URL Loading system support IPV6 from which version of iOS?

Currently our minimum version of the application also needs to support iOS7, although Apple only requires the latest version to support Ipv6-only, but in the sense of being responsible for the user, we still need to figure out whether the API Loading system on the lower version supports IPV6.

(To fix me, make some experiments) ~ ~ ~

3.3 reachability Do I need to modify the support IPV6?

We can find out that the application has used a lot of reachability for network state judgment, but it uses IPV4 's dedicated API.

In the Pods:reachability
Af_inet FILES:REACHABILITY.M
struct sockaddr_in files:reachability.h, reachability.m
How should the reachability support IPV6? (1) The latest version of GitHub's Open Source Library reachability is 3.2, Apple has a support IPV6 reachability official example, we compare the source code, It's no different from reachability on GitHub. (2) We usually use a 0.0.0.0 (zeroaddress) to open the network status monitoring, after we test, on the iOS9 above the system IPV4 and IPV6 network environment can be used normally But IPV4 and IPV6 are not able to monitor changes in network status on IOS8, possibly because Apple has not been related to IPV6 support in IOS8. (This still satisfies Apple's requirement to support the IPV6 network on the latest system version). (3) When everyone is asking reachability to add support for IPV6, in fact, Apple in iOS9 above the zero address has been special treatment, the official statement is this:

Reachabilityforinternetconnection:this monitors the address 0.0.0.0, which reachability treats as a special token that CA uses it to actually monitor the general routing status of the device, both IPV4 and IPv6.

+ (Instancetype) reachabilityforinternetconnection {
struct sockaddr_in zeroaddress;
Bzero (&zeroaddress, sizeof (zeroaddress));
Zeroaddress.sin_len = sizeof (zeroaddress);
zeroaddress.sin_family = af_inet;
return [self reachabilitywithaddress: (const struct SOCKADDR *) &zeroAddress];
}
To sum up, reachability do not need to make any changes, on the iOS9 can support IPV6 and IPV4, but there will be a bug in IOS9, but the Apple audit does not care.

Iv. How does the underlying socket API support both IPV4 and IPV6?

Because of the use of Network Diagnostics in the application of components, a large number of use of the underlying socket API, so for IPV6 support, this block is a play. If you use a long connection in your application, it will necessarily use the underlying socket API, which is also required to support IPV6. For how the socket supports both IPV4 and IPV6, you can refer to Google's Open Source Library Cocoaasyncsocket.

Here's how we can support both IPV4 and IPV6 for our Open Source Network Diagnostics component. Open Source Address: Https://github.com/Lede-Inc/LDNetDiagnoService_IOS.git The main functions of this network diagnostic component are as follows:

Local network environment monitoring (native ip+ local gateway + local dns+ domain name resolution);
Monitoring the connectivity of domain names via TCP connect;
The connection time of the target host is monitored by pinging;
ICMP time-consuming for each router node in the middle of the target host through the traceroute monitoring device;
4.1 Conversion of IP address from binary to symbolic

Previously we were using Inet_ntoa () binary to sign, this API can only convert IPV4 address. Inet_ntop () is compatible with the conversion of IPV4 and IPV6 addresses. Write a common in6_addr conversion method as follows:

For IPV6
+ (NSString *) formatipv6address: (struct in6_addr) ipv6addr{
NSString *address = nil;

Char Dststr[inet6_addrstrlen];
Char Srcstr[inet6_addrstrlen];
memcpy (Srcstr, &ipv6addr, sizeof (struct in6_addr));
if (Inet_ntop (Af_inet6, Srcstr, DSTSTR, inet6_addrstrlen)! = NULL) {
address = [NSString stringwithutf8string:dststr];
}

return address;
}

For IPV4
+ (NSString *) formatipv4address: (struct in_addr) ipv4addr{
NSString *address = nil;

Char Dststr[inet_addrstrlen];
Char Srcstr[inet_addrstrlen];
memcpy (Srcstr, &ipv4addr, sizeof (struct in_addr));
if (Inet_ntop (Af_inet, Srcstr, DSTSTR, inet_addrstrlen)! = NULL) {
address = [NSString stringwithutf8string:dststr];
}

return address;
}
4.2 Native IP Access support IPV6

The equivalent of We enter the Ifconfig command in the terminal to get the string, and then parse the ifconfig result string to get the IP address of En0 (Wifi), pdp_ip0 (mobile network).

Note: (1) The IPV6 unicast address that starts with FE80 on both the simulator and the real machine affects our judgment, so special processing is done here (when the IP address that is not a unicast address is the native IP address for the first time). (2) in the IPV6 environment, when the real machine test, the first occurrence is a IPV4 address, so in IPV4 conditions for the first time encountered unicast address does not exit.

+ (NSString *) deviceipadress
{
while (temp_addr! = NULL) {
NSLog (@ "ifa_name===%@", [NSString Stringwithutf8string:temp_addr->ifa_name]);
Check if interface is En0 which are the WiFi connection on the IPhone
if ([[NSString Stringwithutf8string:temp_addr->ifa_name] isequaltostring:@ "En0"] | | [[NSString Stringwithutf8string:temp_addr->ifa_name] isequaltostring:@ "Pdp_ip0"])
{
If it is a IPV4 address, direct conversion
if (temp_addr->ifa_addr->sa_family = = af_inet) {
Get NSString from C String
address = [Self formatipv4address: ((struct sockaddr_in *) temp_addr->ifa_addr)->sin_addr];
}

If it's a IPV6 address
else if (temp_addr->ifa_addr->sa_family = = Af_inet6) {
address = [Self formatipv6address: ((struct sockaddr_in6 *) temp_addr->ifa_addr)->sin6_addr];
if (Address &&![ Address isequaltostring:@ "" &&! [Address.uppercasestring hasprefix:@ "FE80"]) Break
}
}

TEMP_ADDR = temp_addr->ifa_next;
}
}
}
4.3 Device gateway address get get support IPV6

In fact, in the IPV4 to obtain the gateway address of the source code based on the modification, the first open to Af_inet->af_inet6, sockaddr-sockaddr_in6, but also need to pay attention to the following changes, is the number of copies of the address bytes. Removed the handling of the roundup. (Parse out the address is always less 4 bytes, the result is the offset wrong, tangled half a day), specific reference source library.

/* Net.route.0.inet.flags.gateway */
int mib[] = {ctl_net, pf_route, 0, Af_inet6, net_rt_flags, rtf_gateway};

if (Sysctl (MIB), sizeof (MIB)/sizeof (int), buf, &l, 0, 0) < 0 xss=removed Xss=removed>rtm_addrs & (1 << ; I xss=removed Xss=removed>sa_len));
} else {
Sa_tab[i] = NULL;
}
}

For IPV6
for (i = 0; I < Rtax>rtm_addrs & (1 << i xss=removed Xss=removed>sin6_len);
} else {
Sa_tab[i] = NULL;
}
}
4.4 Device DNS address get support IPV6
IPV4 only needs to be initialized by Res_ninit, but it needs to be obtained through the res_getservers () interface in the IPV6 environment.

+ (Nsarray *) outputdnsservers{
Res_state res = malloc (sizeof (struct __res_state));
int result = Res_ninit (res);

Nsmutablearray *servers = [[Nsmutablearray alloc] init];
if (result = = 0) {
Union res_9_sockaddr_union *addr_union = malloc (res->nscount * sizeof (Union res_9_sockaddr_union));
Res_getservers (res, addr_union, res->nscount);

for (int i = 0; i < res>nscount; i++) {
if (addr_union[i].sin.sin_family = = af_inet) {
Char Ip[inet_addrstrlen];
Inet_ntop (Af_inet, & (addr_union[i].sin.sin_addr), IP, Inet_addrstrlen);
NSString *dnsip = [NSString Stringwithutf8string:ip];
[Servers Addobject:dnsip];
NSLog (@ "IPv4 DNS IP:%@", DNSIP);
} else if (addr_union[i].sin6.sin6_family = = Af_inet6) {
Char Ip[inet6_addrstrlen];
Inet_ntop (Af_inet6, & (addr_union[i].sin6.sin6_addr), IP, Inet6_addrstrlen);
NSString *dnsip = [NSString Stringwithutf8string:ip];
[Servers Addobject:dnsip];
NSLog (@ "IPv6 DNS IP:%@", DNSIP);
} else {
NSLog (@ "Undefined family.");
}
}
}
Res_nclose (RES);
Free (res);

return [Nsarray arraywitharray:servers];
}
4.4 Domain DNS address acquisition support IPV6

Under the IPV4 network we get through the gethostname, and in the IPV6 environment, through the new gethostbyname2 function.

IPv4
Phot = gethostbyname (HOSTN);

IPv6
Phot = Gethostbyname2 (HOSTN, AF_INET6);
4.5 Ping Scheme supports IPV6

Apple's official offers the latest ping scheme to support IPV6, with the following address: https://developer.apple.com/library/mac/samplecode/SimplePing/Introduction/Intro.html

Just note that: (1) The returned packet removed the Ipheader part, the header part of IPV6 does not return the TTL (Time to Live) field, (2) IPV6 ICMP message does not carry on the checksum processing;

4.6 Traceroute Solution Support IPV6

In fact, through the creation of socket sockets to simulate the transmission of ICMP packets, to calculate time-consuming, two key points to note: (1) IPV6 removed Ip_ttl field, use the hop number ipv6_unicast_hops to represent; (2) The SendTo method is compatible with support for IPV4 and IPV6, but requires the last parameter to set the size of the destination IP address, because the previous parameter only indicates the start address of the IP address. Do not use the unified sizeof (struct sockaddr), because Sockaddr_in and sockaddr are 16 bytes, both can be common, but the SOCKADDR_IN6 data structure is 28 bytes, if not explicitly specified, The SendTo method will always return -1,errono Invalid argument error.

The key code is as follows: (full code reference open Source component)

Constructs a generic IP address structure stuck SOCKADDR

NSString *ipaddr0 = [Serverdnss objectatindex:0];
Set the server host's socket address
NSData *addrdata = nil;
BOOL isIPV6 = NO;
if ([IpAddr0 rangeofstring:@ ":"].location = = Nsnotfound) {
IsIPV6 = NO;
struct sockaddr_in nativeAddr4;
memset (&AMP;NATIVEADDR4, 0, sizeof (NATIVEADDR4));
Nativeaddr4.sin_len = sizeof (NATIVEADDR4);
nativeaddr4.sin_family = af_inet;
Nativeaddr4.sin_port = htons (Udpport);
Inet_pton (Af_inet, ipaddr0.utf8string, &nativeaddr4.sin_addr.s_addr);
Addrdata = [NSData datawithbytes:&nativeaddr4 length:sizeof (NATIVEADDR4)];
} else {
IsIPV6 = YES;
struct SOCKADDR_IN6 nativeAddr6;
memset (&AMP;NATIVEADDR6, 0, sizeof (NATIVEADDR6));
Nativeaddr6.sin6_len = sizeof (NATIVEADDR6);
nativeaddr6.sin6_family = Af_inet6;
Nativeaddr6.sin6_port = htons (Udpport);
Inet_pton (Af_inet6, ipaddr0.utf8string, &nativeaddr6.sin6_addr);
Addrdata = [NSData datawithbytes:&nativeaddr6 length:sizeof (NATIVEADDR6)];
}

struct SOCKADDR *destination;
Destination = (struct sockaddr *) [addrdata bytes];

Create socket
if (Recv_sock = socket (destination->sa_family, SOCK_DGRAM, isIPV6? IPPROTO_ICMPV6:IPPROTO_ICMP)) < 0 xss=removed>sa_family, SOCK_DGRAM, 0) &lt; 0)

Set the TTL of the sender socket
if (isIPV6?
SetSockOpt (Send_sock,ipproto_ipv6, Ipv6_unicast_hops, &ttl, sizeof (TTL)):
SetSockOpt (Send_sock, Ipproto_ip, Ip_ttl, &ttl, sizeof)) &lt; 0)

Send a successful return value equal to the length of the message sent
ssize_t Sentlen = sendto (Send_sock, cmsg, sizeof (CMSG), 0,
(struct sockaddr *) destination,
isipv6?sizeof (struct sockaddr_in6): sizeof (struct sockaddr_in));

Ios-about iOS app support IP6

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.