Bonjour over AWDL? Please no.
There are many internet forums with thousands of users scratching their heads, wondering if the reason their WiFi performance is severely degraded on iOS 8 is because of their router, their DNS settings (please help these folks the most), that they need to reset their network settings, and more.
I’ve narrowed down the issue to the use of Apple’s Wireless Direct Link (AWDL) that is used for AirDrop, AirPlay, and Gaming connections.
I’ll go out on a limb and say the WiFi issues are because of Apple’s choice of using Bonjour over AWDL and that, given the constraints of the WiFi hardware, this will be difficult to get right. But perhaps I’m crazy, and this is just a bug that can be fixed by Apple.
Apple: Keep Bonjour over Bluetooth and connected WiFi networks. Are there really justifiable gains by advertising and browsing for services over WiFi vs Bluetooth? And If I missed something, it needs to work without interference.
I’ve confirmed this severe WiFi degradation issue still occurs on iOS 8.1.1 and OSX 10.10.1. This is not fixed.
What is AWDL?
AWDL (Apple Wireless Direct Link) is a low latency/high speed WiFi peer-to peer-connection Apple uses for everywhere you’d expect: AirDrop, GameKit (which also uses Bluetooth), AirPlay, and perhaps elsewhere. It works using its own dedicated network interface, typically “awdl0".
While some services, like Instant HotSpot, Bluetooth Tethering (of course), and GameKit advertise their services over Bluetooth SDP, Apple decided to advertise AirDrop over WiFi and inadvertently destroyed WiFi performance for millions of Yosemite and iOS 8 users.
How does AWDL work?
Since the iPhone 4, the iOS kernels have had multiple WiFi interfaces to 1 WiFi Broadcom hardware chip.
en0 — primary WiFi interface ap1 — access point interface used for WiFi tethering awdl0 — Apple Wireless Direct Link interface (since iOS 7?)
By having multiple interfaces, Apple is able to have your standard WiFi connection on en0, while still broadcasting, browsing, and resolving peer to peer connections on awdl0 (just not well).
2 Channels at the same time!
At any one time, the wifi chip can only communicate at one frequency. Thus, both interfaces would need to be on the same channel when attempting to use both interfaces at the same time. This typically works well when 2 devices are near each other, as they are more than likely connected to the same access point using the same channel.
I did do some tests having 2 devices connected to different channels (one 5ghz and one 2.4ghz) and they were still able to AirDrop successfully (impressive), albeit with obvious transfer chunking and at about 1/2 the normal transfer rate when both devices are on the same channel.
P2P device services happen in discoveryd
discoveryd, previously named mDNSResponder, loads the D2D plugins located in /System/Library/PrivateFrameworks/DeviceToDeviceManager.framework/PlugIns/. The specific one causing issue is the WiFiD2DPlugin.bundle.
Currently there are 2 plugins, one for WiFi and one for Bluetooth. As I mentioned above, some services, such as Instant Hotspot, broadcast over the Bluetooth interface while others such as AirDrop, AirPlay, and GameKit may broadcast on multiple interfaces including the Bluetooth, AWDL, and of course, standard en0 WiFi interfaces.
Reproducing the WiFi Performance issues
WiFi Jittery/Slow Transfer Speeds
The performance degradation is the bigger of the two symptoms. Once I understood what to look for, it was simple to address/fix, but it was a long journey to get here.
When the device is advertising and browsing for services, there is interference with the WiFi transmission, or perhaps some kind of TDMA of the WiFi chip to support multiple interfaces. The performance effects are very apparent and easy to reproduce.
iOS 8 WiFi Performance Issue — Comparison Video
To reproduce this issue on any iPhone
Perform a speed test (many apps to choose from) and simply pull open the Control Center. This will cause the discoveryd process to browse and advertise services over your WiFi interface. You’ll see an immediate reduction in WiFi speeds that will continue for a minute or two while the AWDL interface continues to browse/advertise. This occurs when Bluetooth is turned on as well as turned off, so it doesn’t appear to be a Bluetooth coexistence issue (where Bluetooth and WiFi overlap frequencies and in this case also use the same chip).
Even more interesting is that you can cause an issue with a nearby device. Instead of opening Control Center on the speed testing device, I’ve successfully induced the WiFi issues by simply waking a nearby iOS device. The waking process itself begins a browse and advertise of services that affects other nearby devices.
8.1.1 (Added 12/2/2014): To reproduce on 8.1.1, turn AirDrop On and begin a speed test. On a secondary device, open the Photos App, choose a photo, and press the action icon at the bottom left. You’ll see the WiFi severely degrade.
Slow Ping (”SSH bug”)
On an iPhone 5S, consistently, you’ll see ping times go up to 2 seconds on every other ping. (Yes, who cares about pings very much, but it affects performance too). For those in the JB community, I believe this is what folks have been referring to as the “SSH bug”. The issue is causing a 1–2 second delay on “every” key. Interestingly, when you send data often, the ping latency goes away. i.e if you type pretty quickly for a long period, the connection will be fast. If you press a key once a second, you’ll notice a 2 second delay after each key.
This issue occurs when the kernel disables AWDL, which seems very odd. The system log shows: kernel: 000606.348321 wlan0.W IO80211AWDLPeerManager::doMonitorTimer(): Disabling AWDL due to no services and idle link.
To reproduce this issue on iPhone5S
On your iPhone 5S, the easiest way to reproduce the ping/SSH issue is to set AirDrop to “Off” in Control Center and pull open and close the Control Center. Wait about 20–60 seconds with the phone screen off or on. It’s best performing this activity with no other iOS devices nearby or at least their Bluetooth off. It seems that AWDL will remain around longer when “devices present”, per the kernel log statements in the system log. It’s these specific environmental factors that made this narrowing down the root cause so difficult and I’m sure has caused issued with Apple trying to locate the issue as well.
Once the problem begins, it will go away each time services are advertised, browsed, or resolved. In layman’s terms, just open up Control Center again and the ping time will go back to normal (until it’s closed and then another ~20 seconds until the kernel disables AWDL).
AirDrop Everyone vs Contacts Only vs Off
There are some specific nuances surrounding whether AirDrop is set to advertise to no one, contacts only, and everyone. However, despite which you choose, the issue still remains, just in different sequences/time periods/etc.
Bouncing WiFi/Re-associating WiFi
Part of the confusion on what the “fix” was is due to the fact that when the iOS device reconnects to an AP (either turn off/on WiFi on the phone or Forget/reconnect), some of the AWDL characteristics are reset/disabled for a period of time.
Thus, the WiFi performance restores to 100% upon a WiFi bounce until discoveryd begins its browse/advertise routines, causing performance degradation and the ping lag issue on the 5S when the kernel disables AWDL again.
Until I figured this out, this made it quite difficult when troubleshooting!
A fix for iOS WiFi
How often do you actually use AirDrop or play games with a nearby device or do AirPlay directly to another device (where you’re not connected to the same WiFi)? I’ve used AirDrop once. It was cool, I enjoyed it, but not worth the WiFi issues it’s causing.
I’ve created a disable feature and conveniently located it in the AirDrop menu located in the Control Center. If you’re jailbroken, you can pick this up in Cydia for free. It’s called “WiFried”.
WiFried will allow you to enable/disable your D2DWiFi/AWDL and can be conveniently turned off/on under the AirDrop settings in Control Center.
I’ll post the source on GitHub shortly Edit: https://github.com/mariociabarra/wifried
One Last Thing…
Yosemite WiFi Issues Fix
This issue with D2D/AWDL is the same root cause of the severe WiFi performance degradation affecting users on Yosemite (continues on 10.10.1). Although AirDrop was introduced in OSX Lion and used AWDL, with the release of iOS 8, perhaps there’s more sharing or just some bad new code. AirDrop and AWDL have been active since iOS 7, yet the issue seems to have suddenly appeared in iOS 8.
@rpetrich mentioned AirDrop used to be two incompatible, but identically named protocols until Yosemite/iOS 8. Perhaps this and the changes for continuity introduced bugs in this area.
Turning off AWDL
Perhaps not surprising for Apple users, you actually can’t easily (see below) turn off AWDL/AirDrop in Yosemite. You can remove it from the left side of Finder, but that doesn’t fix the issue. Apple? User choice?
Either way, you can fix your Yosemite WiFi issues, at the cost of disabling AWDL and AirDrop, by typing the following command at the OSX terminal:
sudo ifconfig awdl0 down
And vice versa to restore AirDrop and AWDL (and the WiFi issues)
sudo ifconfig awdl0 up
For clarification: that’s “a w d (lowercase L) (number zero)”
Update: Older Mac’s/MacBooks may not have this interface on Yosemite due to hardware incompatibilities. Based on http://recode.net/2014/10/16/os-x-yosemite-arrives-what-does-it-mean-for-older-macs/, looks like they don’t have full AirDrop and probably don’t support AWDL.
More Hackers Wanted:
I reversed most of the iOS related frameworks, and through trial and error, have determined this is mostly a kernel/driver issue. There’s not much in the iOS userland code except initiation of the advertising, browsing, and resolving. I just glanced at the Yosemite version and there’s more details in there on how this works. If you are so inclined, fire up IDA and take a look at the following framework. Perhaps you’ll be able to figure out more details.