From 14daa11dc1852c5d3b5e8d002e2397cccdc748d9 Mon Sep 17 00:00:00 2001
From: Steffen Vogel <post@steffenvogel.de>
Date: Tue, 20 Jul 2021 19:35:15 +0200
Subject: [PATCH] redis: add detection for TLS support

---
 CMakeLists.txt                         |  8 ++++++++
 include/villas/node/config.h.in        |  1 +
 include/villas/nodes/redis_helpers.hpp | 19 +++++++++++++++++--
 lib/nodes/redis.cpp                    |  5 +++++
 4 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8e66120f3..81aa99a48 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -131,6 +131,14 @@ if(NOT RE_FOUND)
     pkg_check_modules(RE IMPORTED_TARGET libre>=0.5.6)
 endif()
 
+if (REDISPP_FOUND)
+    file(READ "${REDISPP_INCLUDEDIR}/sw/redis++/tls.h" CONTENTS)
+    if (CONTENTS MATCHES "SEWENEW_REDISPLUSPLUS_TLS_H")
+        set(REDISPP_WITH_TLS ON)
+    endif()
+    unset(CONTENTS)
+endif()
+
 # Check if libwebsockets is build with deflate extension
 if(${CMAKE_VERSION} VERSION_LESS "3.12.4")
     set(LWS_LOCATION "${LIBWEBSOCKETS_LIBRARY_DIRS}/lib${LIBWEBSOCKETS_LIBRARIES}.so")
diff --git a/include/villas/node/config.h.in b/include/villas/node/config.h.in
index 2bfd4ca0c..df4af11cf 100644
--- a/include/villas/node/config.h.in
+++ b/include/villas/node/config.h.in
@@ -70,3 +70,4 @@
 
 /* Library features */
 #cmakedefine LWS_DEFLATE_FOUND
+#cmakedefine REDISPP_WITH_TLS
diff --git a/include/villas/nodes/redis_helpers.hpp b/include/villas/nodes/redis_helpers.hpp
index be5a661a0..c53e9afcd 100644
--- a/include/villas/nodes/redis_helpers.hpp
+++ b/include/villas/nodes/redis_helpers.hpp
@@ -34,6 +34,8 @@
 #include <sw/redis++/redis++.h>
 #include <spdlog/fmt/ostr.h>
 
+#include <villas/node/config.h>
+
 namespace std {
 
 template<typename _rep, typename ratio>
@@ -50,12 +52,16 @@ struct hash<sw::redis::tls::TlsOptions>
 {
 	std::size_t operator()(const sw::redis::tls::TlsOptions& t) const
 	{
+#ifdef REDISPP_WITH_TLS
 		return hash<bool>()(t.enabled) ^
 		       hash<std::string>()(t.cacert) ^
 		       hash<std::string>()(t.cacertdir) ^
 		       hash<std::string>()(t.cert) ^
 		       hash<std::string>()(t.key) ^
 		       hash<std::string>()(t.sni);
+#else
+		return 0;
+#endif /* REDISPP_WITH_TLS */
 	}
 };
 
@@ -85,12 +91,16 @@ namespace redis {
 
 bool operator==(const tls::TlsOptions &o1, const tls::TlsOptions &o2)
 {
+#ifdef REDISPP_WITH_TLS
 	return o1.enabled == o2.enabled &&
 	       o1.cacert == o2.cacert &&
 	       o1.cacertdir == o2.cacertdir &&
 	       o1.cert == o2.cert &&
 	       o1.key == o2.key &&
 	       o1.sni == o2.sni;
+#else
+	return true;
+#endif /* REDISPP_WITH_TLS */
 }
 
 bool operator==(const ConnectionOptions &o1, const ConnectionOptions &o2)
@@ -108,6 +118,7 @@ bool operator==(const ConnectionOptions &o1, const ConnectionOptions &o2)
 	       o1.tls == o2.tls;
 }
 
+#ifdef REDISPP_WITH_TLS
 template<typename OStream>
 OStream &operator<<(OStream &os, const tls::TlsOptions &t)
 {
@@ -132,6 +143,7 @@ OStream &operator<<(OStream &os, const tls::TlsOptions &t)
 
 	return os;
 }
+#endif /* REDISPP_WITH_TLS */
 
 template<typename OStream>
 OStream &operator<<(OStream &os, const ConnectionType &t)
@@ -166,8 +178,11 @@ OStream &operator<<(OStream &os, const ConnectionOptions &o)
 
 	os << ", db=" << o.db
 	   << ", user=" << o.user
-	   << ", keepalive=" << (o.keep_alive ? "yes" : "no")
-	   << ", " << o.tls;
+	   << ", keepalive=" << (o.keep_alive ? "yes" : "no");
+
+#ifdef REDISPP_WITH_TLS
+	os << ", " << o.tls;
+#endif
 
 	return os;
 }
diff --git a/lib/nodes/redis.cpp b/lib/nodes/redis.cpp
index fcfbbc294..9df9de6e5 100644
--- a/lib/nodes/redis.cpp
+++ b/lib/nodes/redis.cpp
@@ -34,6 +34,7 @@
 #include <villas/super_node.hpp>
 #include <villas/exceptions.hpp>
 #include <villas/timing.h>
+#include <villas/node/config.h>
 
 /* Forward declartions */
 static struct vnode_type p;
@@ -356,6 +357,7 @@ int redis_parse(struct vnode *n, json_t *json)
 	if (ret)
 		throw ConfigError(json, err, "node-config-node-redis", "Failed to parse node configuration");
 
+#ifdef REDISPP_WITH_TLS
 	if (json_ssl) {
 		const char *cacert;
 		const char *cacertdir;
@@ -384,6 +386,9 @@ int redis_parse(struct vnode *n, json_t *json)
 		if (host)
 			r->options.tls.sni = host;
 	}
+#else
+	throw ConfigError(json_ssl, "node-config-node-redis-ssl", "This built of the redis++ library does not support SSL");
+#endif /* REDISPP_WITH_TLS */
 
 	/* Mode */
 	if (mode) {