Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Switch from matrix:// to matrix-federation:// scheme for internal Synapse routing of outbound federation traffic #15806

Merged
merged 3 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/15806.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Switch from `matrix://` to `matrix-federation://` scheme for internal Synapse routing of outbound federation traffic.
2 changes: 1 addition & 1 deletion contrib/lnav/synapse-log-format.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"level": "error"
},
{
"line": "my-matrix-server-federation-sender-1 | 2023-01-25 20:56:20,995 - synapse.http.matrixfederationclient - 709 - WARNING - federation_transaction_transmission_loop-3 - {PUT-O-3} [example.com] Request failed: PUT matrix://example.com/_matrix/federation/v1/send/1674680155797: HttpResponseException('403: Forbidden')",
"line": "my-matrix-server-federation-sender-1 | 2023-01-25 20:56:20,995 - synapse.http.matrixfederationclient - 709 - WARNING - federation_transaction_transmission_loop-3 - {PUT-O-3} [example.com] Request failed: PUT matrix-federation://example.com/_matrix/federation/v1/send/1674680155797: HttpResponseException('403: Forbidden')",
"level": "warning"
},
{
Expand Down
4 changes: 2 additions & 2 deletions scripts-dev/federation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ def request(
authorization_headers.append(header)
print("Authorization: %s" % header, file=sys.stderr)

dest = "matrix://%s%s" % (destination, path)
dest = "matrix-federation://%s%s" % (destination, path)
print("Requesting %s" % dest, file=sys.stderr)

s = requests.Session()
s.mount("matrix://", MatrixConnectionAdapter())
s.mount("matrix-federation://", MatrixConnectionAdapter())

headers: Dict[str, str] = {
"Authorization": authorization_headers[0],
Expand Down
14 changes: 8 additions & 6 deletions synapse/http/federation/matrix_federation_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@
@implementer(IAgent)
class MatrixFederationAgent:
"""An Agent-like thing which provides a `request` method which correctly
handles resolving matrix server names when using matrix://. Handles standard
https URIs as normal.
handles resolving matrix server names when using `matrix-federation://`. Handles
standard https URIs as normal. The `matrix-federation://` scheme is internal to
Synapse and we purposely want to avoid colliding with the `matrix://` URL scheme
which is now specced.

Doesn't implement any retries. (Those are done in MatrixFederationHttpClient.)

Expand Down Expand Up @@ -167,14 +169,14 @@ def request(
# There must be a valid hostname.
assert parsed_uri.hostname

# If this is a matrix:// URI check if the server has delegated matrix
# If this is a matrix-federation:// URI check if the server has delegated matrix
# traffic using well-known delegation.
#
# We have to do this here and not in the endpoint as we need to rewrite
# the host header with the delegated server name.
delegated_server = None
if (
parsed_uri.scheme == b"matrix"
parsed_uri.scheme == b"matrix-federation"
and not _is_ip_literal(parsed_uri.hostname)
and not parsed_uri.port
):
Expand Down Expand Up @@ -250,7 +252,7 @@ def endpointForURI(self, parsed_uri: URI) -> "MatrixHostnameEndpoint":

@implementer(IStreamClientEndpoint)
class MatrixHostnameEndpoint:
"""An endpoint that resolves matrix:// URLs using Matrix server name
"""An endpoint that resolves matrix-federation:// URLs using Matrix server name
resolution (i.e. via SRV). Does not check for well-known delegation.

Args:
Expand Down Expand Up @@ -379,7 +381,7 @@ async def _resolve_server(self) -> List[Server]:
connect to.
"""

if self._parsed_uri.scheme != b"matrix":
if self._parsed_uri.scheme != b"matrix-federation":
return [Server(host=self._parsed_uri.host, port=self._parsed_uri.port)]

# Note: We don't do well-known lookup as that needs to have happened
Expand Down
9 changes: 8 additions & 1 deletion synapse/http/matrixfederationclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,14 @@ def __attrs_post_init__(self) -> None:

# The object is frozen so we can pre-compute this.
uri = urllib.parse.urlunparse(
(b"matrix", destination_bytes, path_bytes, None, query_bytes, b"")
(
b"matrix-federation",
destination_bytes,
path_bytes,
None,
query_bytes,
b"",
)
)
object.__setattr__(self, "uri", uri)

Expand Down
4 changes: 2 additions & 2 deletions tests/federation/test_federation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def test_get_room_state(self) -> None:
# check the right call got made to the agent
self._mock_agent.request.assert_called_once_with(
b"GET",
b"matrix://yet.another.server/_matrix/federation/v1/state/%21room_id?event_id=event_id",
b"matrix-federation://yet.another.server/_matrix/federation/v1/state/%21room_id?event_id=event_id",
headers=mock.ANY,
bodyProducer=None,
)
Expand Down Expand Up @@ -232,7 +232,7 @@ def _get_pdu_once(self) -> EventBase:
# check the right call got made to the agent
self._mock_agent.request.assert_called_once_with(
b"GET",
b"matrix://yet.another.server/_matrix/federation/v1/event/event_id",
b"matrix-federation://yet.another.server/_matrix/federation/v1/event/event_id",
headers=mock.ANY,
bodyProducer=None,
)
Expand Down
38 changes: 21 additions & 17 deletions tests/http/federation/test_matrix_federation_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ def _do_get(self) -> None:
self.agent = self._make_agent()

self.reactor.lookups["testserv"] = "1.2.3.4"
test_d = self._make_get_request(b"matrix://testserv:8448/foo/bar")
test_d = self._make_get_request(b"matrix-federation://testserv:8448/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -393,7 +393,7 @@ def _do_get_via_proxy(

self.reactor.lookups["testserv"] = "1.2.3.4"
self.reactor.lookups["proxy.com"] = "9.9.9.9"
test_d = self._make_get_request(b"matrix://testserv:8448/foo/bar")
test_d = self._make_get_request(b"matrix-federation://testserv:8448/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -532,7 +532,7 @@ def test_get_ip_address(self) -> None:
# there will be a getaddrinfo on the IP
self.reactor.lookups["1.2.3.4"] = "1.2.3.4"

test_d = self._make_get_request(b"matrix://1.2.3.4/foo/bar")
test_d = self._make_get_request(b"matrix-federation://1.2.3.4/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -568,7 +568,7 @@ def test_get_ipv6_address(self) -> None:
# there will be a getaddrinfo on the IP
self.reactor.lookups["::1"] = "::1"

test_d = self._make_get_request(b"matrix://[::1]/foo/bar")
test_d = self._make_get_request(b"matrix-federation://[::1]/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -604,7 +604,7 @@ def test_get_ipv6_address_with_port(self) -> None:
# there will be a getaddrinfo on the IP
self.reactor.lookups["::1"] = "::1"

test_d = self._make_get_request(b"matrix://[::1]:80/foo/bar")
test_d = self._make_get_request(b"matrix-federation://[::1]:80/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -639,7 +639,7 @@ def test_get_hostname_bad_cert(self) -> None:
self.mock_resolver.resolve_service.side_effect = generate_resolve_service([])
self.reactor.lookups["testserv1"] = "1.2.3.4"

test_d = self._make_get_request(b"matrix://testserv1/foo/bar")
test_d = self._make_get_request(b"matrix-federation://testserv1/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -693,7 +693,7 @@ def test_get_ip_address_bad_cert(self) -> None:
# there will be a getaddrinfo on the IP
self.reactor.lookups["1.2.3.5"] = "1.2.3.5"

test_d = self._make_get_request(b"matrix://1.2.3.5/foo/bar")
test_d = self._make_get_request(b"matrix-federation://1.2.3.5/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -725,7 +725,7 @@ def test_get_no_srv_no_well_known(self) -> None:
self.mock_resolver.resolve_service.side_effect = generate_resolve_service([])
self.reactor.lookups["testserv"] = "1.2.3.4"

test_d = self._make_get_request(b"matrix://testserv/foo/bar")
test_d = self._make_get_request(b"matrix-federation://testserv/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -780,7 +780,7 @@ def test_get_well_known(self) -> None:
self.reactor.lookups["testserv"] = "1.2.3.4"
self.reactor.lookups["target-server"] = "1::f"

test_d = self._make_get_request(b"matrix://testserv/foo/bar")
test_d = self._make_get_request(b"matrix-federation://testserv/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -844,7 +844,7 @@ def test_get_well_known_redirect(self) -> None:
self.reactor.lookups["testserv"] = "1.2.3.4"
self.reactor.lookups["target-server"] = "1::f"

test_d = self._make_get_request(b"matrix://testserv/foo/bar")
test_d = self._make_get_request(b"matrix-federation://testserv/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -933,7 +933,7 @@ def test_get_invalid_well_known(self) -> None:
self.mock_resolver.resolve_service.side_effect = generate_resolve_service([])
self.reactor.lookups["testserv"] = "1.2.3.4"

test_d = self._make_get_request(b"matrix://testserv/foo/bar")
test_d = self._make_get_request(b"matrix-federation://testserv/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -1009,7 +1009,7 @@ def test_get_well_known_unsigned_cert(self) -> None:
),
)

test_d = agent.request(b"GET", b"matrix://testserv/foo/bar")
test_d = agent.request(b"GET", b"matrix-federation://testserv/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -1042,7 +1042,7 @@ def test_get_hostname_srv(self) -> None:
)
self.reactor.lookups["srvtarget"] = "1.2.3.4"

test_d = self._make_get_request(b"matrix://testserv/foo/bar")
test_d = self._make_get_request(b"matrix-federation://testserv/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -1082,7 +1082,7 @@ def test_get_well_known_srv(self) -> None:
self.reactor.lookups["testserv"] = "1.2.3.4"
self.reactor.lookups["srvtarget"] = "5.6.7.8"

test_d = self._make_get_request(b"matrix://testserv/foo/bar")
test_d = self._make_get_request(b"matrix-federation://testserv/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -1143,7 +1143,9 @@ def test_idna_servername(self) -> None:
self.reactor.lookups["xn--bcher-kva.com"] = "1.2.3.4"

# this is idna for bücher.com
test_d = self._make_get_request(b"matrix://xn--bcher-kva.com/foo/bar")
test_d = self._make_get_request(
b"matrix-federation://xn--bcher-kva.com/foo/bar"
)

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -1204,7 +1206,9 @@ def test_idna_srv_target(self) -> None:
)
self.reactor.lookups["xn--trget-3qa.com"] = "1.2.3.4"

test_d = self._make_get_request(b"matrix://xn--bcher-kva.com/foo/bar")
test_d = self._make_get_request(
b"matrix-federation://xn--bcher-kva.com/foo/bar"
)

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down Expand Up @@ -1411,7 +1415,7 @@ def test_srv_fallbacks(self) -> None:
)
self.reactor.lookups["target.com"] = "1.2.3.4"

test_d = self._make_get_request(b"matrix://testserv/foo/bar")
test_d = self._make_get_request(b"matrix-federation://testserv/foo/bar")

# Nothing happened yet
self.assertNoResult(test_d)
Expand Down