Don't do regular federation if should be using mailserver

This commit is contained in:
Devon Hudson 2022-11-29 15:52:21 -07:00
parent d4dde15113
commit 2df4b0750e
No known key found for this signature in database
GPG key ID: CD06B18E77F6A628
2 changed files with 43 additions and 12 deletions

View file

@ -24,6 +24,11 @@ func (r *FederationInternalAPI) PerformDirectoryLookup(
request *api.PerformDirectoryLookupRequest, request *api.PerformDirectoryLookupRequest,
response *api.PerformDirectoryLookupResponse, response *api.PerformDirectoryLookupResponse,
) (err error) { ) (err error) {
stats := r.statistics.ForServer(request.ServerName)
if stats.AssumedOffline() && len(stats.KnownMailservers()) > 0 {
return fmt.Errorf("not performing federation since server is assumed offline with known mailboxes")
}
dir, err := r.federation.LookupRoomAlias( dir, err := r.federation.LookupRoomAlias(
ctx, ctx,
request.ServerName, request.ServerName,
@ -143,6 +148,11 @@ func (r *FederationInternalAPI) performJoinUsingServer(
supportedVersions []gomatrixserverlib.RoomVersion, supportedVersions []gomatrixserverlib.RoomVersion,
unsigned map[string]interface{}, unsigned map[string]interface{},
) error { ) error {
stats := r.statistics.ForServer(serverName)
if stats.AssumedOffline() && len(stats.KnownMailservers()) > 0 {
return fmt.Errorf("not performing federation since server is assumed offline with known mailboxes")
}
// Try to perform a make_join using the information supplied in the // Try to perform a make_join using the information supplied in the
// request. // request.
respMakeJoin, err := r.federation.MakeJoin( respMakeJoin, err := r.federation.MakeJoin(
@ -398,6 +408,11 @@ func (r *FederationInternalAPI) performOutboundPeekUsingServer(
serverName gomatrixserverlib.ServerName, serverName gomatrixserverlib.ServerName,
supportedVersions []gomatrixserverlib.RoomVersion, supportedVersions []gomatrixserverlib.RoomVersion,
) error { ) error {
stats := r.statistics.ForServer(serverName)
if stats.AssumedOffline() && len(stats.KnownMailservers()) > 0 {
return fmt.Errorf("not performing federation since server is assumed offline with known mailboxes")
}
// create a unique ID for this peek. // create a unique ID for this peek.
// for now we just use the room ID again. In future, if we ever // for now we just use the room ID again. In future, if we ever
// support concurrent peeks to the same room with different filters // support concurrent peeks to the same room with different filters
@ -501,6 +516,11 @@ func (r *FederationInternalAPI) PerformLeave(
// Try each server that we were provided until we land on one that // Try each server that we were provided until we land on one that
// successfully completes the make-leave send-leave dance. // successfully completes the make-leave send-leave dance.
for _, serverName := range request.ServerNames { for _, serverName := range request.ServerNames {
stats := r.statistics.ForServer(serverName)
if stats.AssumedOffline() && len(stats.KnownMailservers()) > 0 {
continue
}
// Try to perform a make_leave using the information supplied in the // Try to perform a make_leave using the information supplied in the
// request. // request.
respMakeLeave, err := r.federation.MakeLeave( respMakeLeave, err := r.federation.MakeLeave(
@ -594,6 +614,11 @@ func (r *FederationInternalAPI) PerformInvite(
return fmt.Errorf("gomatrixserverlib.SplitID: %w", err) return fmt.Errorf("gomatrixserverlib.SplitID: %w", err)
} }
stats := r.statistics.ForServer(destination)
if stats.AssumedOffline() && len(stats.KnownMailservers()) > 0 {
return fmt.Errorf("not performing federation since server is assumed offline with known mailboxes")
}
logrus.WithFields(logrus.Fields{ logrus.WithFields(logrus.Fields{
"event_id": request.Event.EventID(), "event_id": request.Event.EventID(),
"user_id": *request.Event.StateKey(), "user_id": *request.Event.StateKey(),

View file

@ -65,8 +65,9 @@ func (s *Statistics) ForServer(serverName gomatrixserverlib.ServerName) *ServerS
if !found { if !found {
s.mutex.Lock() s.mutex.Lock()
server = &ServerStatistics{ server = &ServerStatistics{
statistics: s, statistics: s,
serverName: serverName, serverName: serverName,
knownMailservers: []gomatrixserverlib.ServerName{},
} }
s.servers[serverName] = server s.servers[serverName] = server
s.mutex.Unlock() s.mutex.Unlock()
@ -85,16 +86,17 @@ func (s *Statistics) ForServer(serverName gomatrixserverlib.ServerName) *ServerS
// many times we failed etc. It also manages the backoff time and black- // many times we failed etc. It also manages the backoff time and black-
// listing a remote host if it remains uncooperative. // listing a remote host if it remains uncooperative.
type ServerStatistics struct { type ServerStatistics struct {
statistics *Statistics // statistics *Statistics //
serverName gomatrixserverlib.ServerName // serverName gomatrixserverlib.ServerName //
blacklisted atomic.Bool // is the node blacklisted blacklisted atomic.Bool // is the node blacklisted
assumedOffline atomic.Bool // is the node assumed to be offline assumedOffline atomic.Bool // is the node assumed to be offline
backoffStarted atomic.Bool // is the backoff started backoffStarted atomic.Bool // is the backoff started
backoffUntil atomic.Value // time.Time until this backoff interval ends backoffUntil atomic.Value // time.Time until this backoff interval ends
backoffCount atomic.Uint32 // number of times BackoffDuration has been called backoffCount atomic.Uint32 // number of times BackoffDuration has been called
successCounter atomic.Uint32 // how many times have we succeeded? successCounter atomic.Uint32 // how many times have we succeeded?
backoffNotifier func() // notifies destination queue when backoff completes backoffNotifier func() // notifies destination queue when backoff completes
notifierMutex sync.Mutex notifierMutex sync.Mutex
knownMailservers []gomatrixserverlib.ServerName
} }
const maxJitterMultiplier = 1.4 const maxJitterMultiplier = 1.4
@ -245,3 +247,7 @@ func (s *ServerStatistics) RemoveBlacklist() {
func (s *ServerStatistics) SuccessCount() uint32 { func (s *ServerStatistics) SuccessCount() uint32 {
return s.successCounter.Load() return s.successCounter.Load()
} }
func (s *ServerStatistics) KnownMailservers() []gomatrixserverlib.ServerName {
return s.knownMailservers
}