Commit graph

29 commits

Author SHA1 Message Date
Andreas Kling
789d7cba48 LibWeb: Use direct references to main event loops
Post off-thread font, script, and DNS completion work back to direct
Core::EventLoop references. These callbacks target the process main
loop, which is intentionally kept alive for the lifetime of the
process.
2026-06-05 09:18:39 +02:00
Andreas Kling
164ed80244 Meta: Enable exit-time destructor warnings for libraries
Enable -Wexit-time-destructors for all in-tree library targets and
update process-lifetime library statics so they no longer register
exit-time destructors. Long-lived caches, lookup tables, singleton
registries, and generated constants now use NeverDestroyed or leaked
references where the data is intended to live until process exit.

Update LibWeb, LibLine, and the binding generators so regenerated
sources follow the same rule instead of reintroducing destructed
statics.
2026-06-04 19:20:49 +02:00
François Guerraz
f756219841 LibDNS: Reject domain name labels longer than 63 octets
A DNS label length octet is a 6-bit value, so a label can be at most 63
octets. Several code paths violated this and aborted the process:

- DomainName::from_raw() treated any length octet that was not a
  compression pointer as an ordinary label, including the reserved
  0b01/0b10 top-bit encodings, yielding labels of up to 191 octets.
- DomainName::to_raw() then VERIFY-aborted on any label longer than 63
  octets while encoding it back to the wire.
- Resolver::lookup() encoded the outgoing query with MUST(to_raw(...)),
  so even once to_raw() fails gracefully the MUST would still abort.

Together these crash RequestServer, which drives DNS for the whole
browser. When a custom resolver is configured (e.g. --dns-server), a web
page that references a host name containing a label longer than 63
characters aborts RequestServer while the query is encoded. A response
carrying a reserved-length label is also accepted by the parser and then
aborts when the name is re-encoded (for example during DNSSEC
validation).

Reject over-long labels when parsing, return an error instead of
aborting when encoding, and reject the lookup promise instead of
MUST-aborting at the query call site.
2026-06-04 17:41:09 +02:00
Luke Wilde
fc4b499ab2 LibDNS: Resolve the .localhost special-use domain to loopback
Only the literal "localhost" was special-cased, so names within
".localhost" fell through to the host resolver or upstream DNS
server, neither of which is guaranteed to map them to loopback.
RFC 6761 reserves these names as always resolving to loopback for
address queries, so answer them in-process and never forward them
upstream.

https://www.rfc-editor.org/rfc/rfc6761#section-6.3
2026-05-29 22:23:33 +02:00
R-Goc
02bb892d7a LibThreading/LibSync: Split out sync primitives
This commit splits out synchronization primitives from LibThreading into
LibSync. This is because LibThreading depends on LibCore, while LibCore
needs the synchronization primitives from LibThreading. This worked
while they were header only, but when I tried to add an implementation
file it ran into the circular dependency. To abstract away the pthread
implementation using cpp files is necessary so the synchronization
primitives were moved to a separate library.
2026-05-08 18:58:35 -05:00
Andreas Kling
6f4096a4ca LibDNS: Run getaddrinfo on a thread pool to avoid event-loop freezes
getaddrinfo can hang for many seconds when the system stub resolver
misbehaves; running it inline on the event loop froze every other
request, IPC, and curl socket event for the duration.

New PendingSystemResolution coalesces concurrent lookups for the same
name, dispatches the call to a Threading::ThreadPool worker, and
deferred-invokes the result back to the originating event loop. Each
caller of lookup() gets its own Core::Promise so concurrent
when_resolved/when_rejected handlers can't clobber each other; the
pending state fans out to every joined caller on completion.

Workers issue A and AAAA in parallel on separate sockets to sidestep
the systemd-resolved AAAA-drop bug, and resolve the user's promise
after the first side returns records (with a 50 ms RFC 8305 grace
window for the other side).

Adds Core::Socket::AddressFamily and an optional parameter to
resolve_host so workers can request A or AAAA specifically.
2026-04-26 17:59:52 +02:00
Andreas Kling
f310c222cb LibDNS: Honor negative-cache hits for completed lookups
lookup_in_cache required records of every desired type, so a completed
lookup that returned only A records (e.g. for a host with no AAAA)
missed the cache when the next caller asked for {A, AAAA}, triggering
a re-query.

Pass later=true to has_record_of_type for is_done() entries so "we
asked about AAAA and got none" is treated as a definitive answer.
In-flight entries still fall through to the join-pending path.
2026-04-26 17:59:52 +02:00
Andreas Kling
072a3bdb90 RequestServer: Add diagnostic wire-activity logging
Per-request and per-connection logging that surfaces enough detail
to diagnose where time goes when a page load misbehaves. Gated by a
new REQUESTSERVER_WIRE_DEBUG cmakedefine.

Documentation/RequestServerWireLogging.md describes each label
(wire/wire+/wire++/wire^, wire-batch, wire-stall, wire-burst,
wire-pipe-pressure, LibDNS wire-dns, UI wire-cookie) and how to read
them.
2026-04-26 17:59:52 +02:00
Jelle Raaijmakers
41cf150a5b LibDNS+RequestServer: Don't construct Vectors to validate DNS response
Instead of filling vectors and returning them just to invoke
`.is_empty()`, forward the calls to the underlying vectors directly.
2025-08-13 10:30:04 -04:00
Ali Mohammad Pur
d49106c007 LibDNS: Send the dnssec queries in parallel 2025-06-25 08:20:40 +02:00
Ali Mohammad Pur
833617c8fe LibDNS+dns: Avoid multi-question queries
This is not supported by much of anything (correctly), so send the
requests in parallel instead.
2025-06-25 08:20:40 +02:00
Tomasz Strejczek
6fb2be96bf Everywhere: Replace DateTime::to_string() with UnixDateTime::to_string()
Replace LibCore::DateTime::to_string() with
AK::UnixDateTime::to_string().
Remove unncessary #include <LibCore/DateTime.h>.
2025-06-19 18:42:45 -06:00
rmg-x
5e9ceac16c LibDNS: Add debug messages for error response codes in resolver 2025-06-13 11:42:01 +02:00
Ali Mohammad Pur
b24fb0a836 LibDNS: Add support for local DNSSEC validation 2025-06-11 18:16:29 +02:00
Timothy Flynn
7280ed6312 Meta: Enforce newlines around namespaces
This has come up several times during code review, so let's just enforce
it using a new clang-format 20 option.
2025-05-14 02:01:59 -06:00
Luke Wilde
08246bfa8c LibCore: Don't discard subsequent results in Socket::resolve_host
Previously, we only returned the first result that looked like an IPv6
or IPv4 address.

This cropped up when attempting to connect to https://cxbyte.me/ whilst
IPv6 on the server wasn't working. Since we only returned the first
result, which happened to be the IPv6 address, we wasn't able to
connect.

Returning all results allows curl to attempt to connect to a different
IP if one of them isn't working, and potentially make a successful
connection.
2025-02-28 15:14:35 +01:00
Andrew Kaster
eb4c565e57 LibDNS: Add missing Core::Socket include to resolver
Without this, we get incomplete type errors
2025-02-20 15:04:50 -07:00
rmg-x
1083046f65 LibDNS: Check if cached lookup result is done before resolving 2025-02-11 07:24:33 +01:00
rmg-x
ec481aa08a LibDNS+RequestServer: Fix UAF in lookup() by changing Span -> Vector
Co-authored-by: Ali Mohammad Pur <ali.mpfard@gmail.com>
2025-02-11 07:24:33 +01:00
rmg-x
4904326244 LibDNS: Fix check for cache entries that can be removed
Co-authored-by: Ali Mohammad Pur <ali.mpfard@gmail.com>
2025-02-11 07:24:33 +01:00
rmg-x
4a16c89603 LibDNS: Fix deadlock when receiving invalid lookup result
Previously, we would stop the repeat timer even if we got a null result.
This caused the pending lookup to:
- Never resolve, and
- Never get purged for too many retries

I believe the underlying issue is something on the socket level, but we
should handle this case regardless.
2024-12-01 11:32:45 +01:00
Ali Mohammad Pur
9648c83b7d LibDNS: Don't purge lookup entries that are not yet fully resolved 2024-11-30 23:18:13 +01:00
Ali Mohammad Pur
ff311c1560 RequestServer+LibDNS: Don't .await() the DNS lookup promise
...and make sure it will eventually complete (or fail) by adding a
timeout retry sequence.

Fixes an issue where RequestServer would stick around after exit,
waiting for piled up DNS requests for a long time.
2024-11-25 11:46:35 +01:00
Pavel Shliak
cd14b215d1 LibDNS: Clean up #include directives
This change aims to improve the speed of incremental builds.
2024-11-21 14:08:33 +01:00
Ali Mohammad Pur
63a5717bc7 LibDNS: Immediately resolve IPv4/IPv6 "hostnames" if A/AAAA is queried
This makes e.g. lookup(192.168.1.1, A) resolve to the IP instead of
querying DNS for the IP.
2024-11-20 21:37:58 +01:00
Ali Mohammad Pur
c5afe58540 LibDNS: Add a default entry for localhost
In the future, we may want to parse /etc/hosts (or equivalent) into the
cache; this commit only adds localhost to make the normal workflow work.
2024-11-20 21:37:58 +01:00
Ali Mohammad Pur
3bcd91b109 LibDNS: Hide some debug logs behind DNS_DEBUG 2024-11-20 21:37:58 +01:00
Ali Mohammad Pur
6911c45bab LibDNS: Respect records' TTL in the resolver cache 2024-11-20 21:37:58 +01:00
Ali Mohammad Pur
7e20f4726f LibDNS+LibWeb+Ladybird+RequestServer: Let there be DNS over TLS
This commit adds our own DNS resolver, with the aim of implementing DoT
(and eventually DoH, maybe even DNSSEC etc.)
2024-11-20 21:37:58 +01:00