message: send nacks for protobuf parsing failures
This commit is contained in:
+2
-1
@@ -22,10 +22,11 @@ import (
|
||||
"go.mau.fi/whatsmeow/types/events"
|
||||
)
|
||||
|
||||
func (cli *Client) handleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) (handlerFailed bool) {
|
||||
func (cli *Client) handleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) (handlerFailed, protobufFailed bool) {
|
||||
dec, err := decodeArmadillo(decrypted)
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Failed to decode armadillo message from %s: %v", info.SourceString(), err)
|
||||
protobufFailed = true
|
||||
return
|
||||
}
|
||||
dec.Info = *info
|
||||
|
||||
Generated
+7
-3
@@ -67,7 +67,7 @@ func (int *DangerousInternalClient) RequestAppStateKeys(ctx context.Context, raw
|
||||
int.c.requestAppStateKeys(ctx, rawKeyIDs)
|
||||
}
|
||||
|
||||
func (int *DangerousInternalClient) HandleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) (handlerFailed bool) {
|
||||
func (int *DangerousInternalClient) HandleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) (handlerFailed, protobufFailed bool) {
|
||||
return int.c.handleDecryptedArmadillo(ctx, info, decrypted, retryCount)
|
||||
}
|
||||
|
||||
@@ -511,12 +511,16 @@ func (int *DangerousInternalClient) ParseReceipt(node *waBinary.Node) (*events.R
|
||||
return int.c.parseReceipt(node)
|
||||
}
|
||||
|
||||
func (int *DangerousInternalClient) BackgroundIfAsyncAck(fn func()) {
|
||||
int.c.backgroundIfAsyncAck(fn)
|
||||
}
|
||||
|
||||
func (int *DangerousInternalClient) MaybeDeferredAck(ctx context.Context, node *waBinary.Node) func(...*bool) {
|
||||
return int.c.maybeDeferredAck(ctx, node)
|
||||
}
|
||||
|
||||
func (int *DangerousInternalClient) SendAck(node *waBinary.Node) {
|
||||
int.c.sendAck(node)
|
||||
func (int *DangerousInternalClient) SendAck(node *waBinary.Node, error int) {
|
||||
int.c.sendAck(node, error)
|
||||
}
|
||||
|
||||
func (int *DangerousInternalClient) SendMessageReceipt(info *types.MessageInfo, node *waBinary.Node) {
|
||||
|
||||
+17
-13
@@ -291,13 +291,10 @@ func (cli *Client) decryptMessages(ctx context.Context, info *types.MessageInfo,
|
||||
if ok && len(node.GetChildrenByTag("enc")) == 0 {
|
||||
uType := events.UnavailableType(unavailableNode.AttrGetter().String("type"))
|
||||
cli.Log.Warnf("Unavailable message %s from %s (type: %q)", info.ID, info.SourceString(), uType)
|
||||
if cli.SynchronousAck {
|
||||
cli.backgroundIfAsyncAck(func() {
|
||||
cli.immediateRequestMessageFromPhone(ctx, info)
|
||||
cli.sendAck(node)
|
||||
} else {
|
||||
go cli.delayedRequestMessageFromPhone(info)
|
||||
go cli.sendAck(node)
|
||||
}
|
||||
cli.sendAck(node, 0)
|
||||
})
|
||||
cli.dispatchEvent(&events.UndecryptableMessage{Info: *info, IsUnavailable: true, UnavailableType: uType})
|
||||
return
|
||||
}
|
||||
@@ -320,10 +317,12 @@ func (cli *Client) decryptMessages(ctx context.Context, info *types.MessageInfo,
|
||||
cli.Log.Warnf("No LID found for %s", info.Sender)
|
||||
}
|
||||
}
|
||||
var recognizedStanza, protobufFailed bool
|
||||
for _, child := range children {
|
||||
if child.Tag != "enc" {
|
||||
continue
|
||||
}
|
||||
recognizedStanza = true
|
||||
ag := child.AttrGetter()
|
||||
encType, ok := ag.GetString("type", false)
|
||||
if !ok {
|
||||
@@ -399,15 +398,16 @@ func (cli *Client) decryptMessages(ctx context.Context, info *types.MessageInfo,
|
||||
var handlerFailed bool
|
||||
switch ag.Int("v") {
|
||||
case 2:
|
||||
// TODO send nack instead of receipt for proto unmarshal errors (both this one and armadillo)
|
||||
err = proto.Unmarshal(decrypted, &msg)
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Error unmarshaling decrypted message from %s: %v", info.SourceString(), err)
|
||||
protobufFailed = true
|
||||
continue
|
||||
}
|
||||
protobufFailed = false
|
||||
handlerFailed = cli.handleDecryptedMessage(ctx, info, &msg, retryCount)
|
||||
case 3:
|
||||
handlerFailed = cli.handleDecryptedArmadillo(ctx, info, decrypted, retryCount)
|
||||
handlerFailed, protobufFailed = cli.handleDecryptedArmadillo(ctx, info, decrypted, retryCount)
|
||||
default:
|
||||
cli.Log.Warnf("Unknown version %d in decrypted message from %s", ag.Int("v"), info.SourceString())
|
||||
}
|
||||
@@ -441,11 +441,15 @@ func (cli *Client) decryptMessages(ctx context.Context, info *types.MessageInfo,
|
||||
}
|
||||
}
|
||||
}
|
||||
if cli.SynchronousAck {
|
||||
cli.sendMessageReceipt(info, node)
|
||||
} else {
|
||||
go cli.sendMessageReceipt(info, node)
|
||||
}
|
||||
cli.backgroundIfAsyncAck(func() {
|
||||
if !recognizedStanza {
|
||||
cli.sendAck(node, NackUnrecognizedStanza)
|
||||
} else if protobufFailed {
|
||||
cli.sendAck(node, NackInvalidProtobuf)
|
||||
} else {
|
||||
cli.sendMessageReceipt(info, node)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+30
-3
@@ -101,6 +101,14 @@ func (cli *Client) parseReceipt(node *waBinary.Node) (*events.Receipt, error) {
|
||||
return &receipt, nil
|
||||
}
|
||||
|
||||
func (cli *Client) backgroundIfAsyncAck(fn func()) {
|
||||
if cli.SynchronousAck {
|
||||
fn()
|
||||
} else {
|
||||
go fn()
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *Client) maybeDeferredAck(ctx context.Context, node *waBinary.Node) func(cancelled ...*bool) {
|
||||
if cli.SynchronousAck {
|
||||
return func(cancelled ...*bool) {
|
||||
@@ -113,15 +121,31 @@ func (cli *Client) maybeDeferredAck(ctx context.Context, node *waBinary.Node) fu
|
||||
Msg("Not sending ack for node")
|
||||
return
|
||||
}
|
||||
cli.sendAck(node)
|
||||
cli.sendAck(node, 0)
|
||||
}
|
||||
} else {
|
||||
go cli.sendAck(node)
|
||||
go cli.sendAck(node, 0)
|
||||
return func(...*bool) {}
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *Client) sendAck(node *waBinary.Node) {
|
||||
const (
|
||||
NackParsingError = 487
|
||||
NackUnrecognizedStanza = 488
|
||||
NackUnrecognizedStanzaClass = 489
|
||||
NackUnrecognizedStanzaType = 490
|
||||
NackInvalidProtobuf = 491
|
||||
NackInvalidHostedCompanionStanza = 493
|
||||
NackMissingMessageSecret = 495
|
||||
NackSignalErrorOldCounter = 496
|
||||
NackMessageDeletedOnPeer = 499
|
||||
NackUnhandledError = 500
|
||||
NackUnsupportedAdminRevoke = 550
|
||||
NackUnsupportedLIDGroup = 551
|
||||
NackDBOperationFailed = 552
|
||||
)
|
||||
|
||||
func (cli *Client) sendAck(node *waBinary.Node, error int) {
|
||||
attrs := waBinary.Attrs{
|
||||
"class": node.Tag,
|
||||
"id": node.Attrs["id"],
|
||||
@@ -145,6 +169,9 @@ func (cli *Client) sendAck(node *waBinary.Node) {
|
||||
if receiptType, ok := node.Attrs["type"]; node.Tag != "message" && ok {
|
||||
attrs["type"] = receiptType
|
||||
}
|
||||
if error != 0 {
|
||||
attrs["error"] = error
|
||||
}
|
||||
err := cli.sendNode(waBinary.Node{
|
||||
Tag: "ack",
|
||||
Attrs: attrs,
|
||||
|
||||
Reference in New Issue
Block a user