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

Commit c2db659

Browse files
authored
Fix a bug in the federation API which could cause occasional "Failed to get PDU" errors (#7089).
1 parent a319cb1 commit c2db659

File tree

4 files changed

+22
-30
lines changed

4 files changed

+22
-30
lines changed

changelog.d/7089.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a bug in the federation API which could cause occasional "Failed to get PDU" errors.

synapse/federation/federation_base.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,7 @@
2525

2626
from synapse.api.constants import MAX_DEPTH, EventTypes, Membership
2727
from synapse.api.errors import Codes, SynapseError
28-
from synapse.api.room_versions import (
29-
KNOWN_ROOM_VERSIONS,
30-
EventFormatVersions,
31-
RoomVersion,
32-
)
28+
from synapse.api.room_versions import EventFormatVersions, RoomVersion
3329
from synapse.crypto.event_signing import check_event_content_hash
3430
from synapse.crypto.keyring import Keyring
3531
from synapse.events import EventBase, make_event_from_dict
@@ -55,13 +51,15 @@ def __init__(self, hs):
5551
self.store = hs.get_datastore()
5652
self._clock = hs.get_clock()
5753

58-
def _check_sigs_and_hash(self, room_version: str, pdu: EventBase) -> Deferred:
54+
def _check_sigs_and_hash(
55+
self, room_version: RoomVersion, pdu: EventBase
56+
) -> Deferred:
5957
return make_deferred_yieldable(
6058
self._check_sigs_and_hashes(room_version, [pdu])[0]
6159
)
6260

6361
def _check_sigs_and_hashes(
64-
self, room_version: str, pdus: List[EventBase]
62+
self, room_version: RoomVersion, pdus: List[EventBase]
6563
) -> List[Deferred]:
6664
"""Checks that each of the received events is correctly signed by the
6765
sending server.
@@ -146,7 +144,7 @@ class PduToCheckSig(
146144

147145

148146
def _check_sigs_on_pdus(
149-
keyring: Keyring, room_version: str, pdus: Iterable[EventBase]
147+
keyring: Keyring, room_version: RoomVersion, pdus: Iterable[EventBase]
150148
) -> List[Deferred]:
151149
"""Check that the given events are correctly signed
152150
@@ -191,10 +189,6 @@ def _check_sigs_on_pdus(
191189
for p in pdus
192190
]
193191

194-
v = KNOWN_ROOM_VERSIONS.get(room_version)
195-
if not v:
196-
raise RuntimeError("Unrecognized room version %s" % (room_version,))
197-
198192
# First we check that the sender event is signed by the sender's domain
199193
# (except if its a 3pid invite, in which case it may be sent by any server)
200194
pdus_to_check_sender = [p for p in pdus_to_check if not _is_invite_via_3pid(p.pdu)]
@@ -204,7 +198,7 @@ def _check_sigs_on_pdus(
204198
(
205199
p.sender_domain,
206200
p.redacted_pdu_json,
207-
p.pdu.origin_server_ts if v.enforce_key_validity else 0,
201+
p.pdu.origin_server_ts if room_version.enforce_key_validity else 0,
208202
p.pdu.event_id,
209203
)
210204
for p in pdus_to_check_sender
@@ -227,7 +221,7 @@ def sender_err(e, pdu_to_check):
227221
# event id's domain (normally only the case for joins/leaves), and add additional
228222
# checks. Only do this if the room version has a concept of event ID domain
229223
# (ie, the room version uses old-style non-hash event IDs).
230-
if v.event_format == EventFormatVersions.V1:
224+
if room_version.event_format == EventFormatVersions.V1:
231225
pdus_to_check_event_id = [
232226
p
233227
for p in pdus_to_check
@@ -239,7 +233,7 @@ def sender_err(e, pdu_to_check):
239233
(
240234
get_domain_from_id(p.pdu.event_id),
241235
p.redacted_pdu_json,
242-
p.pdu.origin_server_ts if v.enforce_key_validity else 0,
236+
p.pdu.origin_server_ts if room_version.enforce_key_validity else 0,
243237
p.pdu.event_id,
244238
)
245239
for p in pdus_to_check_event_id

synapse/federation/federation_client.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,7 @@ async def backfill(
220220
# FIXME: We should handle signature failures more gracefully.
221221
pdus[:] = await make_deferred_yieldable(
222222
defer.gatherResults(
223-
self._check_sigs_and_hashes(room_version.identifier, pdus),
224-
consumeErrors=True,
223+
self._check_sigs_and_hashes(room_version, pdus), consumeErrors=True,
225224
).addErrback(unwrapFirstError)
226225
)
227226

@@ -291,9 +290,7 @@ async def get_pdu(
291290
pdu = pdu_list[0]
292291

293292
# Check signatures are correct.
294-
signed_pdu = await self._check_sigs_and_hash(
295-
room_version.identifier, pdu
296-
)
293+
signed_pdu = await self._check_sigs_and_hash(room_version, pdu)
297294

298295
break
299296

@@ -350,7 +347,7 @@ async def _check_sigs_and_hash_and_fetch(
350347
self,
351348
origin: str,
352349
pdus: List[EventBase],
353-
room_version: str,
350+
room_version: RoomVersion,
354351
outlier: bool = False,
355352
include_none: bool = False,
356353
) -> List[EventBase]:
@@ -396,7 +393,7 @@ def handle_check_result(pdu: EventBase, deferred: Deferred):
396393
self.get_pdu(
397394
destinations=[pdu.origin],
398395
event_id=pdu.event_id,
399-
room_version=room_version, # type: ignore
396+
room_version=room_version,
400397
outlier=outlier,
401398
timeout=10000,
402399
)
@@ -434,7 +431,7 @@ async def get_event_auth(self, destination, room_id, event_id):
434431
]
435432

436433
signed_auth = await self._check_sigs_and_hash_and_fetch(
437-
destination, auth_chain, outlier=True, room_version=room_version.identifier
434+
destination, auth_chain, outlier=True, room_version=room_version
438435
)
439436

440437
signed_auth.sort(key=lambda e: e.depth)
@@ -661,7 +658,7 @@ async def send_request(destination) -> Dict[str, Any]:
661658
destination,
662659
list(pdus.values()),
663660
outlier=True,
664-
room_version=room_version.identifier,
661+
room_version=room_version,
665662
)
666663

667664
valid_pdus_map = {p.event_id: p for p in valid_pdus}
@@ -756,7 +753,7 @@ async def send_invite(
756753
pdu = event_from_pdu_json(pdu_dict, room_version)
757754

758755
# Check signatures are correct.
759-
pdu = await self._check_sigs_and_hash(room_version.identifier, pdu)
756+
pdu = await self._check_sigs_and_hash(room_version, pdu)
760757

761758
# FIXME: We should handle signature failures more gracefully.
762759

@@ -948,7 +945,7 @@ async def get_missing_events(
948945
]
949946

950947
signed_events = await self._check_sigs_and_hash_and_fetch(
951-
destination, events, outlier=False, room_version=room_version.identifier
948+
destination, events, outlier=False, room_version=room_version
952949
)
953950
except HttpResponseException as e:
954951
if not e.code == 400:

synapse/federation/federation_server.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ async def on_invite_request(
409409
pdu = event_from_pdu_json(content, room_version)
410410
origin_host, _ = parse_server_name(origin)
411411
await self.check_server_matches_acl(origin_host, pdu.room_id)
412-
pdu = await self._check_sigs_and_hash(room_version.identifier, pdu)
412+
pdu = await self._check_sigs_and_hash(room_version, pdu)
413413
ret_pdu = await self.handler.on_invite_request(origin, pdu, room_version)
414414
time_now = self._clock.time_msec()
415415
return {"event": ret_pdu.get_pdu_json(time_now)}
@@ -425,7 +425,7 @@ async def on_send_join_request(self, origin, content, room_id):
425425

426426
logger.debug("on_send_join_request: pdu sigs: %s", pdu.signatures)
427427

428-
pdu = await self._check_sigs_and_hash(room_version.identifier, pdu)
428+
pdu = await self._check_sigs_and_hash(room_version, pdu)
429429

430430
res_pdus = await self.handler.on_send_join_request(origin, pdu)
431431
time_now = self._clock.time_msec()
@@ -455,7 +455,7 @@ async def on_send_leave_request(self, origin, content, room_id):
455455

456456
logger.debug("on_send_leave_request: pdu sigs: %s", pdu.signatures)
457457

458-
pdu = await self._check_sigs_and_hash(room_version.identifier, pdu)
458+
pdu = await self._check_sigs_and_hash(room_version, pdu)
459459

460460
await self.handler.on_send_leave_request(origin, pdu)
461461
return {}
@@ -611,7 +611,7 @@ async def _handle_received_pdu(self, origin, pdu):
611611
logger.info("Accepting join PDU %s from %s", pdu.event_id, origin)
612612

613613
# We've already checked that we know the room version by this point
614-
room_version = await self.store.get_room_version_id(pdu.room_id)
614+
room_version = await self.store.get_room_version(pdu.room_id)
615615

616616
# Check signature.
617617
try:

0 commit comments

Comments
 (0)