From 93ef4aa15b46bccfd6fc36fadeda393420f38339 Mon Sep 17 00:00:00 2001 From: Felix Breidenstein Date: Mon, 27 Jul 2020 18:26:33 +0200 Subject: [PATCH 1/3] Update .goreleaser.yml to support current version --- .goreleaser.yml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index f6386ae..57b530e 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,8 +1,5 @@ -# This is an example goreleaser.yaml file with some sane defaults. -# Make sure to check the documentation at http://goreleaser.com builds: -- - env: +- env: - CGO_ENABLED=0 goos: - linux @@ -11,13 +8,13 @@ builds: - amd64 - arm64 -archive: - replacements: - linux: Linux - amd64: x86_64 - files: - - LICENSE - - cpthook.yml.example +archives: + - replacements: + linux: Linux + amd64: x86_64 + files: + - LICENSE + - cpthook.yml.example checksum: name_template: 'checksums.txt' @@ -30,5 +27,5 @@ changelog: filters: exclude: - '^docs:' - - '^test:' + - '^test_data:' From 5b2c4a216df2082dc3ebd6ce267b38a6f8229a9c Mon Sep 17 00:00:00 2001 From: kmille Date: Fri, 19 Feb 2021 14:47:10 +0100 Subject: [PATCH 2/3] Update default settings for hackint in cpthook.yml.example Switch to the SSL port of hackint. In the meantime hackint uses Let's encrypt so we can use /etc/ssl/certs/ca-certificates.crt for validation here. --- cpthook.yml.example | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpthook.yml.example b/cpthook.yml.example index 70fbf0f..8327f20 100644 --- a/cpthook.yml.example +++ b/cpthook.yml.example @@ -5,11 +5,11 @@ logging: level: "INFO" irc: - host: "irc.hackint.eu" - port: 6667 + host: "irc.hackint.org" + port: 6697 ssl: enabled: true - cafile: "/etc/ssl/hackint.pem" + cafile: "/etc/ssl/certs/ca-certificates.crt" client_cert: certfile: "/home/bot/bot.cert" keyfile: "/home/bot/bot.key" From f0faa6e5eb63581c0ffc33152961d7d3b43d220b Mon Sep 17 00:00:00 2001 From: kmille Date: Fri, 19 Feb 2021 15:24:51 +0100 Subject: [PATCH 3/3] Improve handling of connection issues (related to #47) There was a problem in the automatic reconnect loop: If the connection to the IRC server is dropped it will not be reestablished because the call to `client.Server()` blocks forever. This is fixed by not calling it at this point. But there are other issues we have to tackle. The first one is our locking. We still have a big issue here if the following happens: - if the connection goes down, `client.Connect()` returns an error - we acquire the lock: `clientLock.Lock()` - we sleep some time - we call `client.Connect()` again and it fails again because our Internet is still broken - As our handler (CONNECTED) was not called, the lock is still in use - we hang here forever If we want to rewrite the lock logic, we have to think about two scenarios: 1) How do we handle the time between irc-connection-is-down and the-library-knows-that-the-connection-is-down? The library sends continuously a PING (every 20 seconds is the smallest time interval we can use). If now() - time_last(PONG) is > 60 seconds, the connection goes in state disconnected. Then `Connect()` returns and we reconnect. 2) What happens if the connection to the IRC server is down, but our http server works and is used? We can - send a 500 because the IRC connection is down (if we know it; good for alertmanager, probably bad for other things that don't automatically resend) - handle the received data in a go routine and always return a 200 (never blocks, but we have to buffer the messages until IRC is up again) - we keep the logic as it is and increase the channel size. Right now, http connections are held open if we cannot write into the channel (because the IRC sender does not work and stops reading from the channel) --- irc.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/irc.go b/irc.go index c8db34f..6f3ca64 100644 --- a/irc.go +++ b/irc.go @@ -120,12 +120,16 @@ func ircConnection(config *viper.Viper, channelList []string) { log.Info("Connecting to IRC server") for { - if err := client.Connect(); err != nil { - clientLock.Lock() - log.Warnf("Connection to %s terminated: %s", client.Server(), err) - log.Warn("Reconnecting in 30 seconds...") - time.Sleep(30 * time.Second) - } + // client.Connect() blocks. It returns nil if we call a client.Close() which we never do. + // If the the connection is dropped/broken (recognized if we don't get a PONG 60 seconds + // after we sent a PING) an error is returned. + err := client.Connect() + // FIXME: if client.Connect() fails twice without going in state connected our handler is + // not called. This means that the lock is still acquired and we will hang here forever. + clientLock.Lock() + log.Warnf("Connection terminated: %s", err) + log.Warn("Reconnecting in 30 seconds...") + time.Sleep(30 * time.Second) } }