I maintain an app that works with specific IoT devices. One of the functionalities I need is sending and receiving UDP broadcasts from the devices in the local network. In fact, such a procedure worked perfectly for almost 2 years, but with iOS 12 things got complicated.
- In the debug mode broadcasts work as they did before - they are can be both send and received.
- There is a problem with receiving broadcasts in the release compilations of the app. It doesn't show up even if I uncheck "the debug executable" option and install the app on the testing phone via a cable, but the only way to replicate such a behavior that I found is uploading the app to the App Store Connect and installing it using TestFlight.
Because of that, it's really hard to debug. I define a listening address like that (the port I use is 15001):
listening_address = sockaddr_in(
sin_len: __uint8_t(MemoryLayout<sockaddr_in>.size),
sin_family: sa_family_t(AF_INET),
sin_port: inboundPort.bigEndian,
sin_addr: INADDR_ANY,
sin_zero: ( 0, 0, 0, 0, 0, 0, 0, 0 )
)
Then I create a socket with SO_BROADCAST enabled:
let newSocket: Int32 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
var broadcastEnable = Int32(1);
let ret = setsockopt(newSocket, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, socklen_t(MemoryLayout.size));
And I try to bind it:
let bind_ret = bind(newSocket, sockaddr_cast(&listening_address), socklen_t(__uint8_t(MemoryLayout<sockaddr_in>.size)))
In the debug mode, binding succeeds and receiving broadcasts works well. So it did in the release compilations not long ago (at least prior to iOS 12), but now the bind function returns an error: Operation not permitted (EPERM). Enabling SO_REUSEPORT silences the error, but the packets are still not received. On the contrary, sending UDP packets to the broadcast address works as before both in debug and release apps and the response also reaches the phone (what I've checked with rvictl).
---
Today I tried to rewrite the same procedure using the Network framework. An NWListener on the port 15001 somehow reacts to the incoming messages, but instead of invoking newConnectionHandler, it displays nw_listener_inbox_accept_udp bind failed [49: Can't assign requested address] on the debug console for each received broadcast message.