From eb57c8f1835dc25c4110af8e69a14aabab7cbf25 Mon Sep 17 00:00:00 2001
From: Adrian Rudnik <adrian@klonmaschine.de>
Date: Fri, 4 Oct 2024 12:47:28 +0200
Subject: [PATCH 1/3] Force exit on DYNDNS server failure

---
 main.go | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/main.go b/main.go
index 018fbfe..e680b60 100644
--- a/main.go
+++ b/main.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"context"
 	"github.com/cromefire/fritzbox-cloudflare-dyndns/pkg/avm"
 	"github.com/cromefire/fritzbox-cloudflare-dyndns/pkg/cloudflare"
 	"github.com/cromefire/fritzbox-cloudflare-dyndns/pkg/dyndns"
@@ -24,6 +25,8 @@ func main() {
 	updater := newUpdater()
 	updater.StartWorker()
 
+	ctx, cancel := context.WithCancel(context.Background())
+
 	ipv6LocalAddress := os.Getenv("DEVICE_LOCAL_ADDRESS_IPV6")
 
 	var localIp net.IP
@@ -37,14 +40,21 @@ func main() {
 	}
 
 	startPollServer(updater.In, &localIp)
-	startPushServer(updater.In, &localIp)
+	startPushServer(updater.In, &localIp, cancel)
 
+	// Create a OS signal shutdown channel
 	shutdown := make(chan os.Signal)
 
 	signal.Notify(shutdown, syscall.SIGTERM)
 	signal.Notify(shutdown, syscall.SIGINT)
 
-	<-shutdown
+	// Wait for either the context to finish or the shutdown signal
+	select {
+	case <-ctx.Done():
+		break
+	case <-shutdown:
+		break
+	}
 
 	slog.Info("Shutdown detected")
 }
@@ -133,7 +143,7 @@ func newUpdater() *cloudflare.Updater {
 	return u
 }
 
-func startPushServer(out chan<- *net.IP, localIp *net.IP) {
+func startPushServer(out chan<- *net.IP, localIp *net.IP, cancel context.CancelFunc) {
 	bind := os.Getenv("DYNDNS_SERVER_BIND")
 
 	if bind == "" {
@@ -155,6 +165,7 @@ func startPushServer(out chan<- *net.IP, localIp *net.IP) {
 	go func() {
 		err := s.ListenAndServe()
 		slog.Error("Server stopped", logging.ErrorAttr(err))
+		cancel()
 	}()
 }
 

From f3dce8ab059d2eb23c7af55870c41bfcef60ee20 Mon Sep 17 00:00:00 2001
From: Adrian Rudnik <adrian@klonmaschine.de>
Date: Fri, 4 Oct 2024 13:58:22 +0200
Subject: [PATCH 2/3] Added cause to context, moved logging of cause and added
 exit code

---
 main.go | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/main.go b/main.go
index e680b60..24d9bb2 100644
--- a/main.go
+++ b/main.go
@@ -25,7 +25,7 @@ func main() {
 	updater := newUpdater()
 	updater.StartWorker()
 
-	ctx, cancel := context.WithCancel(context.Background())
+	ctx, cancel := context.WithCancelCause(context.Background())
 
 	ipv6LocalAddress := os.Getenv("DEVICE_LOCAL_ADDRESS_IPV6")
 
@@ -51,7 +51,8 @@ func main() {
 	// Wait for either the context to finish or the shutdown signal
 	select {
 	case <-ctx.Done():
-		break
+		slog.Error("Context error", logging.ErrorAttr(context.Cause(ctx)))
+		os.Exit(1)
 	case <-shutdown:
 		break
 	}
@@ -143,7 +144,7 @@ func newUpdater() *cloudflare.Updater {
 	return u
 }
 
-func startPushServer(out chan<- *net.IP, localIp *net.IP, cancel context.CancelFunc) {
+func startPushServer(out chan<- *net.IP, localIp *net.IP, cancel context.CancelCauseFunc) {
 	bind := os.Getenv("DYNDNS_SERVER_BIND")
 
 	if bind == "" {
@@ -164,8 +165,7 @@ func startPushServer(out chan<- *net.IP, localIp *net.IP, cancel context.CancelF
 
 	go func() {
 		err := s.ListenAndServe()
-		slog.Error("Server stopped", logging.ErrorAttr(err))
-		cancel()
+		cancel(err)
 	}()
 }
 

From 31efd1c70d25c0acd81f11ba62e64e254420894d Mon Sep 17 00:00:00 2001
From: Adrian Rudnik <adrian@klonmaschine.de>
Date: Fri, 4 Oct 2024 14:15:57 +0200
Subject: [PATCH 3/3] Wrapped http server errors

---
 main.go | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/main.go b/main.go
index 24d9bb2..6b5b2c3 100644
--- a/main.go
+++ b/main.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"context"
+	"errors"
 	"github.com/cromefire/fritzbox-cloudflare-dyndns/pkg/avm"
 	"github.com/cromefire/fritzbox-cloudflare-dyndns/pkg/cloudflare"
 	"github.com/cromefire/fritzbox-cloudflare-dyndns/pkg/dyndns"
@@ -51,7 +52,7 @@ func main() {
 	// Wait for either the context to finish or the shutdown signal
 	select {
 	case <-ctx.Done():
-		slog.Error("Context error", logging.ErrorAttr(context.Cause(ctx)))
+		slog.Error("Context closed", logging.ErrorAttr(context.Cause(ctx)))
 		os.Exit(1)
 	case <-shutdown:
 		break
@@ -165,7 +166,7 @@ func startPushServer(out chan<- *net.IP, localIp *net.IP, cancel context.CancelC
 
 	go func() {
 		err := s.ListenAndServe()
-		cancel(err)
+		cancel(errors.Join(errors.New("http server error"), err))
 	}()
 }