blob: deeb9197a8da7aba92f75b29a2b08667d7b420b7 [file] [log] [blame]
/*
* 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 {
struct 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 dhtnet