It's a little weird to me that getaddrinfo() is considered a "low-level legacy API". Maybe things are drastically different on macOS, but getaddrinfo() is the way to resolve names on Linux and I suspect the *BSDs.
Sure, I expect most macOS apps will use something in Foundation or some other NetworkKit-type framework to do DNS queries, but it's odd to me that the code there wouldn't then call down to getaddrinfo() or the like to do the dirty work. I guess GAI is blocking, so presumably there's some other low-level non-blocking call?
>so presumably there's some other low-level non-blocking call
Correct, CFNetwork is open source so you can check implementation but last I remember it used some variant like `getaddrinfo_async`. But Apple really doesn't want you (the end-user) to use getaddrinfo (or the async variant CF exposes) to resolve an IP and then directly connect() via that ip, everything is geared towards connect-by-hostname since then Apple's can internally handle the implementation of happy-eyeballs.
Applications should not use getaddrinfo(). Because for the connect by name, the OS or app SDK can parallelize the entire multi-step lookup and connection process, not just step by step:
“Now, I’m not saying that all implementations of these APIs [Java, Apple Foundation, etc., doing connect by name] necessarily do the right thing today, but if applications are using these APIs, then the implementations can be improved over time.”
“The difference with getaddrinfo() and similar APIs is that they fundamentally can’t be improved over time. The API definition is that they return you a full list of addresses, so they have to wait until they have that full list to give you. There’s no way getaddrinfo can return you a partial list and then later give you some more.”
The deck's position on implementation of happy-eyeballs (which could sound dismissive here but is treated as "you had one job" important by the deck), is finding a way to avoid waiting 5 seconds for either side of IPv4 vs. IPv5 stack to timeout before finishing connection setup and serving the user a web page.
> getaddrinfo() is the way to resolve names on Linux
Not at all. That's just a glibc function, it's got nothing to do with Linux. People just assume that glibc is how things are done in Linux user space but it doesn't have to be that way. For example, systemd came up with its own resolved mechanism which turned out to be much better than the glibc stuff. I will probably end up inventing my own at some point as well since I'm working on freestanding software targeting Linux.
getaddrinfo is defined by POSIX and UNIX. Where the implementation is doesn’t matter. It’s portable, which is why it’s used. The slide deck referenced above talks about better implementations for various platforms, but they are all platform specific.
So OP might not be completely accurate, but getaddrinfo is _the_ way to resolve names if you are writing portable POSIX and/or UNIX code.
> getaddrinfo() is the way to resolve names on Linux and I suspect the *BSDs.
At least on OpenBSD, all classical/standard DNS functions (getaddrinfo/gethostbyname/...) are wrappers around OpenBSD's libc asr implementation, written by Eric Faurot.
> Maybe things are drastically different on macOS, but getaddrinfo() is the way to resolve names on Linux and I suspect the *BSDs.
I'm not sure if this is the case in this case, but it might be worth noting that some system functions with the same name have drastically different internal/implementation differences between Linux/*BSD/MacOS. With there being differences between the *BSDs too.
So on some systems one function call is "the way", because its been maintained over the years, but then on another it might actually be old and not useful.
Everything in the UNIX compatibility layer is low-level in macOS. Not necessarily "legacy" though.
But this is no different than saying that, for example, calling out platform-specific native OS APIs from Java is "low-level." Which it is, from the perspective of compile-once, run-anywhere Java applets. macOS is a NeXT-compatible non-UNIX API, and you are supposed to use the macOS frameworks for everything. Calling down to BSD or even mach is definitely not what Apple wants you to do.
Seems to be badly phrased and meant something else, since macOS is certified to be UNIX - https://www.opengroup.org/openbrand/register/ - contrary to Linux which is not UNIX-certified.
For quite some versions that modern networking APIs on macOS using Objective-C frameworks, starting in 2018.
See WWDC 2018's "Introducing Network.framework, A modern alternative to sockets".
NeXTSTEP might have been a UNIX, and macOS derives from it, but the whole UNIX story has always been to bring UNIX software into the platform, not to make it easier to move elsewhere.
The Apple deck linked elsewhere in this thread suggests the developer's goal generally isn't "DNS resolution", the dev's goal is usually establishing a connection to a host/server/endpoint to start doing something.
So, usually devs should use the Java or Apple or whatever higher level OS API gets you connected the fastest, and that API is free to implement the connection however most quickly gets to the point of able to return data to the user (app or end user).
The API that returns a list of addresses is stuck doing that, instead of being able to parallize the entire "get connected" data flow.
Yes, this! I even wonder how else you would do this. By the way I worked with many IoT devices that do not use your dhcp dns but just hardcode quad 8 or similar
Yeah, this report seems a little spun. The essence is basically that the encrypted DNS needs to go through the proxy, and there's resolver code elsewhere in the OS that doesn't use the proxy. It's a bug, sure. It could plausibly have interesting exploits, though none are shown. But it's not a very interesting bug.
>UPDATE: Spoke too soon…
The problem discussed here turned out to be specific to Little Snitch 6.1 and not a general issue in macOS. It will be fixed in an update of Little Snitch later today.
> After further investigation, we found that this bug has already existed at least since macOS 14.5 Sonoma (maybe even earlier, but we currently don’t have access to an older 14.x system for testing).
Did they test it ever worked with getaddrinfo? Or did they just see it worked once with CFNetwork and called it a day and then later publish a blog post saying it’s broken?
It's ridiculous us developers still have to jump through hoops to save around older versions of the OS for testing. There is 0 technical reason why Apple can't let us downgrade.
Can someone fill me in on this? What hoops have to be jumped through? The last time I used macs, there were no issues downloading and installing older OS versions, but I have not used them recently.
You can do a fresh install of an older macOS version whenever you like (you need to enable that option in the rescue system tho).
You can also run older macOS in a VM (the hypervisor framework keeps getting new features that make guest macOS more fully supported).
Name an OS (ok maybe NixOS) that allows you to do clean downgrades out of the box. Also wonder what's gonna happen to your data in e.g. Postgres if you blindly downgrade.
Before Sequoia when using OpenDNS for VPN, could be on VPN and iMessage and other apps still work, but since Sequoia, when on VPN iMessage (text messages) etc no longer work. Once I disconnect to VPN all goes through. Is this related at all? Do have macOS firewall enabled. But not block all incoming connections.
After upgrading to Sequoia, I could not browse with Safari or Mozilla. What fixed it for me was to go to the DNS settings for my Wi-Fi connection, and add Google's DNS servers (8.8.8.8. and 8.8.4.4). They replaced the autofilled DNS servers that were there.
Were the autofilled DNS servers in RFC1918 private space (10.0.0.0/8, 192.168.0.0/16, etc.)? I had issues after the upgrade with Google Chrome being unable to access hosts in these ranges, and fixed it by going to System Settings -> Privacy & Security -> Local Network and toggling Google Chrome off and on again.
There is no such thing as a remotely cross-platform DNS resolution API that has the system do the lookup and does not utterly suck for asynchronous use.
I remember 20+ years ago when one of the most commonly seen attacks was malware configuring a proxy server in Internet Explorer which by design overrode the operating system's configuration.
What a lot of software does today by ignoring the operating system in lieu of their own shit is just like the above. If your program doesn't (or can't) respect the operating system, your shit is malware and you should reconsider who you write code for.
I have one browser setup to do DNS differently than another. I don't want to have to set it at a system level and then need multiple systems just to run 2 browsers with different DNS lookup
Yep, I wish they would go the full way and block socket access entirely so your own outgoing traffic is always introspectable even with cert pinning. It would make it blatantly obvious when apps try shady shit.
Devil's advocate would say: They could do this and make it look like a bug that never gets fixed in order to avoid backlash. How it gets achieved is flexible if the goal is met.
Why would they be afraid of backlash on such an obscure, technical feature? They never were in the past and are expected to take controversial technical decisions by now. And by “now”, I mean in the last 30-odd years.
I maybe imagining but I feel like deja vu that there will be a problem with DNS that would affect Little snitch., Mullvad and others with new releases of iOS and Mac. If true I would really question what apple is doing during their months long developer and beta testing.
I was confused at the Little Snitch mention, and then reading further it just seems like a LS bug, that it only works in certain cases.
Well, seems this is the LS blog, so only confusion is why this is portrayed as a macOS bug? I'm not saying it's wrong, it's their domain not mine after all, it just doesn't seem to be justified in TFA?
If I recall, Apple deprecated use of certain network apis for third party developers. But Apple’s own apps (App Store) do not have these same restrictions. Thus, when trying to filter network traffic via app firewall via new APIs. It would fail since App Store uses legacy APIs.
Maybe part of this old bug (that I thought was fixed)
Sure, I expect most macOS apps will use something in Foundation or some other NetworkKit-type framework to do DNS queries, but it's odd to me that the code there wouldn't then call down to getaddrinfo() or the like to do the dirty work. I guess GAI is blocking, so presumably there's some other low-level non-blocking call?
Correct, CFNetwork is open source so you can check implementation but last I remember it used some variant like `getaddrinfo_async`. But Apple really doesn't want you (the end-user) to use getaddrinfo (or the async variant CF exposes) to resolve an IP and then directly connect() via that ip, everything is geared towards connect-by-hostname since then Apple's can internally handle the implementation of happy-eyeballs.
Edit: You can read https://www.ietf.org/proceedings/72/slides/plenaryw-6.pdf for their thoughts on why they don't like the getaddrinfo() model [there are speaker notes at the bottom of each slide]
https://developer.apple.com/library/archive/documentation/Ne...
Applications should not use getaddrinfo(). Because for the connect by name, the OS or app SDK can parallelize the entire multi-step lookup and connection process, not just step by step:
“Now, I’m not saying that all implementations of these APIs [Java, Apple Foundation, etc., doing connect by name] necessarily do the right thing today, but if applications are using these APIs, then the implementations can be improved over time.”
“The difference with getaddrinfo() and similar APIs is that they fundamentally can’t be improved over time. The API definition is that they return you a full list of addresses, so they have to wait until they have that full list to give you. There’s no way getaddrinfo can return you a partial list and then later give you some more.”
The deck's position on implementation of happy-eyeballs (which could sound dismissive here but is treated as "you had one job" important by the deck), is finding a way to avoid waiting 5 seconds for either side of IPv4 vs. IPv5 stack to timeout before finishing connection setup and serving the user a web page.
I don't think it is considered legacy. The blog post gets that wrong.
(Whether it's "low-level" or not just depends on your perspective.)
Not at all. That's just a glibc function, it's got nothing to do with Linux. People just assume that glibc is how things are done in Linux user space but it doesn't have to be that way. For example, systemd came up with its own resolved mechanism which turned out to be much better than the glibc stuff. I will probably end up inventing my own at some point as well since I'm working on freestanding software targeting Linux.
So OP might not be completely accurate, but getaddrinfo is _the_ way to resolve names if you are writing portable POSIX and/or UNIX code.
(As an administrator I'm getting a bit tired of working around the differing bugs and behaviour of different resolver implementations).
glibc also has an async getaddrinfo_a function for asynchronous name resolution, with completion notification.
At least on OpenBSD, all classical/standard DNS functions (getaddrinfo/gethostbyname/...) are wrappers around OpenBSD's libc asr implementation, written by Eric Faurot.
https://man.openbsd.org/man3/asr_run.3
https://github.com/openbsd/src/tree/master/lib/libc/asr
I'm not sure if this is the case in this case, but it might be worth noting that some system functions with the same name have drastically different internal/implementation differences between Linux/*BSD/MacOS. With there being differences between the *BSDs too.
So on some systems one function call is "the way", because its been maintained over the years, but then on another it might actually be old and not useful.
But this is no different than saying that, for example, calling out platform-specific native OS APIs from Java is "low-level." Which it is, from the perspective of compile-once, run-anywhere Java applets. macOS is a NeXT-compatible non-UNIX API, and you are supposed to use the macOS frameworks for everything. Calling down to BSD or even mach is definitely not what Apple wants you to do.
Seems to be badly phrased and meant something else, since macOS is certified to be UNIX - https://www.opengroup.org/openbrand/register/ - contrary to Linux which is not UNIX-certified.
HN posted about this at least once - https://news.ycombinator.com/item?id=29984016
Isn't the Mach kernel based on BSD?
How much of getaddrinfo is in the kernel, how much of it is pure "libc"?
See WWDC 2018's "Introducing Network.framework, A modern alternative to sockets".
NeXTSTEP might have been a UNIX, and macOS derives from it, but the whole UNIX story has always been to bring UNIX software into the platform, not to make it easier to move elsewhere.
EDIT: maybe not anymore, Sequoia isn't listed yet, https://www.opengroup.org/openbrand/register/xy.htm
So, usually devs should use the Java or Apple or whatever higher level OS API gets you connected the fastest, and that API is free to implement the connection however most quickly gets to the point of able to return data to the user (app or end user).
The API that returns a list of addresses is stuck doing that, instead of being able to parallize the entire "get connected" data flow.
https://github.com/apple/swift-async-dns-resolver
I can’t blame them but I personally would still have my apps use them, even knowingly that it would be made off-limit to iOS/iPadOS apps … soon.
/s
New title from source: Warning: DNS encryption in Little Snitch 6.1 may occasionally fail
> After further investigation, we found that this bug has already existed at least since macOS 14.5 Sonoma (maybe even earlier, but we currently don’t have access to an older 14.x system for testing).
You can do a fresh install of an older macOS version whenever you like (you need to enable that option in the rescue system tho).
You can also run older macOS in a VM (the hypervisor framework keeps getting new features that make guest macOS more fully supported).
Name an OS (ok maybe NixOS) that allows you to do clean downgrades out of the box. Also wonder what's gonna happen to your data in e.g. Postgres if you blindly downgrade.
FYI, it looks like Firefox fixed this.
The reasons applications do this is to prevent users from blocking telemetry etc. It's my computer, I should have final say on what goes out.
I remember 20+ years ago when one of the most commonly seen attacks was malware configuring a proxy server in Internet Explorer which by design overrode the operating system's configuration.
What a lot of software does today by ignoring the operating system in lieu of their own shit is just like the above. If your program doesn't (or can't) respect the operating system, your shit is malware and you should reconsider who you write code for.
I also wish people would post the FB numbers and the details of their report when they say they've reported things like this.
Well, seems this is the LS blog, so only confusion is why this is portrayed as a macOS bug? I'm not saying it's wrong, it's their domain not mine after all, it just doesn't seem to be justified in TFA?
Besides, apps can always make direct lookups to a resolver of their choice, bypassing any resolver hints of the operating system.
Maybe part of this old bug (that I thought was fixed)