Skip to content

resolver: use SRV target as federation URL hostname - #480

Open
amaanq wants to merge 1 commit into
matrix-construct:mainfrom
amaanq:resolver-srv-sni
Open

resolver: use SRV target as federation URL hostname#480
amaanq wants to merge 1 commit into
matrix-construct:mainfrom
amaanq:resolver-srv-sni

Conversation

@amaanq

@amaanq amaanq commented Jun 5, 2026

Copy link
Copy Markdown

actual_dest_3_3 and actual_dest_4 returned the caller's server_name as the URL hostname while the IP override pointed at the SRV target. reqwest derives TLS SNI from that hostname, so behind an SNI-routing proxy, requests end up hitting the wrong backend.

This commit routes both through srv_url_dest to track the SRV peer.

I ran into this when a synapse homeserver was down temporarily then came back up, causing many issues between chatting with users on that homeserver.

`actual_dest_3_3` and `actual_dest_4` returned the caller's `server_name`
as the URL hostname while the IP override pointed at the SRV target.
reqwest derives TLS SNI from that hostname, so behind an SNI-routing
proxy, requests end up hitting the wrong backend.

This commit routes both through `srv_url_dest` to track the SRV peer.
@jevolk

jevolk commented Jun 5, 2026

Copy link
Copy Markdown
Member
Source Connect target SNI / cert host Host header Authority / evidence
Matrix spec (normative) SRV target (resolved IP:port) base name base name server-server-api §Resolving server names (steps 3.3, 4; SRV rationale note: cert must be valid for <hostname>/<delegated_hostname>, not the SRV target)
conduwuit/tuwunel (main, current) SRV target (IP override) base name base name actual.rs L192-218 (3.3), L229-253 (4)
conduwuit/tuwunel (with PR #480) SRV target SRV target SRV target (follows URL) fed.rs srv_url_dest L47-60, actual.rs L214-230, #480 diff
Synapse 1.152.0 SRV target (TCP endpoint) base name base name agent.py L345 (TLS opts from base name), L393-395 (SRV target = endpoint only), context_factory.py L267 (SNI), agent.py L242 (Host)
Dendrite / gomatrixserverlib SRV target (Destination) base name (TLSServerName) base name (Host) resolve.go L124-126 (ResolutionResult), client.go L305 (ServerName), L372-374 (dial + Host)
Conduit SRV target (IP override) base name base name server_server.rs L556-604 (get_srv_destination), globals/mod.rs L125-137 (resolver)
Continuwuity SRV target (IP override) base name base name actual.rs L211-236 (4), L175-201 (3.3)
resolvematrix (extracted crate) SRV target (DNS override) base name (host) base name (host) server.rs L49-72 (host = SNI/Host), L572-575 (SRV branch keeps base), L278-280 (resolver intent: "ensure the correct SNI")
matrix-oracle (standalone crate) SRV target (address()) base name base name Server enum: Srv(addr, hostname-from-server-name), address() vs host_header()

@amaanq

amaanq commented Jun 5, 2026

Copy link
Copy Markdown
Author

Hm, I guess I should've checked the spec instead of coming up with a hack out of frustration that diverges from the spec in an undesirable manner.

It turns out I still had the deprecated _matrix._tcp SRV record around for the bare server name, which tuwunel fell back to when .well-known failed. I only serve on a dedicated chat. vhost, so the spec-correct SRV fallback landed on the wrong vhost. I've removed that which in theory should fix my issue should it happen again.

That does raise another question though, should a resolution derived from a failed .well-known get cached for 18-36h? The spec recommends caching .well-known errors for up to 1h with backoff (https://spec.matrix.org/latest/server-server-api/#resolving-server-names see the third point).

I would like to tackle that if that's fine with you. If it is, would you prefer I update this pr or make a new one?

@jevolk

jevolk commented Jun 8, 2026

Copy link
Copy Markdown
Member

That does raise another question though, should a resolution derived from a failed .well-known get cached for 18-36h? The spec recommends caching .well-known errors for up to 1h with backoff (https://spec.matrix.org/latest/server-server-api/#resolving-server-names see the third point).

I would like to tackle that if that's fine with you. If it is, would you prefer I update this pr or make a new one?

Detecting false .well-known results which poison the cache would be a useful problem to tackle, but the overall cache cycle and chosen timings have been carefully determined based on years of experience running servers at scale on a variety of hosts and DNS providers.

It's probably better to open a new PR if the task has no overlap with this one. I would suggest running some experiments and thoroughly testing any changes to that area of code because it's very delicate and also mission-critical; the level of scrutiny for any PR would be above average.

@jevolk jevolk added the bug Something isn't right. label Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't right.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants