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.
This commit is contained in:
Neil Alexander 2022-04-28 11:45:56 +01:00 committed by GitHub
parent 2ff75b7c80
commit 6deb10f3f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 0 deletions

View file

@ -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. // Check if all of the required parameters are there.
eIDs, exists = httpReq.URL.Query()["v"] eIDs, exists = httpReq.URL.Query()["v"]
if !exists { if !exists {

View file

@ -30,6 +30,12 @@ func GetEventAuth(
roomID string, roomID string,
eventID string, eventID string,
) util.JSONResponse { ) 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) event, resErr := fetchEvent(ctx, rsAPI, eventID)
if resErr != nil { if resErr != nil {
return *resErr return *resErr

View file

@ -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 var eventsResponse api.QueryMissingEventsResponse
if err := rsAPI.QueryMissingEvents( if err := rsAPI.QueryMissingEvents(
httpReq.Context(), &api.QueryMissingEventsRequest{ httpReq.Context(), &api.QueryMissingEventsRequest{

View file

@ -15,6 +15,8 @@
package routing package routing
import ( import (
"context"
"fmt"
"net/http" "net/http"
"github.com/gorilla/mux" "github.com/gorilla/mux"
@ -24,6 +26,7 @@ import (
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/httputil" "github.com/matrix-org/dendrite/internal/httputil"
keyserverAPI "github.com/matrix-org/dendrite/keyserver/api" keyserverAPI "github.com/matrix-org/dendrite/keyserver/api"
"github.com/matrix-org/dendrite/roomserver/api"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/setup/config" "github.com/matrix-org/dendrite/setup/config"
userapi "github.com/matrix-org/dendrite/userapi/api" userapi "github.com/matrix-org/dendrite/userapi/api"
@ -491,3 +494,27 @@ func Setup(
}), }),
).Methods(http.MethodGet) ).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
}

View file

@ -101,6 +101,12 @@ func getState(
roomID string, roomID string,
eventID string, eventID string,
) (stateEvents, authEvents []*gomatrixserverlib.HeaderedEvent, errRes *util.JSONResponse) { ) (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) event, resErr := fetchEvent(ctx, rsAPI, eventID)
if resErr != nil { if resErr != nil {
return nil, nil, resErr return nil, nil, resErr