Skip to content

Commit

Permalink
Add internal counter for retry requests
Browse files Browse the repository at this point in the history
Apparently some people have broken (possibly unofficial) clients which don't
increment the counter on outgoing requests like whatsmeow and official clients
do, so need to keep track of the count and ignore requests if the sender spams
them.
  • Loading branch information
tulir committed Nov 10, 2023
1 parent bcfaed4 commit cfd1bea
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 0 deletions.
5 changes: 5 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ type Client struct {
messageRetries map[string]int
messageRetriesLock sync.Mutex

incomingRetryRequestCounter map[incomingRetryKey]int
incomingRetryRequestCounterLock sync.Mutex

appStateKeyRequests map[string]time.Time
appStateKeyRequestsLock sync.RWMutex

Expand Down Expand Up @@ -186,6 +189,8 @@ func NewClient(deviceStore *store.Device, log waLog.Logger) *Client {
appStateProc: appstate.NewProcessor(deviceStore, log.Sub("AppState")),
socketWait: make(chan struct{}),

incomingRetryRequestCounter: make(map[incomingRetryKey]int),

historySyncNotifications: make(chan *waProto.HistorySyncNotification, 32),

groupParticipantsCache: make(map[types.JID][]types.JID),
Expand Down
16 changes: 16 additions & 0 deletions retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ func (cli *Client) shouldRecreateSession(retryCount int, jid types.JID) (reason
return "", false
}

type incomingRetryKey struct {
jid types.JID
messageID types.MessageID
}

// handleRetryReceipt handles an incoming retry receipt for an outgoing message.
func (cli *Client) handleRetryReceipt(receipt *events.Receipt, node *waBinary.Node) error {
retryChild, ok := node.GetOptionalChildByTag("retry")
Expand All @@ -111,6 +116,17 @@ func (cli *Client) handleRetryReceipt(receipt *events.Receipt, node *waBinary.No
if err != nil {
return err
}

retryKey := incomingRetryKey{receipt.Sender, messageID}
cli.incomingRetryRequestCounterLock.Lock()
cli.incomingRetryRequestCounter[retryKey]++
internalCounter := cli.incomingRetryRequestCounter[retryKey]
cli.incomingRetryRequestCounterLock.Unlock()
if internalCounter >= 10 {
cli.Log.Warnf("Dropping retry request from %s for %s: internal retry counter is %d", messageID, receipt.Sender, internalCounter)
return nil
}

ownID := cli.getOwnID()
if ownID.IsEmpty() {
return ErrNotLoggedIn
Expand Down

0 comments on commit cfd1bea

Please sign in to comment.