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
pull/5317/head
Erik Johnston 2019-06-03 09:56:45 +01:00
parent d828d1dc57
commit 220a733d73
1 changed files with 38 additions and 12 deletions

View File

@ -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"]]