ScuttleBot
fix: relay re-registers SASL credentials on reconnect After a server restart, Ergo's account database resets and the relay's cached SASL passphrase becomes invalid. The keepAlive loop now clears stale credentials and calls ensureCredentials() before each reconnect attempt, which re-registers or rotates to get a fresh passphrase.
Commit
54be8d26cb8d16e82873140afd28f8fa1942b88fead6687027d28bb1cce03492
Parent
ada73432140ce08…
1 file changed
+18
+18
| --- pkg/sessionrelay/irc.go | ||
| +++ pkg/sessionrelay/irc.go | ||
| @@ -5,10 +5,11 @@ | ||
| 5 | 5 | "context" |
| 6 | 6 | "encoding/json" |
| 7 | 7 | "fmt" |
| 8 | 8 | "net" |
| 9 | 9 | "net/http" |
| 10 | + "os" | |
| 10 | 11 | "slices" |
| 11 | 12 | "strconv" |
| 12 | 13 | "strings" |
| 13 | 14 | "sync" |
| 14 | 15 | "time" |
| @@ -180,10 +181,27 @@ | ||
| 180 | 181 | select { |
| 181 | 182 | case <-ctx.Done(): |
| 182 | 183 | return |
| 183 | 184 | case <-time.After(wait): |
| 184 | 185 | } |
| 186 | + | |
| 187 | + // Re-register to get fresh SASL credentials in case the server | |
| 188 | + // restarted and the Ergo database was reset. | |
| 189 | + c.pass = "" // clear stale creds | |
| 190 | + if err := c.ensureCredentials(ctx); err != nil { | |
| 191 | + fmt.Fprintf(os.Stderr, "sessionrelay: reconnect credential refresh failed: %v\n", err) | |
| 192 | + wait = min(wait*2, ircReconnectMax) | |
| 193 | + // Push a synthetic error so the loop retries. | |
| 194 | + go func() { | |
| 195 | + select { | |
| 196 | + case c.errCh <- err: | |
| 197 | + default: | |
| 198 | + } | |
| 199 | + }() | |
| 200 | + continue | |
| 201 | + } | |
| 202 | + | |
| 185 | 203 | wait = min(wait*2, ircReconnectMax) |
| 186 | 204 | c.dial(host, port, func() { wait = ircReconnectMin }) |
| 187 | 205 | } |
| 188 | 206 | } |
| 189 | 207 | |
| 190 | 208 |
| --- pkg/sessionrelay/irc.go | |
| +++ pkg/sessionrelay/irc.go | |
| @@ -5,10 +5,11 @@ | |
| 5 | "context" |
| 6 | "encoding/json" |
| 7 | "fmt" |
| 8 | "net" |
| 9 | "net/http" |
| 10 | "slices" |
| 11 | "strconv" |
| 12 | "strings" |
| 13 | "sync" |
| 14 | "time" |
| @@ -180,10 +181,27 @@ | |
| 180 | select { |
| 181 | case <-ctx.Done(): |
| 182 | return |
| 183 | case <-time.After(wait): |
| 184 | } |
| 185 | wait = min(wait*2, ircReconnectMax) |
| 186 | c.dial(host, port, func() { wait = ircReconnectMin }) |
| 187 | } |
| 188 | } |
| 189 | |
| 190 |
| --- pkg/sessionrelay/irc.go | |
| +++ pkg/sessionrelay/irc.go | |
| @@ -5,10 +5,11 @@ | |
| 5 | "context" |
| 6 | "encoding/json" |
| 7 | "fmt" |
| 8 | "net" |
| 9 | "net/http" |
| 10 | "os" |
| 11 | "slices" |
| 12 | "strconv" |
| 13 | "strings" |
| 14 | "sync" |
| 15 | "time" |
| @@ -180,10 +181,27 @@ | |
| 181 | select { |
| 182 | case <-ctx.Done(): |
| 183 | return |
| 184 | case <-time.After(wait): |
| 185 | } |
| 186 | |
| 187 | // Re-register to get fresh SASL credentials in case the server |
| 188 | // restarted and the Ergo database was reset. |
| 189 | c.pass = "" // clear stale creds |
| 190 | if err := c.ensureCredentials(ctx); err != nil { |
| 191 | fmt.Fprintf(os.Stderr, "sessionrelay: reconnect credential refresh failed: %v\n", err) |
| 192 | wait = min(wait*2, ircReconnectMax) |
| 193 | // Push a synthetic error so the loop retries. |
| 194 | go func() { |
| 195 | select { |
| 196 | case c.errCh <- err: |
| 197 | default: |
| 198 | } |
| 199 | }() |
| 200 | continue |
| 201 | } |
| 202 | |
| 203 | wait = min(wait*2, ircReconnectMax) |
| 204 | c.dial(host, port, func() { wait = ircReconnectMin }) |
| 205 | } |
| 206 | } |
| 207 | |
| 208 |