Don't answer expensive federation requests for rooms we no longer belong to
This includes `/state`, `/state_ids`, `/get_missing_events` and `/backfill`.
This should fix
MODIFY
federationapi/routing/backfill.go
federationapi/routing/backfill.go
@@ -51,6 +51,12 @@ func Backfill(
}
}
+ // If we don't think we belong to this room then don't waste the effort
+ // responding to expensive requests for it.
+ if err := ErrorIfLocalServerNotInRoom(httpReq.Context(), rsAPI, roomID); err != nil {
+ return *err
+ }
+
// Check if all of the required parameters are there.
eIDs, exists = httpReq.URL.Query()["v"]
if !exists {

MODIFY
federationapi/routing/eventauth.go
federationapi/routing/eventauth.go
@@ -30,6 +30,12 @@ func GetEventAuth(
roomID string,
eventID string,
) util.JSONResponse {
+ // If we don't think we belong to this room then don't waste the effort
+ // responding to expensive requests for it.
+ if err := ErrorIfLocalServerNotInRoom(ctx, rsAPI, roomID); err != nil {
+ return *err
+ }
+
event, resErr := fetchEvent(ctx, rsAPI, eventID)
if resErr != nil {
return *resErr

MODIFY
federationapi/routing/missingevents.go
federationapi/routing/missingevents.go
@@ -45,6 +45,12 @@ func GetMissingEvents(
}
}
+ // If we don't think we belong to this room then don't waste the effort
+ // responding to expensive requests for it.
+ if err := ErrorIfLocalServerNotInRoom(httpReq.Context(), rsAPI, roomID); err != nil {
+ return *err
+ }
+
var eventsResponse api.QueryMissingEventsResponse
if err := rsAPI.QueryMissingEvents(
httpReq.Context(), &api.QueryMissingEventsRequest{

MODIFY
federationapi/routing/routing.go
federationapi/routing/routing.go
package routing
import (
+ "context"
+ "fmt"
"net/http"
"github.com/gorilla/mux"
@@ -24,6 +26,7 @@ import (
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/httputil"
keyserverAPI "github.com/matrix-org/dendrite/keyserver/api"
+ "github.com/matrix-org/dendrite/roomserver/api"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/setup/config"
userapi "github.com/matrix-org/dendrite/userapi/api"
@@ -491,3 +494,27 @@ func Setup(
}),
).Methods(http.MethodGet)
}
+
+func ErrorIfLocalServerNotInRoom(
+ ctx context.Context,
+ rsAPI api.RoomserverInternalAPI,
+ roomID string,
+) *util.JSONResponse {
+ // Check if we think we're in this room. If we aren't then
+ // we won't waste CPU cycles serving this request.
+ joinedReq := &api.QueryServerJoinedToRoomRequest{
+ RoomID: roomID,
+ }
+ joinedRes := &api.QueryServerJoinedToRoomResponse{}
+ if err := rsAPI.QueryServerJoinedToRoom(ctx, joinedReq, joinedRes); err != nil {
+ res := util.ErrorResponse(err)
+ return &res
+ }
+ if !joinedRes.IsInRoom {
+ return &util.JSONResponse{
+ Code: http.StatusNotFound,
+ JSON: jsonerror.NotFound(fmt.Sprintf("This server is not joined to room %s", roomID)),
+ }
+ }
+ return nil
+}

MODIFY
federationapi/routing/state.go
federationapi/routing/state.go
@@ -101,6 +101,12 @@ func getState(
roomID string,
eventID string,
) (stateEvents, authEvents []*gomatrixserverlib.HeaderedEvent, errRes *util.JSONResponse) {
+ // If we don't think we belong to this room then don't waste the effort
+ // responding to expensive requests for it.
+ if err := ErrorIfLocalServerNotInRoom(ctx, rsAPI, roomID); err != nil {
+ return nil, nil, err
+ }
+
event, resErr := fetchEvent(ctx, rsAPI, eventID)
if resErr != nil {
return nil, nil, resErr

Don't answer expensive federation requests for rooms we no longer belong to (#2398)

This includes `/state`, `/state_ids`, `/get_missing_events` and `/backfill`.

This should fix #2396.