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

Commit

Permalink
Update federation routing logic to check .well-known before SRV
Browse files Browse the repository at this point in the history
  • Loading branch information
richvdh committed Jan 31, 2019
1 parent 85129d7 commit d428b46
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 35 deletions.
1 change: 1 addition & 0 deletions changelog.d/4539.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update federation routing logic to check .well-known before SRV
10 changes: 5 additions & 5 deletions synapse/http/federation/matrix_federation_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,7 @@ def _route_matrix_uri(self, parsed_uri, lookup_well_known=True):
target_port=parsed_uri.port,
))

# try a SRV lookup
service_name = b"_matrix._tcp.%s" % (parsed_uri.host,)
server_list = yield self._srv_resolver.resolve_service(service_name)

if not server_list and lookup_well_known:
if lookup_well_known:
# try a .well-known lookup
well_known_server = yield self._get_well_known(parsed_uri.host)

Expand Down Expand Up @@ -250,6 +246,10 @@ def _route_matrix_uri(self, parsed_uri, lookup_well_known=True):
res = yield self._route_matrix_uri(new_uri, lookup_well_known=False)
defer.returnValue(res)

# try a SRV lookup
service_name = b"_matrix._tcp.%s" % (parsed_uri.host,)
server_list = yield self._srv_resolver.resolve_service(service_name)

if not server_list:
target_host = parsed_uri.host
port = 8448
Expand Down
51 changes: 21 additions & 30 deletions tests/http/federation/test_matrix_federation_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,8 @@ def test_get_no_srv_no_well_known(self):
# Nothing happened yet
self.assertNoResult(test_d)

self.mock_resolver.resolve_service.assert_called_once_with(
b"_matrix._tcp.testserv",
)
# No SRV record lookup yet
self.mock_resolver.resolve_service.assert_not_called()

# there should be an attempt to connect on port 443 for the .well-known
clients = self.reactor.tcpClients
Expand All @@ -376,6 +375,11 @@ def test_get_no_srv_no_well_known(self):
# .well-known request fails.
self.reactor.pump((0.4,))

# now there should be a SRV lookup
self.mock_resolver.resolve_service.assert_called_once_with(
b"_matrix._tcp.testserv",
)

# we should fall back to a direct connection
self.assertEqual(len(clients), 2)
(host, port, client_factory, _timeout, _bindAddress) = clients[1]
Expand Down Expand Up @@ -403,8 +407,7 @@ def test_get_no_srv_no_well_known(self):
self.successResultOf(test_d)

def test_get_well_known(self):
"""Test the behaviour when the server name has no port and no SRV record, but
the .well-known redirects elsewhere
"""Test the behaviour when the .well-known redirects elsewhere
"""

self.mock_resolver.resolve_service.side_effect = lambda _: []
Expand All @@ -416,11 +419,6 @@ def test_get_well_known(self):
# Nothing happened yet
self.assertNoResult(test_d)

self.mock_resolver.resolve_service.assert_called_once_with(
b"_matrix._tcp.testserv",
)
self.mock_resolver.resolve_service.reset_mock()

# there should be an attempt to connect on port 443 for the .well-known
clients = self.reactor.tcpClients
self.assertEqual(len(clients), 1)
Expand All @@ -432,7 +430,7 @@ def test_get_well_known(self):
client_factory, expected_sni=b"testserv", target_server=b"target-server",
)

# there should be another SRV lookup
# there should be a SRV lookup
self.mock_resolver.resolve_service.assert_called_once_with(
b"_matrix._tcp.target-server",
)
Expand Down Expand Up @@ -483,11 +481,6 @@ def test_get_well_known_redirect(self):
# Nothing happened yet
self.assertNoResult(test_d)

self.mock_resolver.resolve_service.assert_called_once_with(
b"_matrix._tcp.testserv",
)
self.mock_resolver.resolve_service.reset_mock()

# there should be an attempt to connect on port 443 for the .well-known
clients = self.reactor.tcpClients
self.assertEqual(len(clients), 1)
Expand Down Expand Up @@ -529,7 +522,7 @@ def test_get_well_known_redirect(self):

self.reactor.pump((0.1, ))

# there should be another SRV lookup
# there should be a SRV lookup
self.mock_resolver.resolve_service.assert_called_once_with(
b"_matrix._tcp.target-server",
)
Expand Down Expand Up @@ -581,6 +574,7 @@ def test_get_hostname_srv(self):
# Nothing happened yet
self.assertNoResult(test_d)

# the request for a .well-known will have failed with a DNS lookup error.
self.mock_resolver.resolve_service.assert_called_once_with(
b"_matrix._tcp.testserv",
)
Expand Down Expand Up @@ -613,11 +607,9 @@ def test_get_hostname_srv(self):
self.successResultOf(test_d)

def test_get_well_known_srv(self):
"""Test the behaviour when the server name has no port and no SRV record, but
the .well-known redirects to a place where there is a SRV.
"""Test the behaviour when the .well-known redirects to a place where there
is a SRV.
"""

self.mock_resolver.resolve_service.side_effect = lambda _: []
self.reactor.lookups["testserv"] = "1.2.3.4"
self.reactor.lookups["srvtarget"] = "5.6.7.8"

Expand All @@ -626,11 +618,6 @@ def test_get_well_known_srv(self):
# Nothing happened yet
self.assertNoResult(test_d)

self.mock_resolver.resolve_service.assert_called_once_with(
b"_matrix._tcp.testserv",
)
self.mock_resolver.resolve_service.reset_mock()

# there should be an attempt to connect on port 443 for the .well-known
clients = self.reactor.tcpClients
self.assertEqual(len(clients), 1)
Expand All @@ -646,7 +633,7 @@ def test_get_well_known_srv(self):
client_factory, expected_sni=b"testserv", target_server=b"target-server",
)

# there should be another SRV lookup
# there should be a SRV lookup
self.mock_resolver.resolve_service.assert_called_once_with(
b"_matrix._tcp.target-server",
)
Expand Down Expand Up @@ -691,9 +678,8 @@ def test_idna_servername(self):
# Nothing happened yet
self.assertNoResult(test_d)

self.mock_resolver.resolve_service.assert_called_once_with(
b"_matrix._tcp.xn--bcher-kva.com",
)
# No SRV record lookup yet
self.mock_resolver.resolve_service.assert_not_called()

# there should be an attempt to connect on port 443 for the .well-known
clients = self.reactor.tcpClients
Expand All @@ -709,6 +695,11 @@ def test_idna_servername(self):
# .well-known request fails.
self.reactor.pump((0.4,))

# now there should have been a SRV lookup
self.mock_resolver.resolve_service.assert_called_once_with(
b"_matrix._tcp.xn--bcher-kva.com",
)

# We should fall back to port 8448
clients = self.reactor.tcpClients
self.assertEqual(len(clients), 2)
Expand Down

0 comments on commit d428b46

Please sign in to comment.