mirror of
https://github.com/element-hq/synapse
synced 2024-08-31 04:40:21 +00:00
Fix handling of failures when calling /event_auth.
When processing an incoming event over federation, we may try and resolve any unexpected differences in auth events. This is a non-essential process and so should not stop the processing of the event if it fails (e.g. due to the remote disappearing or not implementing the necessary endpoints). Fixes #3330
This commit is contained in:
parent
d828d1dc57
commit
220a733d73
1 changed files with 38 additions and 12 deletions
|
@ -35,6 +35,7 @@ from synapse.api.errors import (
|
||||||
CodeMessageException,
|
CodeMessageException,
|
||||||
FederationDeniedError,
|
FederationDeniedError,
|
||||||
FederationError,
|
FederationError,
|
||||||
|
RequestSendFailed,
|
||||||
StoreError,
|
StoreError,
|
||||||
SynapseError,
|
SynapseError,
|
||||||
)
|
)
|
||||||
|
@ -2027,9 +2028,15 @@ class FederationHandler(BaseHandler):
|
||||||
"""
|
"""
|
||||||
room_version = yield self.store.get_room_version(event.room_id)
|
room_version = yield self.store.get_room_version(event.room_id)
|
||||||
|
|
||||||
|
try:
|
||||||
yield self._update_auth_events_and_context_for_auth(
|
yield self._update_auth_events_and_context_for_auth(
|
||||||
origin, event, context, auth_events
|
origin, event, context, auth_events
|
||||||
)
|
)
|
||||||
|
except Exception:
|
||||||
|
# We don't really mind if the above fails, so lets not fail
|
||||||
|
# processing if it does.
|
||||||
|
logger.exception("Failed to call _update_auth_events_and_context_for_auth")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.auth.check(room_version, event, auth_events=auth_events)
|
self.auth.check(room_version, event, auth_events=auth_events)
|
||||||
except AuthError as e:
|
except AuthError as e:
|
||||||
|
@ -2042,6 +2049,15 @@ class FederationHandler(BaseHandler):
|
||||||
):
|
):
|
||||||
"""Helper for do_auth. See there for docs.
|
"""Helper for do_auth. See there for docs.
|
||||||
|
|
||||||
|
Checks whether a given event has the expected auth events. If it
|
||||||
|
doesn't then we talk to the remote server to compare state to see if
|
||||||
|
we can come to a consensus (e.g. if one server missed some valid
|
||||||
|
state).
|
||||||
|
|
||||||
|
This attempts to resovle any potential divergence of state between
|
||||||
|
servers, but is not essential and so failures should not block further
|
||||||
|
processing of the event.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
origin (str):
|
origin (str):
|
||||||
event (synapse.events.EventBase):
|
event (synapse.events.EventBase):
|
||||||
|
@ -2087,10 +2103,15 @@ class FederationHandler(BaseHandler):
|
||||||
"auth_events contains unknown events: %s",
|
"auth_events contains unknown events: %s",
|
||||||
missing_auth,
|
missing_auth,
|
||||||
)
|
)
|
||||||
|
try:
|
||||||
try:
|
try:
|
||||||
remote_auth_chain = yield self.federation_client.get_event_auth(
|
remote_auth_chain = yield self.federation_client.get_event_auth(
|
||||||
origin, event.room_id, event.event_id
|
origin, event.room_id, event.event_id
|
||||||
)
|
)
|
||||||
|
except RequestSendFailed:
|
||||||
|
# The other side isn't around or doesn't implement the
|
||||||
|
# endpoint, so lets just bail out.
|
||||||
|
return
|
||||||
|
|
||||||
seen_remotes = yield self.store.have_seen_events(
|
seen_remotes = yield self.store.have_seen_events(
|
||||||
[e.event_id for e in remote_auth_chain]
|
[e.event_id for e in remote_auth_chain]
|
||||||
|
@ -2236,12 +2257,17 @@ class FederationHandler(BaseHandler):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 2. Get remote difference.
|
# 2. Get remote difference.
|
||||||
|
try:
|
||||||
result = yield self.federation_client.query_auth(
|
result = yield self.federation_client.query_auth(
|
||||||
origin,
|
origin,
|
||||||
event.room_id,
|
event.room_id,
|
||||||
event.event_id,
|
event.event_id,
|
||||||
local_auth_chain,
|
local_auth_chain,
|
||||||
)
|
)
|
||||||
|
except RequestSendFailed:
|
||||||
|
# The other side isn't around or doesn't implement the
|
||||||
|
# endpoint, so lets just bail out.
|
||||||
|
return
|
||||||
|
|
||||||
seen_remotes = yield self.store.have_seen_events(
|
seen_remotes = yield self.store.have_seen_events(
|
||||||
[e.event_id for e in result["auth_chain"]]
|
[e.event_id for e in result["auth_chain"]]
|
||||||
|
|
Loading…
Reference in a new issue