Skip to content

Commit cfe5fd0

Browse files
committed
message, retry: include error code in retry receipt
1 parent 65f6143 commit cfe5fd0

3 files changed

Lines changed: 54 additions & 5 deletions

File tree

internals.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

message.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,16 +379,19 @@ func (cli *Client) decryptMessages(ctx context.Context, info *types.MessageInfo,
379379
return
380380
}
381381
isUnavailable := encType == "skmsg" && !containsDirectMsg && errors.Is(err, signalerror.ErrNoSenderKeyForUser)
382+
383+
retryReason := getRetryReasonFromError(err)
384+
382385
if encType == "msmsg" {
383386
cli.backgroundIfAsyncAck(func() {
384387
cli.sendAck(node, NackMissingMessageSecret)
385388
})
386389
} else if cli.SynchronousAck {
387-
cli.sendRetryReceipt(ctx, node, info, isUnavailable)
390+
cli.sendRetryReceipt(ctx, node, info, isUnavailable, retryReason)
388391
// TODO this probably isn't supposed to ack
389392
cli.sendAck(node, 0)
390393
} else {
391-
go cli.sendRetryReceipt(context.WithoutCancel(ctx), node, info, isUnavailable)
394+
go cli.sendRetryReceipt(context.WithoutCancel(ctx), node, info, isUnavailable, retryReason)
392395
go cli.sendAck(node, 0)
393396
}
394397
cli.dispatchEvent(&events.UndecryptableMessage{

retry.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ import (
1111
"crypto/hmac"
1212
"crypto/sha256"
1313
"encoding/binary"
14+
"errors"
1415
"fmt"
1516
"time"
1617

18+
"go.mau.fi/libsignal/signalerror"
19+
1720
"go.mau.fi/libsignal/ecc"
1821
"go.mau.fi/libsignal/groups"
1922
"go.mau.fi/libsignal/keys/prekey"
@@ -43,6 +46,48 @@ type RecentMessage struct {
4346
fb *waMsgApplication.MessageApplication
4447
}
4548

49+
var (
50+
RetryReasonUnknownError = 0
51+
RetryReasonSignalErrorNoSession = 1
52+
RetryReasonSignalErrorInvalidKey = 2
53+
RetryReasonSignalErrorInvalidKeyId = 3
54+
RetryReasonSignalErrorInvalidMessage = 4
55+
RetryReasonSignalErrorInvalidSignature = 5
56+
RetryReasonSignalErrorFutureMessage = 6
57+
RetryReasonSignalErrorBadMac = 7
58+
RetryReasonSignalErrorInvalidSession = 8
59+
RetryReasonSignalErrorInvalidMsgKey = 9
60+
RetryReasonBadBroadcastEphemeralSetting = 10
61+
RetryReasonUnknownCompanionNoPrekey = 11
62+
RetryReasonAdvFailure = 12
63+
RetryReasonStatusRevokeDelay = 13
64+
)
65+
66+
func getRetryReasonFromError(err error) int {
67+
switch {
68+
case errors.Is(err, signalerror.ErrBadMAC):
69+
return RetryReasonSignalErrorBadMac
70+
case errors.Is(err, signalerror.ErrNoSessionForUser):
71+
case errors.Is(err, signalerror.ErrNoSenderKeyForUser):
72+
return RetryReasonSignalErrorNoSession
73+
case errors.Is(err, signalerror.ErrWrongMessageVersion):
74+
case errors.Is(err, signalerror.ErrOldMessageVersion):
75+
case errors.Is(err, signalerror.ErrUnknownMessageVersion):
76+
case errors.Is(err, signalerror.ErrIncompleteMessage):
77+
return RetryReasonSignalErrorInvalidMessage
78+
case errors.Is(err, signalerror.ErrInvalidSignature):
79+
case errors.Is(err, signalerror.ErrSenderKeyStateVerificationFailed):
80+
return RetryReasonSignalErrorInvalidSignature
81+
case errors.Is(err, signalerror.ErrNoSignedPreKey):
82+
return RetryReasonSignalErrorInvalidKey
83+
case errors.Is(err, signalerror.ErrNoSenderKeyStateForID):
84+
return RetryReasonSignalErrorInvalidKeyId
85+
case errors.Is(err, signalerror.ErrTooFarIntoFuture):
86+
return RetryReasonSignalErrorFutureMessage
87+
}
88+
return RetryReasonUnknownError
89+
}
90+
4691
func (rm RecentMessage) IsEmpty() bool {
4792
return rm.wa == nil && rm.fb == nil
4893
}
@@ -376,7 +421,7 @@ func (cli *Client) clearDelayedMessageRequests() {
376421
}
377422

378423
// sendRetryReceipt sends a retry receipt for an incoming message.
379-
func (cli *Client) sendRetryReceipt(ctx context.Context, node *waBinary.Node, info *types.MessageInfo, forceIncludeIdentity bool) {
424+
func (cli *Client) sendRetryReceipt(ctx context.Context, node *waBinary.Node, info *types.MessageInfo, forceIncludeIdentity bool, errorCode int) {
380425
id, _ := node.Attrs["id"].(string)
381426
children := node.GetChildren()
382427
var retryCountInMsg int
@@ -421,6 +466,7 @@ func (cli *Client) sendRetryReceipt(ctx context.Context, node *waBinary.Node, in
421466
"id": id,
422467
"t": node.Attrs["t"],
423468
"v": 1,
469+
"error": errorCode, // this can be 0 for the case of Unknown reason
424470
}},
425471
{Tag: "registration", Content: registrationIDBytes[:]},
426472
},

0 commit comments

Comments
 (0)