add turn cache
Change-Id: I71ed970e4005d73035223ac8b32c24b27e923f1e
diff --git a/include/turn_cache.h b/include/turn_cache.h
new file mode 100644
index 0000000..c8d3684
--- /dev/null
+++ b/include/turn_cache.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2004-2023 Savoir-faire Linux Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "ip_utils.h"
+#include "turn_params.h"
+
+#include <asio.hpp>
+
+#include <atomic>
+#include <chrono>
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <string>
+
+namespace dht {
+namespace log {
+class Logger;
+}
+}
+
+namespace dhtnet {
+
+using Logger = dht::log::Logger;
+
+class TurnTransport;
+
+class TurnCache : public std::enable_shared_from_this<TurnCache>
+{
+public:
+ TurnCache(const std::string& accountId,
+ const std::string& cachePath,
+ const std::shared_ptr<asio::io_context>& io_context,
+ const std::shared_ptr<Logger>& logger,
+ const TurnTransportParams& params,
+ bool enabled);
+ ~TurnCache();
+
+ std::optional<IpAddr> getResolvedTurn(uint16_t family = AF_INET) const;
+ /**
+ * Pass a new configuration for the cache
+ * @param param The new configuration
+ */
+ void reconfigure(const TurnTransportParams& params, bool enabled);
+ /**
+ * Refresh cache from current configuration
+ */
+ void refresh(const asio::error_code& ec = {});
+
+private:
+ std::string accountId_;
+ std::string cachePath_;
+ TurnTransportParams params_;
+ std::atomic_bool enabled_ {false};
+ /**
+ * Avoid to refresh the cache multiple times
+ */
+ std::atomic_bool isRefreshing_ {false};
+ /**
+ * This will cache the turn server resolution each time we launch
+ * Jami, or for each connectivityChange()
+ */
+ void testTurn(IpAddr server);
+ std::unique_ptr<TurnTransport> testTurnV4_;
+ std::unique_ptr<TurnTransport> testTurnV6_;
+
+ // Used to detect if a turn server is down.
+ void refreshTurnDelay(bool scheduleNext);
+ std::chrono::seconds turnRefreshDelay_ {std::chrono::seconds(10)};
+
+ // Store resoved turn addresses
+ mutable std::mutex cachedTurnMutex_ {};
+ std::unique_ptr<IpAddr> cacheTurnV4_ {};
+ std::unique_ptr<IpAddr> cacheTurnV6_ {};
+
+ void onConnected(const asio::error_code& ec, bool ok, IpAddr server);
+
+ // io
+ std::shared_ptr<asio::io_context> io_context;
+ std::unique_ptr<asio::steady_timer> refreshTimer_;
+ std::unique_ptr<asio::steady_timer> onConnectedTimer_;
+
+ std::mutex shutdownMtx_;
+
+ std::shared_ptr<Logger> logger_;
+
+ // Asio :(
+ // https://stackoverflow.com/questions/35507956/is-it-safe-to-destroy-boostasio-timer-from-its-handler-or-handler-dtor
+ std::weak_ptr<TurnCache> weak()
+ {
+ return std::static_pointer_cast<TurnCache>(shared_from_this());
+ }
+};
+
+} // namespace jami