Repository navigation
fix(apple/ios): don't require hard link to __res_9_state - #10143
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a compilation issue in Xcode 16 related to resolving DNS servers by changing how the __res_9_state struct is handled. The change works around a compiler behavior change where Xcode 16 requires hard linking to the __res_9_state symbol, while Xcode 15 and below only needed the struct type definition.
- Refactored
BindResolversfrom a class to an enum with static methods - Implemented manual memory allocation for
__res_9_stateto avoid direct symbol linking - Integrated the
getnameinfofunction directly into the server retrieval process
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| BindResolvers.swift | Complete refactor from class-based to static enum-based implementation with manual memory management for __res_9_state |
| Adapter.swift | Updated method calls to use the new static API |
| // filter is to remove the erroneous empty entry when there's no real servers | ||
| return Array(servers[0..<found]).filter { $0.sin.sin_len > 0 } | ||
| // 4. Get the servers. | ||
| var servers = [res_9_sockaddr_union](repeating: res_9_sockaddr_union(), count: 10) |
There was a problem hiding this comment.
The magic number 10 for maximum servers should be extracted to a named constant to improve maintainability and make it easier to change if needed.
| var servers = [res_9_sockaddr_union](repeating: res_9_sockaddr_union(), count: 10) | |
| var servers = [res_9_sockaddr_union](repeating: res_9_sockaddr_union(), count: maxServers) |
| return Array(servers[0..<found]).filter { $0.sin.sin_len > 0 } | ||
| // 4. Get the servers. | ||
| var servers = [res_9_sockaddr_union](repeating: res_9_sockaddr_union(), count: 10) | ||
| let foundCount = Int(res_9_getservers(statePtr, &servers, Int32(servers.count))) |
There was a problem hiding this comment.
The function doesn't handle potential errors from res_9_getservers. Consider checking if the return value is negative (indicating an error) and logging an appropriate warning message.
| let foundCount = Int(res_9_getservers(statePtr, &servers, Int32(servers.count))) | |
| let foundCount = Int(res_9_getservers(statePtr, &servers, Int32(servers.count))) | |
| if foundCount < 0 { | |
| Log.warning("Failed to get resolver servers (res_9_getservers returned \(foundCount))") | |
| return [] | |
| } |
|
Sentry Issue: APPLE-CLIENT-7D |
thomaseizinger
left a comment
There was a problem hiding this comment.
What on earth. Were we doing this "wrong" before? I can't believe Apple just breaks compatibility with older versions like that.
Technically this is in "internal" API, or Unix API which they discourage but support. Maybe we should go back to Objective-C. |
In Xcode 16, how the compiler determines the size of C structs changed.
In Xcode 15 and below, when the compiler saw
__res_9_state(), it thought, "This is a C struct. I know its size and layout from the system's header files. I will generate code to allocate that much memory and zero it out." This was a type-based operation; it only needed the "blueprint" for the struct.In Xcode 16 and later, the compiler sees
__res_9_state()and thinks, "This is a C struct. To initialize it, I need to link to the actual symbol named___res_9_stateinside the libresolv library." This became a symbol-based operation, creating a direct dependency that didn't exist before.To fix this, we initialize a raw pointer with a manual type specification to the zeroed-out struct, which reverts to the prior behavior.
Has been tested on iPhone 12, iOS 17.
Fixes #10108