@@ -15,6 +15,8 @@ import (
1515 "runtime/debug"
1616 "time"
1717
18+ "go.mau.fi/libsignal/state/record"
19+
1820 "go.mau.fi/libsignal/ecc"
1921 "go.mau.fi/libsignal/groups"
2022 "go.mau.fi/libsignal/keys/prekey"
@@ -92,6 +94,15 @@ func (cli *Client) shouldRecreateSession(ctx context.Context, retryCount int, ji
9294 cli .sessionRecreateHistoryLock .Lock ()
9395 defer cli .sessionRecreateHistoryLock .Unlock ()
9496 if contains , err := cli .Store .ContainsSession (ctx , jid .SignalAddress ()); err != nil {
97+ session , err := cli .Store .LoadSession (ctx , jid .SignalAddress ())
98+ if err != nil {
99+ cli .sessionRecreateHistory [jid ] = time .Now ()
100+ return fmt .Sprintf ("error loading session: %v" , err ), true
101+ }
102+ if reason , valid := cli .validSession (session ); ! valid {
103+ cli .sessionRecreateHistory [jid ] = time .Now ()
104+ return reason , true
105+ }
95106 return "" , false
96107 } else if ! contains {
97108 cli .sessionRecreateHistory [jid ] = time .Now ()
@@ -456,3 +467,28 @@ func (cli *Client) sendRetryReceipt(ctx context.Context, node *waBinary.Node, in
456467 cli .Log .Errorf ("Failed to send retry receipt for %s: %v" , id , err )
457468 }
458469}
470+
471+ func (cli * Client ) validSession (session * record.Session ) (reason string , valid bool ) {
472+ defer func () {
473+ if r := recover (); r != nil {
474+ buf := debug .Stack ()
475+ cli .Log .Errorf ("panic in validSession: %v\n %s" , r , buf )
476+ reason = "panic occurred while checking session validity"
477+ valid = false
478+ return
479+ }
480+ }()
481+ if session == nil {
482+ return "session is nil" , false
483+ }
484+ if session .SessionState () == nil {
485+ return "session state is nil" , false
486+ }
487+ state := session .SessionState ()
488+ if ! state .HasSenderChain () {
489+ return "session has no sender chain" , false
490+ }
491+ // touch the sender chain key to see if it panics
492+ state .SenderChainKey ()
493+ return "" , true
494+ }
0 commit comments