summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2019-06-03 09:56:45 +0100
committerErik Johnston <erik@matrix.org>2019-06-03 09:56:45 +0100
commit220a733d7379be88514f7681ec37388755d4e612 (patch)
treef87dfde2e72688127aa0cd38de1e4f1d92febc02 /synapse
parentMerge pull request #5309 from matrix-org/rav/limit_displayname_length (diff)
downloadsynapse-220a733d7379be88514f7681ec37388755d4e612.tar.xz
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
Diffstat (limited to 'synapse')
-rw-r--r--synapse/handlers/federation.py50
1 files changed, 38 insertions, 12 deletions
diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py
index cf4fad7de0..fa735efedd 100644
--- a/synapse/handlers/federation.py
+++ b/synapse/handlers/federation.py
@@ -35,6 +35,7 @@ from synapse.api.errors import (
     CodeMessageException,
     FederationDeniedError,
     FederationError,
+    RequestSendFailed,
     StoreError,
     SynapseError,
 )
@@ -2027,9 +2028,15 @@ class FederationHandler(BaseHandler):
         """
         room_version = yield self.store.get_room_version(event.room_id)
 
-        yield self._update_auth_events_and_context_for_auth(
-            origin, event, context, auth_events
-        )
+        try:
+            yield self._update_auth_events_and_context_for_auth(
+                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:
             self.auth.check(room_version, event, auth_events=auth_events)
         except AuthError as e:
@@ -2042,6 +2049,15 @@ class FederationHandler(BaseHandler):
     ):
         """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:
             origin (str):
             event (synapse.events.EventBase):
@@ -2088,9 +2104,14 @@ class FederationHandler(BaseHandler):
                 missing_auth,
             )
             try:
-                remote_auth_chain = yield self.federation_client.get_event_auth(
-                    origin, event.room_id, event.event_id
-                )
+                try:
+                    remote_auth_chain = yield self.federation_client.get_event_auth(
+                        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(
                     [e.event_id for e in remote_auth_chain]
@@ -2236,12 +2257,17 @@ class FederationHandler(BaseHandler):
 
         try:
             # 2. Get remote difference.
-            result = yield self.federation_client.query_auth(
-                origin,
-                event.room_id,
-                event.event_id,
-                local_auth_chain,
-            )
+            try:
+                result = yield self.federation_client.query_auth(
+                    origin,
+                    event.room_id,
+                    event.event_id,
+                    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(
                 [e.event_id for e in result["auth_chain"]]