mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-12-15 07:42:49 -05:00
handle federation not telling us about prev_events
This commit is contained in:
parent
cd6bcdaf87
commit
77078d6c8e
4 changed files with 301 additions and 27 deletions
|
|
@ -44,6 +44,7 @@ from synapse.util.frozenutils import unfreeze
|
|||
from synapse.crypto.event_signing import (
|
||||
compute_event_signature, add_hashes_and_signatures,
|
||||
)
|
||||
from synapse.state import resolve_events_with_factory
|
||||
from synapse.types import UserID, get_domain_from_id
|
||||
|
||||
from synapse.events.utils import prune_event
|
||||
|
|
@ -89,7 +90,9 @@ class FederationHandler(BaseHandler):
|
|||
|
||||
@defer.inlineCallbacks
|
||||
@log_function
|
||||
def on_receive_pdu(self, origin, pdu, get_missing=True):
|
||||
def on_receive_pdu(
|
||||
self, origin, pdu, get_missing=True, sent_to_us_directly=False,
|
||||
):
|
||||
""" Process a PDU received via a federation /send/ transaction, or
|
||||
via backfill of missing prev_events
|
||||
|
||||
|
|
@ -163,7 +166,7 @@ class FederationHandler(BaseHandler):
|
|||
"Ignoring PDU %s for room %s from %s as we've left the room!",
|
||||
pdu.event_id, pdu.room_id, origin,
|
||||
)
|
||||
return
|
||||
defer.returnValue(None)
|
||||
|
||||
state = None
|
||||
|
||||
|
|
@ -225,26 +228,54 @@ class FederationHandler(BaseHandler):
|
|||
list(prevs - seen)[:5],
|
||||
)
|
||||
|
||||
if prevs - seen:
|
||||
logger.info(
|
||||
"Still missing %d events for room %r: %r...",
|
||||
len(prevs - seen), pdu.room_id, list(prevs - seen)[:5]
|
||||
if sent_to_us_directly and prevs - seen:
|
||||
# If they have sent it to us directly, and the server
|
||||
# isn't telling us about the auth events that it's
|
||||
# made a message referencing, we explode
|
||||
raise FederationError(
|
||||
"ERROR",
|
||||
403,
|
||||
("Your server isn't divulging details about prev_events "
|
||||
"referenced in this event."),
|
||||
affected=pdu.event_id,
|
||||
)
|
||||
fetch_state = True
|
||||
elif prevs - seen:
|
||||
# If we're walking back up the chain to fetch it, then
|
||||
# try and find the states. If we can't get the states,
|
||||
# discard it.
|
||||
state_groups = []
|
||||
auth_chains = set()
|
||||
try:
|
||||
# Get the ones we know about
|
||||
ours = yield self.store.get_state_groups(pdu.room_id, list(seen))
|
||||
state_groups.append(ours)
|
||||
|
||||
if fetch_state:
|
||||
# We need to get the state at this event, since we haven't
|
||||
# processed all the prev events.
|
||||
logger.debug(
|
||||
"_handle_new_pdu getting state for %s",
|
||||
pdu.room_id
|
||||
)
|
||||
try:
|
||||
state, auth_chain = yield self.replication_layer.get_state_for_room(
|
||||
origin, pdu.room_id, pdu.event_id,
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Failed to get state for event: %s", pdu.event_id)
|
||||
for p in prevs - seen:
|
||||
state, auth_chain = yield self.replication_layer.get_state_for_room(
|
||||
origin, pdu.room_id, p
|
||||
)
|
||||
auth_chains.update(auth_chain)
|
||||
state_group = {
|
||||
(x.type, x.state_key): x.event_id for x in state
|
||||
}
|
||||
state_groups.append(state_group)
|
||||
|
||||
def fetch(ev_ids):
|
||||
return self.store.get_events(
|
||||
ev_ids, get_prev_content=False, check_redacted=False,
|
||||
)
|
||||
|
||||
state = yield resolve_events_with_factory(state_groups, {pdu.event_id: pdu}, fetch)
|
||||
|
||||
state = yield self.store.get_events(state.values())
|
||||
state = state.values()
|
||||
except Exception:
|
||||
raise FederationError(
|
||||
"ERROR",
|
||||
403,
|
||||
"We can't get valid state history.",
|
||||
affected=pdu.event_id,
|
||||
)
|
||||
|
||||
yield self._process_received_pdu(
|
||||
origin,
|
||||
|
|
@ -322,11 +353,17 @@ class FederationHandler(BaseHandler):
|
|||
|
||||
for e in missing_events:
|
||||
logger.info("Handling found event %s", e.event_id)
|
||||
yield self.on_receive_pdu(
|
||||
origin,
|
||||
e,
|
||||
get_missing=False
|
||||
)
|
||||
try:
|
||||
yield self.on_receive_pdu(
|
||||
origin,
|
||||
e,
|
||||
get_missing=False
|
||||
)
|
||||
except FederationError as e:
|
||||
if e.code == 403:
|
||||
logger.warn("Event %s failed history check.")
|
||||
else:
|
||||
raise
|
||||
|
||||
@log_function
|
||||
@defer.inlineCallbacks
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue