@@ -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"
@@ -106,6 +108,15 @@ func (cli *Client) shouldRecreateSession(ctx context.Context, retryCount int, ji
106108 cli .sessionRecreateHistoryLock .Lock ()
107109 defer cli .sessionRecreateHistoryLock .Unlock ()
108110 if contains , err := cli .Store .ContainsSession (ctx , jid .SignalAddress ()); err != nil {
111+ session , err := cli .Store .LoadSession (ctx , jid .SignalAddress ())
112+ if err != nil {
113+ cli .sessionRecreateHistory [jid ] = time .Now ()
114+ return fmt .Sprintf ("error loading session: %v" , err ), true
115+ }
116+ if reason , valid := cli .validSession (session ); ! valid {
117+ cli .sessionRecreateHistory [jid ] = time .Now ()
118+ return reason , true
119+ }
109120 return "" , false
110121 } else if ! contains {
111122 cli .sessionRecreateHistory [jid ] = time .Now ()
@@ -467,3 +478,28 @@ func (cli *Client) sendRetryReceipt(ctx context.Context, node *waBinary.Node, in
467478 cli .Log .Errorf ("Failed to send retry receipt for %s: %v" , id , err )
468479 }
469480}
481+
482+ func (cli * Client ) validSession (session * record.Session ) (reason string , valid bool ) {
483+ defer func () {
484+ if r := recover (); r != nil {
485+ buf := debug .Stack ()
486+ cli .Log .Errorf ("panic in validSession: %v\n %s" , r , buf )
487+ reason = "panic occurred while checking session validity"
488+ valid = false
489+ return
490+ }
491+ }()
492+ if session == nil {
493+ return "session is nil" , false
494+ }
495+ if session .SessionState () == nil {
496+ return "session state is nil" , false
497+ }
498+ state := session .SessionState ()
499+ if ! state .HasSenderChain () {
500+ return "session has no sender chain" , false
501+ }
502+ // touch the sender chain key to see if it panics
503+ state .SenderChainKey ()
504+ return "" , true
505+ }
0 commit comments