From a4db163a6970fdf2dc126c4f5620dd5c32bf838d Mon Sep 17 00:00:00 2001
From: yrutschle <git1@rutschle.net>
Date: Sun, 10 Jul 2022 21:16:41 +0200
Subject: [PATCH] config sanity check that there is at least one target
 protocol for each family that we listen to (fix #336)

---
 sslh-main.c    |  5 -----
 tcp-probe.c    | 22 ++++++++++++++++++++++
 udp-listener.c | 22 ++++++++++++++++++++++
 3 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/sslh-main.c b/sslh-main.c
index 01ade0a..eeb2f34 100644
--- a/sslh-main.c
+++ b/sslh-main.c
@@ -168,11 +168,6 @@ static void config_protocols()
 
 
 void config_sanity_check(struct sslhcfg_item* cfg) {
-    if (!cfg->protocols_len) {
-        print_message(msg_config_error, "At least one target protocol must be specified.\n");
-        exit(2);
-    }
-
 /* If compiling with systemd socket support no need to require listen address */
 #ifndef SYSTEMD
     if (!cfg->listen_len && !cfg->inetd) {
diff --git a/tcp-probe.c b/tcp-probe.c
index eebf09b..ed4060b 100644
--- a/tcp-probe.c
+++ b/tcp-probe.c
@@ -70,7 +70,29 @@ static void tcp_protocol_list_init(void)
     }
 }
 
+/* Configuration sanity check for TCP:
+ * - If there is a listening socket, there must be at least one target
+ */
+static void tcp_sanity_check(void)
+{
+    int tcp_present = 0;
+
+    for (int i = 0; i < cfg.listen_len; i++) {
+        struct sslhcfg_listen_item* p = &cfg.listen[i];
+        if (!p->is_udp) {
+            tcp_present = 1;
+            break;
+        }
+    }
+
+    if (tcp_present && !tcp_protocols_len) {
+        print_message(msg_config_error, "At least one TCP target protocol must be specified.\n");
+        exit(2);
+    }
+}
+
 void tcp_init(void)
 {
     tcp_protocol_list_init();
+    tcp_sanity_check();
 }
diff --git a/udp-listener.c b/udp-listener.c
index e595718..179cc93 100644
--- a/udp-listener.c
+++ b/udp-listener.c
@@ -91,6 +91,27 @@ static void udp_protocol_list_init(void)
     }
 }
 
+/* Configuration sanity check for UDP:
+ * - If there is a listening addres, there must be at least one target
+ */
+static void udp_sanity_check(void)
+{
+    int udp_present = 0;
+
+    for (int i = 0; i < cfg.listen_len; i++) {
+        struct sslhcfg_listen_item* p = &cfg.listen[i];
+        if (p->is_udp) {
+            udp_present = 1;
+            break;
+        }
+    }
+
+    if (udp_present && !udp_protocols_len) {
+        print_message(msg_config_error, "At least one UDP target protocol must be specified.\n");
+        exit(2);
+    }
+}
+
 /* Init the UDP subsystem.
  * - Initialise the hash
  * - that's all, folks
@@ -100,6 +121,7 @@ void udp_init(struct loop_info* fd_info)
     fd_info->hash_sources = hash_init(cfg.udp_max_connections, &hash_make_key, &cnx_cmp);
 
     udp_protocol_list_init();
+    udp_sanity_check();
 }