This is the DNS developer room.
I hope you know that.
First speaker, Valentin, who will be talking about
Get Other Info and other ways to resolve names.
I hope you can hear from my heart.
Hi everyone, welcome to my talk.
Get Other Info sucks and everything else is much worse.
First off, my name is Valentin Goshu.
I'm a DNS enthusiast and developer on the networking team for Mozilla Firefox.
I've been on the team for almost 11 years now.
I spent a bunch of time maintaining our DNS stack,
and especially working on our DNS over HTTPS implementation.
I'm originally from Romania, but currently reside in Sweden.
And you can reach me at any of these emails.
As you'll see later, I'm a big fan of emojis.
So, they're going to be a big part of the presentation.
I'm also a natural introvert, so I'm not great at starting conversations.
But if you have any questions, I'm quite friendly, so please come and say hi.
Full disclosure. Yes, the title is clickbait.
No yet, other Info doesn't really suck.
Unless you want to use it for something that it can't really do.
This talk might include some rent.
And I really know what I'm doing.
I'm just an user of these APIs that I'm going to talk about today.
So some of you in this room may know a few things more than I do.
And if I'm doing something wrong, just because I'm dumb.
Don't be afraid to tell me.
Yeah, so get other Info.
It's been with us for a very long time.
It originally was part of an IT people-edraft containing the socket extensions.
And then it was imported in RFC 2021-33, and then updated a few times after that.
Get other Info as a pretty simple API.
These are the most important parts of it, apart from the stock adder struct.
And so like what's great about adder info?
First of all, it's simple.
It follows the POSIX philosophy.
It does one thing and one thing well.
It works.
It's well documented.
And it's available on all platforms, and it works roughly the same on all platforms.
Which is already quite amazing.
As we'll see with some of the other APIs, when each OS does its own thing,
you wind up with a variety of things with different levels of quality.
Yeah, so like this prescriptive nature of the RFC,
and the fact that these are included in libres of and libse and system libraries,
meant that if you want to resolve the main name to an IP address,
it is easy and straightforward on all operating system.
And I think that's something we sometimes take for granted about yet other info.
It really, really works.
Now what sucks about yet other info?
It's a synchronous API.
That's sometimes good and sometimes bad.
But the fact is that threads take up resources, not a lot, but enough.
And I think API would have been nice to have.
It is also very limited.
As I said, it does one thing and does one thing well.
It doesn't expose the full response details,
so like some things that are missing, like the TTL,
EDNS values, the actual code from the response,
and the full C-name chain in the DNS response.
These are things that would have been great to have sometimes,
but if you need them, yet other info doesn't really have them.
There are also minor implementation differences.
For example, the Bionic implementation in Android
fails if any of the domains in the C-name chain
starts with a dash or an underscore.
And that's something that works on other operating systems.
So that's quite surprising sometimes.
And there's no good way to control the request,
so like if I want to bypass the cache or it is slash host.
Yeah, it's not possible to do that.
And sometimes that would be great to do.
Now let's go over the Firefox implementation really quickly.
In Firefox, we have a dedicated thread pool for DNS resolution,
or NS host resolver class has a bunch of cues with different priorities.
And then each thread looks in the priority cues,
in order of priority, picks up one request,
and then calls get the other info on them.
Of course, there's also caching.
So like if the domain name is already in the Firefox DNS cache,
it never winds up in one of those priority cues.
But it's like resolve immediately.
And of course, there are multiple layers of caching.
Like there's one in the Firefox DNS cache.
There's the OS DNS cache, and there's the ISP DNS cache.
So that's something that we also need to keep in mind.
Yeah, and as I mentioned, get other info doesn't provide details.
So Firefox had to do something about it.
So like we were caching things,
but we don't know for how long to cache those things.
So if we only cache them for one minute,
that means we're sometimes calling get another info immediately.
So what we did instead was on Windows,
we used DNS query A, just to get the TTL value.
So we call get another info, then we call again,
DNS query A, just for that TTL value.
Which isn't great, but it works fairly well.
And at some point, we started our DNS over HTTPS implementation,
which kind of changed how things work.
So like for more thread pull, calling get another info,
we changed it to an event loop that takes the HTTPS response
and parses the DNS payload.
So like all in one thread.
And now, so we had that DNS response,
like we had TTL values, and we could parse any resource record we wanted,
such as text records, or scene names, or whatever.
And a few years ago,
we got the SVCB service record,
an HTTPS resource record, which are really great.
Yeah, and before we continue,
I know some of the people in this room may have
like strong opinions about DNS over HTTPS.
And I wanted to note that there's a difference
between the dual protocol and the implementation in Firefox,
and Firefox trusted recursive resolver program,
which means that the resolvers that are defaults in Firefox
are contractually obligated to follow our privacy requirements.
And I'm quite happy to talk about that after the presentation,
if you have any questions.
So the SVCB resource records,
an HTTPS record, the resource records,
are quite useful.
So if the user tries to load example.com,
www.example.com,
Firefox will resolve the HTTPS record,
and just even before connecting to example.com,
it will know that, hey, this host has an HTTPS record,
that means there's no reason to use plain text HTTP.
It also knows that it supports HTTP2,
before negotiating it on the default port,
and it knows that it supports HTTP3 on an alternative port.
So if it wants to do HTTP3,
we can connect it at alternative port,
and the nice thing is that the URL bar will still
show the same origin, so like with the default TLS port,
and it will have the same origin meaning
that it will share the same origin.
It will be same origin with things like websockets and other resources.
And there's other nice things in HTTPS records as well,
like IPv4 hint and IPv6 hint,
and then crypt and client hello,
which is great for privacy because it allows you
to hide the server name indication in the TLS handshake.
Yeah, so that's great,
but previously this was only available for Firefox users
who used to do, and that's not all of them.
So we want to bring the benefits of HTTPS records
to all of Firefox users.
So we looked at native OS APIs to resolve HTTPS records,
which have a few advantages,
like we're using the same resolver as the rest
of the operating system.
It may share the OS cache,
and maybe the implementation is easier.
That's something that we still don't know
whether it's true or not.
And yeah, when going into this project,
our expectations for these APIs were that they exist,
they're well documented, and that's they actually work.
Yeah, so the best experience with the Linux implementation,
res and query, which is well documented,
it's easy to use, and after calling res and query,
the buffer you pass into answer will contain the response bytes
that you can parse with any DNS packet parser.
And that's pretty much it.
We were able to use the same parser that we had
for our dough implementation, which was nice.
The next platform was Android,
and we looked at res query,
but immediately when trying to use it,
we noticed that it didn't really work.
So just calling it for a record,
it just returned minus one.
I didn't find much documentation about it.
Apart from a lonely stack overflow question,
and a few forum posts,
that said, okay, yeah, it doesn't work.
So the implementation is completely worked.
I did it ever work.
I have no idea, maybe it did.
But at least this gave us a good hint
to look next, which is Android,
res and query.
So as you'll notice, this one needs dynamic linking
to libandroidnet.so,
where, and calling res and query returns a file descriptor,
which you can pull, you can select, you can read from it,
and the interesting thing about this one
is that the answer here, the buffer,
will actually contain the eight bytes for the UDP header,
which was unexpected.
None of the other APIs behave like that.
Yeah, so my main right with this API
is that it's only available on Android 10 and up.
Fortunately, most Firefox users use a newer Android version,
but it would have been nice to also support those
user-dom on older phones too.
It's relatively well documented,
and you can specify it on like caching flags
and the network interface that it's supposed to use.
I haven't checked if these actually work,
but I also haven't found anything that said that they don't work.
Yeah, so next up is Windows.
So as I mentioned, we already used the DNS query A
for resolving A and quad A records.
The big surprise was that on Windows 10,
resolving HTTPS records returned null,
which was really, really surprising,
because the same code just worked on Windows 10.
So obviously, there's a Windows bug here.
We reported it to Microsoft,
and reached out to some of their developers.
But so far, there's been no progress on it.
So if you want to upload it, if you're on Windows,
please go to the URL and give it a thumbs up.
Yeah, so exists.
Well, documented kind of works on Windows 11.
And there are some things I really like about this API.
So it's really powerful.
It has lots of options to control how the query is made,
like taching, use of the host file,
whether to use recursion or not.
There's also DNS query X, which is A sync,
which is like nice, if you don't want to use multiple threads.
The response is a link to list of records,
like similar to to get other info.
And the nice thing about DNS record is that
the data field is actually a union.
So you can either access it as a struct,
or you can access it as a buffer of bytes,
and parse it with your otherwise DNS bucket library.
Yeah, and you have the length of the DNS record, which can use.
So I think this API is quite powerful and flexible.
So if it weren't for the Windows 10 implementation bug,
this would have been one of my favorite APIs here.
Yeah, now we get to the vein of my existence,
which is macOS.
So like when we first started, we looked into risk query,
but it soon became a parent that risk query is not thread safe.
So that means it kind of works,
but you can only resolve one record at the time.
The documentation for it is not great.
It says nothing about thread safety.
So soon after this presentation,
this talk was approved.
I actually found out about DNS service query record.
It's like this one definitely exists.
The documentation could be better.
It is thread safe.
So I don't know if there's a lot of mac developers in the room,
but my experience with Apple documentation is that it kind of sucks.
Most APIs is just like, yeah, this is the function definition
and like a short description for all the options.
And that's pretty much it.
But I would really like examples and something that
talk about how things actually work.
So it's quite an interesting API.
You define a callback.
Then you call the service query record.
And then you call process resolved on it.
And the callback gets called with the records.
Now, what would you expect to happen if that host
did not have an A record?
Well, what I actually expected to happen is that this callback gets called
with an error, right?
Well, what actually happens is that the callback never gets called
if you don't have that record.
I have no idea how these things happen.
I hope this is a bug.
There is a worker on for it.
So you can define a timeout there.
But the fact that you have to wait for a timeout instead of the callback
getting called when the NX domain comes back,
it's just weird.
You shouldn't need to do that.
NX domain.
Yeah.
So yeah.
So I looked in Wireshark and saw that the records
goes out.
Response comes back.
Nothing happens.
It's just thanks.
So some things I learned in this experience,
like the API capabilities vary widely across platforms.
An abstraction library would be really nice.
So like in Firefox, we use an SPR, which is kind of old and not
maintained so much and difficult to update.
So it would be nice if there were something like a rust library,
which abstracted all these details away.
Sometimes implementing your own DNS client would
might be worth it, or use an existing library.
And please, if you ever use some of these APIs or things,
like trees blog posts about it, or documentary experience,
because for me implementing this,
it was quite difficult to find any resources about some of these.
So yeah.
Working the open, I think that's really valuable.
And what kinds of APIs would I like?
If I were to request one.
So as I mentioned, the DNS query A and DNS query X have lots of options
and would be really useful.
I kind of liked Android risk query to the fact that it kind of
gave you access to the socket and the response bytes.
So you can actually wait on it, like even the UDP header.
That was nice.
I would like some better control over the request bytes as well.
I think that would be nice.
And like yet other info, I would like something that works everywhere.
So like if all operating systems could get together and
said, yeah, this is what we're going to implement.
And make sure that it's going to work the same way.
I would be really, really, really happy.
So yeah.
Thank you.
Any questions?
We have one question from Matrix.
I'll start there.
You have to repeat it as you are holding the microphone.
Yes.
Hasmobzilla tried requesting more modern APIs from some OS vendors.
With listed requirements, missing and get other info.
Yeah.
So the question is, hasmobzilla tried requesting more modern API from some OS vendors
with listed requirements missing and get other info?
No, we haven't.
We haven't found bugs for some of these issues.
But no.
Right now, we haven't tried to drive the development of new DNS APIs.
Yeah.
All right.
So I do have a question that relates it to this.
Yes.
So recently, there was a security researchers planning bugs in the park.
It's just a little lot of the answers.
There's many additional records, compression.
So are you doing your own DNS parsing or are you relying on the system?
Because it makes back, I'm feeling.
So have you thought about these?
Like, if you receive the huge DNS response,
there has a lot of compression pointing through each other and then stuff.
So you just can blow off in the.
Yes.
Well, we have.
So I should repeat the question.
So there were some like security issues with DNS packets and compression,
and like blowing up in size and getting very, very big.
Yeah.
So we've, I know we've had one of one issue, like that in the past in Firefox,
because we implement our own like DNS packet parser,
which is like, very simple, but it does do compression.
But so we are looking into maybe using something,
not implementing something or something,
or maybe using an off the shelf library.
Yeah.
To avoid kind of like not having to re-implement some of these things,
especially when they're in like more established DNS libraries.
So follow up.
Yeah.
Do you want to be included?
Something like this comes up.
And the security researchers come to, well,
that's not the end of vendors.
Do you want to be like in this?
Yes.
So the question is whether we'd like to be included,
when there's a.
Research by by security researchers and S,
and the answer is yes.
I think that would be very useful for us.
And second question and matrix is.
Have you tried getting HTTPS RR?
Not only with DNS specific APIs,
but there's any OS provide a way to request it over multi-cast DNS,
for example.
I don't know.
I haven't looked into it at all.
Okay.
Questions in here?
Like that?
If you kind of said far,
if you want to see an X,
then what do you just,
probably think something's in there,
okay, and that's the reason why I'm looking at this.
So the question is,
if we're doing our own DNS parsing,
we just open a socket and do the request ourselves.
Right?
That's a very good question.
And that's something we are exploring in the future,
just because of all the things that I mentioned here.
Like all the platforms that don't work.
But rather than doing that,
we're actually looking at maybe using a rust implementation
that already exists,
that's like that's a DNS client.
So maybe using one of those,
including it's DNS packet parser.
Any other questions?
Yeah.
What's on there, a project to unify DNS query,
I'm forcing, get DNS.
The question is,
whether there was an attempt to unify DNS parsing
with DNS requesting resources with get DNS?
I don't know.
Maybe there's someone else in the room
who has more information about this.
Yeah, come on.
I get DNS was of ease,
depending on who you ask.
The project was a unified API,
a recent intimidation.
It can, as detailed as a get DNS API.
Up next.
From the point to the point, it works.
It could be a solution to this.
As far as I know,
it's going out of favor now,
but not the format.
Yeah, thank you.
Could you show or write that?
Like one sentence?
So there is an attempt to use get DNS,
but it's falling out of favor,
and it can be found out,
yet DNS.org.
Get the APIs,
get DNS API.net.
Thank you.
Oops.
This is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could do, this is the first one I could