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,
response *api.PerformDirectoryLookupResponse,
) (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(
ctx,
request.ServerName,
@ -143,6 +148,11 @@ func (r *FederationInternalAPI) performJoinUsingServer(
supportedVersions []gomatrixserverlib.RoomVersion,
unsigned map[string]interface{},
) 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
// request.
respMakeJoin, err := r.federation.MakeJoin(
@ -398,6 +408,11 @@ func (r *FederationInternalAPI) performOutboundPeekUsingServer(
serverName gomatrixserverlib.ServerName,
supportedVersions []gomatrixserverlib.RoomVersion,
) 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.
// for now we just use the room ID again. In future, if we ever
// 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
// successfully completes the make-leave send-leave dance.
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
// request.
respMakeLeave, err := r.federation.MakeLeave(
@ -594,6 +614,11 @@ func (r *FederationInternalAPI) PerformInvite(
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{
"event_id": request.Event.EventID(),
"user_id": *request.Event.StateKey(),

View file

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