High Sierra WiFi connection breaks socket connection to localhost

I have a daemon and agent running at startup. The daemon broadcasts a Bonjour service, the client agent attaches to a localhost socket, all is good.


Or at least it was until recently. Under High Sierra, all this happens before the WiFi network connection is complete, and when that finishes, it breaks the socket connection between the daemon and its client(s). I have coded a workaround to restart the Bonjour browser, which then re-finds the daemon, reconnects, etc. This in turn causes a bit of UI turmoil, which does settle down after the workaround, and is also just a transient on bootup. I point at WiFi startup because the timing is coincident and I do not see the behavior if I boot up with WiFi turned off. If I then turn it on, same problem -- the socket connection is blown away, and my workaround fixes it. The "UI turmoil" is a bit difficult to suppress since the client agent has no good way to distinguish this from a legitimate daemon-gone-away event such as can happen when connecting to a daemon on a different _tcp._local. server.


I would like to know if it is possible to keep the WiFi processing from resetting the network stack.


I consider it a bug that an innocent socket connection to localhost would get blown away by whatever is happening on the rest of the network.


MacBook Pro, macOS High Sierra (10.13), MacBook Pro (13-inch, Early 2011)

Why is the agent browsing for the daemon via Bonjour? Given that there can only be one instance of the daemon, why not just hardwire

localhost
?

The reason this is relevant is because, if the client goes through Bonjour, it will connect to an interface-specific IP address. Such connections are subject to interruption as the interface gets reconfigured. It’s better to stay out of this business entirely by connecting

localhost
(which always runs over the loopback interface, which is always up).

Alternatively you could connect over a UNIX domain socket. That avoids networking entirely, which seems like the right option if you’re domain daemon/agent IPC.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

bonjour because the daemon is not always on localhost. This is a setup that unlocks TCG-compatible self-encrypting drive, and includes a simple desktop popup window on the e.g. MacBook with the SED(s), a Self-Encrypting Drives preference pane that runs in System Preferences, iOS apps that can unlock SEDs by WiFi or Bluetooth, and a developer's desktop app that can see all daemons on all machines on the _tcp._local network and send and receive low level daemon commands (think FTP connected by telnet) -- even Android or Windows devices that can do bonjour browsing. But the simplest case, of the popup and preference pane on the same system as the SEDs, naturally just connects via localhost. AFAIK WiFi connect/disconnect did not previously break a localhost socket connection, and now it does.


Would your suggestion be noticing in the code when the bonjour browser finds a daemon on the same machine and making the connection directly via localhost (i.e 127.0.01)? Would that make the connection impervious to WiFi connect/disconnect causing a network stack reset?

Would your suggestion be noticing in the code when the bonjour browser finds a daemon on the same machine and making the connection directly via localhost (i.e 127.0.01)?

Yes, I think that’s worth experimenting with.

The one gotcha here is that it’s harder than you think to identify a local service. One option would be to put a UUID in the server

TXT
record and then have a separate channel to get the local UUID from the daemon (it could just stash that ID it in a file in
/var/run/
).

Would that make the connection impervious to WiFi connect/disconnect causing a network stack reset?

To be clear, the network stack has not been reset. I’m not actually sure what’s causing your connections to fail but it’s likely that the Wi-Fi interface has gone down and come back up, which may or may not tear any network connections running over that interface depending on a bunch of factors. The ones that spring to mind are:

  • The API you’re using to run the connections

  • Whether the interface comes back up with the same IP address, and that itself is a complex issue in the IPv6 case

There are techniques you could use to investigate what’s actually happening but, given your unique requirements, I suspect it’s a better use of your time to get on to the loopback interface.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
High Sierra WiFi connection breaks socket connection to localhost
 
 
Q