System Frameworks • iOS, macOS, tvOS, watchOS • 39:26
The next wave of the Internet's evolution is happening now. You'll learn best practices for supporting IPv6, restricting cellular usage, and using Quality of Service to create a fast lane for your iOS apps. Discover how to support a multilingual Internet by using UTF-8, and how new internationalized domain names and email addresses affect you.
Speaker: Stuart Cheshire
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript has potential transcription errors. We are working on an improved version.
Good afternoon, ladies and gentlemen. It's great to see so many people here. How many of you are here for the first time at WWDC? Wow! That's incredible. Well, welcome. I hope WWDC is going well for you. Now we're going to talk about some networking topics. I've got five things to cover today. We're going to give you an update on Explicit Congestion Notification that we talked about last year. We're going to give you an update in the progress on IPv6. We're going to talk a little bit about international text, which is becoming increasingly important.
We're going to explore how you control access to network interfaces to avoid running up big data bills for your customers. And we're going to finish off with some discussion of network quality of service. You may have heard about the Apple Cisco Fastlane announcement. We're going to talk a little bit about how that might apply to your applications. So let's start with ECN. To recap from last year, we showed how Smart Queue Management and marking packets instead of dropping them can lower latency, reduce delays due to retransmission, and improve the user experience for all applications, and especially for things like streaming video.
In iOS 9, we did not enable ECN for TCP connections, but in an unrelated change, the VPN software would pay attention to ECN markings. We found one ISP in Germany that marked all packets "congestion experienced," which was bad for VPN. The good news is they fixed their network within a couple of weeks. We had no reports of any problems anywhere else in the world, and what that tells us now is we rolled out iOS all around the world, found one problem, fixed it; the Internet is now safe for ECN.
And because of that, in iOS 9.3 and OS X El Capitan, five percent of TCP connections at random are using ECN, and we're using this to gather performance data and check that the Internet continues to be safe for ECN. In the Developer Seed that you have already, 100 percent of Wi-Fi connections and 100 percent of connections on these three carriers are now using ECN. So last year, I reported that 56 percent of the Alexa top million websites supported ECN, which is a pretty impressive support number for a technology no one was using.
I talked to my good friends at ETH Zurich, and Brian, Brian Trammell and Mira Coolwind, and their colleagues reran the experiment for us. This year the percentage is up to 70 percent. And if you only look at IPv6 sites, it's up to 83 percent. So this is a call to action to ISPs and carriers and their vendors who sell equipment to them.
The clients are now doing ECN. The services are supporting ECN. It's time for the network in the middle to start marking packets instead of dropping them. It gives you a better user experience, it reduces delays due to retransmission, and it makes more efficient use of your network because you are avoiding wasted bandwidth retransmitting packets. Our next topic is IPv6.
World IPv6 launch was four years ago last week, and it continues to grow. I looked at a variety of statistics, and I'm going to show you just a small sampling here. I looked at accesses to Apple's home page but coming over IPv6. In Belgium, it's now up to 39 percent. On T-Mobile USA, we're up to 54 percent. On Verizon, we're up to 74 percent. So it's pretty clear now on these carriers that IPv6 traffic is the majority.
And the reason is clear. IPv6 is simpler, it's more reliable, it's less expensive to operate. So it's very clear why the carriers want to move to IPv6. But at what cost to developers and customers? Is IPv6 less mature? Is it slower? Is there less capacity allocated to IPv6? These are important questions, and content providers and developers pay close attention to this.
They use statistics gathering in the web browsers to measure things like page load times for every single one of their users viewing the web page and report that back, so they can tell how well their product is working in different countries around the world, different ISPs, different carrier networks.
LinkedIn reports that now 10 percent of their traffic is over IPv6, and they find the page load time on average is 10 to 40 percent faster than over IPv4. They theorize that that is due to less overhead, setting up connections through overloaded large scale NATs. Facebook found similar results. 45 percent of their traffic is now over IPv6, and they reported recently that on average ATP GET requests are 15 percent faster over IPv6. If you only look at the iPhone data in that collection, it turns out to be 30 percent over IPv6.
So IPv6 is better for network operators. It's better for users and content providers. And that's why Apple is 100 percent backing the move to IPv6. And you will have all seen this announcement last month. We announced last year we were going to be requiring all apps to be compatible with IPv6 networks, and we said we would be testing all apps on our own IPv6 network with the NAT64 Gateway.
Starting this month we started enforcing that requirement, and we looked very closely for any evidence that this was causing an increase in the rate of application rejection, because if that were the case, we would have to look into it and work out what to do. But the good news is, look as hard as we can, we don't find any change in application rejection, so what that really tell us is that 99 percent of you have apps that are working just fine with IPv6 support, which is what we expected, but it's still really good to have that confirmed.
Now, if you've had an app rejected and you think it might be to do with IPv6, then come on down to the labs today or tomorrow. You can test your app here at WWDC on the NAT64 network, and we can help you troubleshoot what might be going wrong. Our advice continues to be, as it always has been, use the high level APIs that are address-family agnostic.
If you have to use the low level BSD APIs, then there is extra work that you are going to have to do, which is why we really advise using the high level APIs that do that for you. Another key piece of advice is use hostnames, not literal IPv4 addresses. Because IPv4 addresses are inherently tied to IPv4. And let me give you a little picture showing why.
This is a typical situation from a few years ago. You have a client on IPv4. You have a server on IPv4. The packets make their little detour via the NAT Gateway, and that's how you connect to the server. Nowadays, many more carriers are rolling out IPv6 networks with a NAT64 Gateway, and the packets still make their little detour through the NAT Gateway and connect to that old legacy IPv4 service on the Internet.
Now, if your data center guys bring up dual-stack services but you're still using v4 literals in your apps, then the packets are going to make that same detour through the NAT to get to the v4 interface at the service. But if you look up by hostname and they put the IPv6 quota records into the DNS, that's how you get the straight through data path without going through the NAT Gateway.
I talked about literal addresses. We now support using IPv4 literal addresses in selected APIs. And if you use one of those addresses, we will actually do the DNS64 synthesis for you locally on the device, create a temporary IPv6 address corresponding with your v4 service on the Internet, and then connect through the NAT64 Gateway. Now, remember, using literal v4 addresses will prevent your app from ever connecting to an ATV6 server. But that said, if that's what you need to do for your app, here is an example of how you do it.
If you're writing code using Swift and the high layer Cocoa APIs, this happens for you automatically. But if you're writing UDP code today and you're using BSD sockets, the API you need to use is getaddrinfo. You pass in the address you want to connect to as a literal string. You pass in the port you want. Here https is a synonym for port 443. You loop through all the addresses you get. Remember, don't just take the first one. You'll get back an array of multiple addresses to try, and, of course, free the memory when you're finished.
Another question we get from developers is about the Internet of things. There are developers writing apps that interact with the device that they don't make, and some of those devices are not very modern. Now, we'd like those devices to support IPv6. And if they don't support IPv6, we recommend that they at least support IPv4 link-local addressing. So even on a v6 only network, devices can use v4 amongst themselves to communicate with link-local addressing.
Now, if the device can't do either of those things, that's okay. Inform app review, when you submit your app, that is not grounds for rejection of your app. It probably is grounds for putting one of these stickers on the device. [Laughter] And remember, all off link communication still have to be compatible with IPv6 and NAT64.
So to summarize, we recommend you support both IPv4 and IPv6 at both ends, in the clients and the servers. We recommend you use hostnames. That way you can get a v4 address on a v4 network and a v6 address on a v6 network. If you do need to use literal addresses, those are now supported in select APIs, as long as you do it properly. But remember, imbedding v4 literals will block communication to v6 servers in the future. So that brings us to our next session, international text.
You may have started to see things like this, and if you're a native English speaker, this can look pretty daunting and scary. And what I want to talk about today is how simple this really is. International support in your application doesn't need to be a big task. In fact, it really is no harder than supporting ASCII. So even though the title of this session is International Text and Networking, really we can scratch the networking. For now I just want to talk about how you support international text in general.
I'm going to start with some background. Not because many of you will need to encounter this day to day, but I want to de-mystify some of this and make it less scary, because it really isn't any more complicated than ASCII. So the first concept we have is Unicode.
Unicode is a big list of numbers, and corresponding to each number a human visible character, and it's like a big phone directory. In fact, it is available in book form. It's a big, thick book with page after page of number and character. And that's an abstract concept. You have integers and you have the characters they represent.
Now, to use those integers in our computers, we need some way of representing those numbers, in memory, on disk, over the network. One way of representing them is UTF-32, which is just a 32-bit number. And like any 32-bit number, you have to be concerned whether it's big endian or little endian. And it takes up four times as much space as ASCII.
UTF-16 is more compact. It uses 16-bit numbers. It still has the same problem of little endian versus big endian, and because it's only 16-bits, it can only represent 65,000 values. So you have to use the surrogate pairs to represent the values outside that range. So that's a bit cumbersome. UTF-8 is an 8-bit byte-oriented encoding. Because of that, there are no byte order issues, and this is really what makes it the ideal encoding to use. So let's dive in a bit deeper into UTF-8.
It was invented late night in New Jersey 1992, and it's one of those rare pieces of computer science genius. And when I first heard about that, I immediately saw, this is the answer. This solves the problem for international text. So I want to tell you guys a little bit about how it works so you can understand how simple it is.
The Codepoints in Unicode from 0 to 7F are exactly the same as the ASCII values. And UTF represents them using the exact same bytes in memory. So what that means is if you've got a disk full of plain ASCII files, I can wave my magic wand over it and say, I declare you to be UTF-8. Not a single byte on disk changes. The meaning of the files doesn't change. You have automatic backwards compatibility with all that legacy of ASCII, so that is a wonderful thing. UTF-16, UTF-32, other encodings don't have that property.
For the values that are outside the ASCII range, they are represented as multi-byte sequences. But all those multi-byte sequences only use byte values above 128. So there was no overlap between the ASCII characters and the multi-byte encodings of the higher value Unicode Codepoints. That property is not true of other encodings that re-use the high code bytes to mean something else.
UTF-8 has three flavors of bytes. It has the plain ASCII bytes. If a byte starts with the most significant bit being 0, that tells you it's plain ASCII. If the top two, three, or four bits are 1s, that tells you it's a two, three, or four byte sequence.
And if the top bits are 1 0, that tells you it's a continuation of a multi-byte sequence. So I'll show that in context. The ASCII characters stand alone. The bytes with two leading 1s signify two byte sequence. Three leading 1s is a three byte sequence. Four leading 1s is a four byte sequence.
And this gives it a wonderful property that you can jump into the middle of a UTF-8 file anywhere, and by just looking at any old byte, you can tell what you've got. Does this stand alone as ASCII? Is this the start of a multi-byte sequence? Did I land in the middle of a multi-byte sequence and I have to skip forward or back to find the character boundary? So it's very, very robust to insertion and deletion errors.
It's an encoding that is efficient enough to be compact but has just enough redundancy to be very reliable. Another useful property it has is in an UTF encoding of a string, there are no 0 bytes. And C treats 0 as the string terminator, so that's a very useful property. UTF-16 strings have zeros all over the place.
And another nice property is if you do a naive simple byte-wise string sort on UTF strings, they sort in the same order as if you sorted the Unicode Codepoints directly. So a whole bunch of really wonderful properties, and this is why just six years after Ken Thompson invented it, the IETF issued a document saying that from then on, all new Internet standard protocols had to work with UTF-8. And that philosophy has been embraced on the web. Four years ago, Google did a survey and found that 80 percent of web pages were UTF-8, and that includes a small percentage that were old fashioned, plain ASCII, which is of course a compatible subset of UTF-8.
Last month that number is now up to 87 percent. And because of that, the W3C, just like the IETF, also recommends that we only use UTF-8 for everything. And this is wonderful. There is, however, one catch. For some reason, lost in history, the DNS community decided not to do that, and they invented a different encoding that they call Punycode. And Punycode re-uses existing ASCII byte values to mean different things. So those are the byte values that correspond to letters, digits, and hyphens.
A result of this is that if we have a block of bytes, I can interpret those bytes as ASCII values and get something like that, or I can interpret them as being Punycode encoding and get what they're meant to be. And that dual interpretation of the same bytes can be very problematic, because it becomes unclear what you want to display to the user or what the user meant.
If we contrast that with UTF-8, the first thing you notice is the encoding is more compact. It takes fewer bytes, and there's also only one valid interpretation. So there was no ambiguity there. The good news for you guys is you don't need to care about this, because we handle it for you.
In iOS 9 and OS X El Capitan, if you tried to ping a UTF-8 hostname on the command line, it would fail. You type in UTF-8, those characters pass through the tool to the APIs on to the network, but that name was not put into the DNS as UTF-8 and it fails.
Starting now in iOS 10 and macOS Sierra, the same ping command on the command line with the same UTF-8 input, we will now translate that automatically to Punycode, do the query, and it will be successful. Now, here the ping command is taking that Punycode and displaying it as if it were ASCII so you get this gibberish on the screen instead of the actual name that you meant, and that's part of the problem of having dual interpretations of the same string. But the good news is all the Bonjour and DSA APIs will now accept international text input in UTF-8 format, because --
[ Applause ]
Thank you. Because the Punycode format is quite restrictive, it doesn't support even simple things like spaces in names, and we use DNS for Bonjour search discovery, we don't want to be that restrictive. So the way the algorithm works, which is what's documented in RFC 6763, we will first try UTF-8 as is, and if the DNS administrator put UTF-8 into their zone file, which is very easy to do, and people were doing that back in the '90s, we do the query, we are successful, we get the result, everything is fine. What's new now is that if we fail, instead of giving up, we will do one more try with Punycode and see if that works. So we support both in the same API.
Email addresses are also becoming internationalized today. And this is also not hard to do, but users face problems for a silly, trivial reason. Many apps, when you sign up for an account or you go onto the website to sign up for an account, they try to validate if the email address is valid and they check whether it ends in .com or things of that form.
And users with perfectly valid email addresses are not allowed to sign up for accounts because their email address is rejected. So we need to remove those ill-advised validators. Really the only thing you can check for in an email address is it has to have an @ sign. And if it's got that, it could be a valid email address. If you want to know if it's valid, send a validation email and have the user respond to confirm that it's live.
If you're writing an email client or an email server, there are a bunch of RFCs you are going to need to look at. But for the rest of you, you don't need to worry about that. Let the user enter their email address as UTF-8, stick it in your customer database, and have the mail server send that out correctly encoding with the email standards.
So to wrap up this section, we recommend UTF-8 for everything. Makes everything so much simpler. Don't worry about Punycode. We handle it for you. And be liberal about accepting user input in this new international multi-lingual world. That brings us to interface selection. Now, Wi-Fi Assist is something that we introduced last year.
Really, this is not new. This is the way things have worked since the very first iPhone. If I have Wi-Fi, I want my phone to use it. If I don't have Wi-Fi, that's why I pay for cellular data, so I have network access outside the home as well. And the first iPhone did this. What we changed last year is we did it better. We were smarter about making that determination, because there's always this gray area right on the edge of a Wi-Fi network.
And mobility factors into this as well. We have a situation that we call the parking lot problem, and it happens at the end of the day when you leave work. You leave the office, you get your phone out, you have Wi-Fi, you're walking out to the car and you want to check maps or weather forecasts or look for movies or something and your phone thought it had Wi-Fi. It had Wi-Fi a moment ago, but you just walked out of range and it hasn't realized yet. With Wi-Fi Assist, we will detect that. We'll try to use Wi-Fi. If it doesn't work, we'll use cellular instead.
But like any new feature, there's sometimes a tendency for the new thing to be the whipping boy that gets blamed for people's problems. Everybody hates it when some app uses a ton of data and they get a big bill they weren't expecting, and it's human nature to blame the new feature. But if you actually look at your Wi-Fi Assist data, you will probably find they are very small.
Wi-Fi Assist is normally not the problem here. Now, apps have the switch. If you don't want that app using lots of data, you can turn it off. But that's very crude. That's kind of an all or nothing switch. And a lot of apps want to do something a bit more subtle. Say you have a video streaming app.
You may want the user to be able to browse the catalog, see little thumbnail pictures, read the descriptions over mobile data. Doesn't cost very much. But you may want the setting in your app that says don't stream videos over mobile because users may not want to spend that much money on mobile data. And if you have that, you're going to want to be able to differentiate between getting the thumbnail, which is allowed over cellular, and streaming the video, which is not.
A lot of developers have done things like this. They use the reachability API to say, am I on cell? Yes or no? If I'm not on cell, go ahead and do that download. Well, things don't stay the same in networking. Things change from second to second. And between you checking whether you're on cell and actually doing the connection, the user may be walking across the parking lot. So this is not the right way to do it. The right way to do it is to express your intent to the networking layers, and we will honor what you tell us.
The first step here is don't bother with preflight checks. If you want to do a network transaction, just try it. If that's a transaction that you don't want to use cellular data, then you can express that to the networking layers. Using the CoreMedia APIs, you set the allow cellular access key using NSURLSession. If you set allows cellular access to false, then we won't use cellular data connection. Nice and simple.
[ Applause ]
If that connection fails, you can ask the user, do you want to stream this video over mobile data, or you can just wait, subscribe for better route notifications, and when the phone comes back on Wi-Fi, you'll be told about it and then you can retry your connection once Wi-Fi is available again.
So to summarize, don't assume that because you're on Wi-Fi now, you will still be on Wi-Fi one second from now, or even half a second from now. Conditions change. Express what you want to the networking layers and we will respect that. Our last topic is networking quality of service.
Last summer, we announced a partnership between Cisco and Apple, and I'm going to tell you a little bit about one of the new APIs that you can use to express your needs to the networking layers. There are different kinds of networking traffic. 99 percent of what we do is good, standard Internet best effort traffic. We want the best throughput we can get, and ideally we'd like low delay. But we definitely want as much throughput as we can get. This supplies browsing the web, sending an email.
Another thing that we do is online backup, uploading photos to iCloud. And that also wants to have good throughput, but not as good as the priority stuff. We'd like to be able to upload all of our photos to iCloud in the background without disrupting our Netflix TV binge.
The photo upload should take place when we're sleeping. It is what we call scavenger-class traffic. It uses the otherwise idle capacity of the network that would otherwise have been wasted, but it is second class to sending emails, browsing the web, anything that the human is actively involved with.
The third class of traffic is telephony, interactive voice and video. And I say interactive, because that's the key thing. When we're having a conversation, I speak, you hear me, you respond, you speak back, I hear you. If that round-trip is more than a couple hundred milliseconds, human communication breaks down.
When people talk about voice and video, it's important to realize that watching a YouTube video may be video, but it's not interactive. It doesn't need that sub 200 millisecond round-trip time. Listening to a podcast may be voice; that doesn't mean a podcast is voice traffic. It's not interactive.
So that's why I labeled this part of the chart telephony, because this is interactive voice and video. For that traffic you want the lowest round-trip time possible, and it's very small throughput. It's a few kilobits per second. You don't need 50 megabits of voice. So marking your traffic as telephony tells the network keep the latency low, but you also don't have a big queue.
If you try to do any kind of bulk transfer as voice class, you're going to lose most of your packets, because a very small amount of the network capacity is allocated for that traffic. So one of our FAQ questions people ask us, will Fastlane make my app faster? And the answer is no, it doesn't make it faster. It will lower the latency for voice traffic.
You may be wondering, how does this relate to the Smart Queue Management and Explicit Congestion Notification that we were talking about earlier? And the answer is those technologies improve the delay for all traffic across the board, but telephony will probably still be an extreme case that wants the very, very lowest latency and doesn't mind sacrificing throughput to get that.
Starting in iOS 5 we had the network service type API, and that lets you express some of these needs to the network. But many of the developers writing apps like Skype and Facetime that are doing this kind of voice telephony are using UDP. And to use UDP today on iOS, you need to be using BSD sockets. So we now have a socket option that exposes the same functionality so your UDP clients can benefit from this.
We know some developers had been previously setting the IP type of service bits in an attempt to get the same effect. The problem is those type of service bits are not well defined. They are not specified anywhere. Some Wi-Fi chip vendors will look at the type of service bits and use that as a hint to set the Wi-Fi traffic class to voice, video, background.
But the problem is with no standard definition of the bits, that interpretation is not consistent. So you may test it in your office and think it works fine, but for a customer, it does something different. And that's why we have the new socket option that gives you reliable, consistent behavior across all devices.
If you're writing Swift code, you can set the network service type property to voice, video, or background. Or if you don't set it at all, then that is traditional best effort. If you are using the socket option, we have the same options. We have about another seven more than this, which is more than most of you will need. These are the four interesting ones.
When you set these options, a couple of things happen. On the device itself, there are multiple outband queues, and the type of service you set for your traffic controls which queue it uses. On Wi-Fi interfaces, it will also set the wireless multi-media access category. This is supported on all devices, iOS and OS X, and the outband queue selection also applies for Ethernet as well as Wi-Fi.
Now, if your device is on one of these new Cisco Fastlane networks, we will recognize that and we will also set the IP layer differentiating services Code Point so that you get that handling that you want, not just on the first hop leaving the device but in subsequent hops through the enterprise network.
I want to stress this is not something that you all need to feel obliged to go away and change your code. If you're writing an online backup app, definitely set background traffic class. If you're writing the next Skype, then set the voice class. But for the rest of you, standard best effort is almost certainly what you want.
Some other things you ought to remember: The outband queue selection and Wi-Fi layer, quality of service marking is supported on all devices, but remember it only applies to outband packets. The packets coming in have to be marked by the thing at the other end sending them. And the IP layer marking is also only for outbound packets. It's today only supported on Cisco networks with compatible hardware.
It's only on iOS. It's not supported on Macs or Apple TV or anything else. And for now it's only supported on Wi-Fi. I know most people don't use Ethernet with your iPads, but if you do plug in an Ethernet adaptor, the quality of service is not supported on Ethernet.
And finally if the administrator chooses to install a management profile on the device, then that management profile can restrict which apps are allowed to use this type of service option, and only apps that are listed in the profile will be able to set type of service. It will be a no op for all other apps.
So to summarize this section, most of your traffic should continue to be best effort. If you are doing large, bulk transfers that are not time critical, background traffic is a way for you to be less disruptive and be a better citizen on the network. Remember, it's not a priority level. There isn't a ranked ordering here of high priority to low priority. It's a web expressing whether you want low throughput and low latency or high throughput and moderate latency.
So that ends our session. Thank you for coming. We've talked about Smart Queue Management, and this is a call to action to all the ISPs and carriers and network vendors. The clients are supporting ECN. The servers are supporting ECN. If you start marking the packets in your network instead of dropping them, you will make your users much happier. The message for developers in the room is IPv6 is now the majority of traffic for many carriers on many networks. Support IPv6 in your applications. Support IPv6 and IPv4 in your servers.
For your text, UTF-8 is the new ASCII. It's no harder than ASCII. It's really very simple to use it. All of our devices now have good support for all the Unicode characters in the fonts, so you should have no worries about supporting UTF-8 without hesitation. And finally, we have new ways for you to express intent to the networking layers. You can control when you don't want to use cellular data, and you now also have finer control of the throughput latency characteristics of your data.
So with that, there's a link where you can find more information. We have other sessions that you can watch on video that you may find interesting. We have sessions about networking and security, which is important. We have a couple of other sessions about internationalization. We have some sessions about higher layer networking applications, like HomeKit. So with that, thank you for coming to WWDC.
[ Applause ]