Skip to content
Snippets Groups Projects
Commit 31791e5e authored by Amna Snene's avatar Amna Snene Committed by Adrien Béraud
Browse files

New API for connection monitoring

Change-Id: If63c8121351f81b869b5b48b3df64eb412dd6f79
parent b8c33bb2
Branches
No related tags found
No related merge requests found
...@@ -42,6 +42,7 @@ class Controller; ...@@ -42,6 +42,7 @@ class Controller;
namespace tls { namespace tls {
class CertificateStore; class CertificateStore;
} }
enum class ConnectionStatus : int { Connected, TLS, ICE, Connecting, Waiting };
/** /**
* A PeerConnectionRequest is a request which ask for an initial connection * A PeerConnectionRequest is a request which ask for an initial connection
...@@ -211,6 +212,46 @@ public: ...@@ -211,6 +212,46 @@ public:
*/ */
void storeActiveIpAddress(std::function<void()>&& cb = {}); void storeActiveIpAddress(std::function<void()>&& cb = {});
/**
* Retrieve the list of connections.
*
* @param device The device ID to filter the connections (optional).
* @return The list of connections as a vector of maps, where each map represents a connection.
*
* Note: The connections are represented as maps with string keys and string values. The map
* contains the following key-value pairs:
* - "id": The unique identifier of the connection.
* - "userUri": The user URI associated with the connection (if available).
* - "status": The status of the connection, represented as an integer:
* - 0: ConnectionStatus::Connected
* - 1: ConnectionStatus::TLS
* - 2: ConnectionStatus::ICE
* - 3: ConnectionStatus::Connecting (for pending operations)
* - 4: ConnectionStatus::Waiting (for pending operations)
* - "remoteAddress": The remote IP address of the connection (if available).
* - "remotePort": The remote port of the connection (if available).
*
* If a specific device ID is provided, the returned list will only include connections
* associated with that device. Otherwise, connections from all devices will be included.
*/
std::vector<std::map<std::string, std::string>> getConnectionList(
const DeviceId& device = {}) const;
/**
* Retrieve the list of channels associated with a connection.
*
* @param connectionId The ID of the connection to fetch the channels from.
* @return The list of channels as a vector of maps, where each map represents a channel
* and contains key-value pairs of channel ID and channel name.
*
* If the specified connection ID is valid and associated with a connection,
* the method returns the list of channels associated with that connection.
* Otherwise, an empty vector is returned.
*/
std::vector<std::map<std::string, std::string>> getChannelList(
const std::string& connectionId) const;
std::shared_ptr<Config> getConfig(); std::shared_ptr<Config> getConfig();
private: private:
...@@ -273,6 +314,7 @@ struct ConnectionManager::Config ...@@ -273,6 +314,7 @@ struct ConnectionManager::Config
* ie: if it is able to make port mappings * ie: if it is able to make port mappings
*/ */
bool getUPnPActive() const; bool getUPnPActive() const;
}; };
} // namespace dhtnet } // namespace dhtnet
\ No newline at end of file
...@@ -141,6 +141,11 @@ public: ...@@ -141,6 +141,11 @@ public:
const std::shared_ptr<Logger>& logger(); const std::shared_ptr<Logger>& logger();
/**
* Get the list of channels
*/
std::vector<std::map<std::string, std::string>> getChannelList() const;
/** /**
* Send a beacon on the socket and close if no response come * Send a beacon on the socket and close if no response come
* @param timeout * @param timeout
......
...@@ -41,7 +41,23 @@ static constexpr uint64_t ID_MAX_VAL = 9007199254740992; ...@@ -41,7 +41,23 @@ static constexpr uint64_t ID_MAX_VAL = 9007199254740992;
using ValueIdDist = std::uniform_int_distribution<dht::Value::Id>; using ValueIdDist = std::uniform_int_distribution<dht::Value::Id>;
using CallbackId = std::pair<dhtnet::DeviceId, dht::Value::Id>; using CallbackId = std::pair<dhtnet::DeviceId, dht::Value::Id>;
std::string
callbackIdToString(const dhtnet::DeviceId& did, const dht::Value::Id& vid)
{
return fmt::format("{} {}", did.to_view(), vid);
}
CallbackId parseCallbackId(std::string_view ci)
{
auto sep = ci.find(' ');
std::string_view deviceIdString = ci.substr(0, sep);
std::string_view vidString = ci.substr(sep + 1);
dhtnet::DeviceId deviceId(deviceIdString);
dht::Value::Id vid = std::stoul(std::string(vidString), nullptr, 10);
return CallbackId(deviceId, vid);
}
struct ConnectionInfo struct ConnectionInfo
{ {
~ConnectionInfo() ~ConnectionInfo()
...@@ -1756,4 +1772,92 @@ ConnectionManager::getConfig() ...@@ -1756,4 +1772,92 @@ ConnectionManager::getConfig()
return pimpl_->config_; return pimpl_->config_;
} }
std::vector<std::map<std::string, std::string>>
ConnectionManager::getConnectionList(const DeviceId& device) const
{
std::vector<std::map<std::string, std::string>> connectionsList;
std::lock_guard<std::mutex> lk(pimpl_->infosMtx_);
for (const auto& [key, ci] : pimpl_->infos_) {
if (device && key.first != device)
continue;
std::map<std::string, std::string> connectionInfo;
connectionInfo["id"] = callbackIdToString(key.first, key.second);
if (ci->tls_ && ci->tls_->peerCertificate()) {
auto cert = ci->tls_->peerCertificate();
connectionInfo["userUri"] = cert->issuer->getId().toString();
}
if (ci->socket_) {
connectionInfo["status"] = std::to_string(static_cast<int>(ConnectionStatus::Connected));
} else if (ci->tls_) {
connectionInfo["status"] = std::to_string(static_cast<int>(ConnectionStatus::TLS));
} else if(ci->ice_)
{
connectionInfo["status"] = std::to_string(static_cast<int>(ConnectionStatus::ICE));
}
if (ci->tls_) {
std::string remoteAddress = ci->tls_->getRemoteAddress();
std::string remoteAddressIp = remoteAddress.substr(0, remoteAddress.find(':'));
std::string remoteAddressPort = remoteAddress.substr(remoteAddress.find(':') + 1);
connectionInfo["remoteAdress"] = remoteAddressIp;
connectionInfo["remotePort"] = remoteAddressPort;
}
connectionsList.emplace_back(std::move(connectionInfo));
}
if (device) {
auto it = pimpl_->pendingOperations_.find(device);
if (it != pimpl_->pendingOperations_.end()) {
const auto& po = it->second;
for (const auto& [vid, ci] : po.connecting) {
std::map<std::string, std::string> connectionInfo;
connectionInfo["id"] = callbackIdToString(device, vid);
connectionInfo["deviceId"] = vid;
connectionInfo["status"] = std::to_string(static_cast<int>(ConnectionStatus::Connecting));
connectionsList.emplace_back(std::move(connectionInfo));
}
for (const auto& [vid, ci] : po.waiting) {
std::map<std::string, std::string> connectionInfo;
connectionInfo["id"] = callbackIdToString(device, vid);
connectionInfo["deviceId"] = vid;
connectionInfo["status"] = std::to_string(static_cast<int>(ConnectionStatus::Waiting));
connectionsList.emplace_back(std::move(connectionInfo));
}
}
}
else {
for (const auto& [key, po] : pimpl_->pendingOperations_) {
for (const auto& [vid, ci] : po.connecting) {
std::map<std::string, std::string> connectionInfo;
connectionInfo["id"] = callbackIdToString(device, vid);
connectionInfo["deviceId"] = vid;
connectionInfo["status"] = std::to_string(static_cast<int>(ConnectionStatus::Connecting));
connectionsList.emplace_back(std::move(connectionInfo));
}
for (const auto& [vid, ci] : po.waiting) {
std::map<std::string, std::string> connectionInfo;
connectionInfo["id"] = callbackIdToString(device, vid);
connectionInfo["deviceId"] = vid;
connectionInfo["status"] = std::to_string(static_cast<int>(ConnectionStatus::Waiting));
connectionsList.emplace_back(std::move(connectionInfo));
}
}
}
return connectionsList;
}
std::vector<std::map<std::string, std::string>>
ConnectionManager::getChannelList(const std::string& connectionId) const
{
std::lock_guard<std::mutex> lk(pimpl_->infosMtx_);
CallbackId cbid = parseCallbackId(connectionId);
if (pimpl_->infos_.count(cbid) > 0) {
return pimpl_->infos_[cbid]->socket_->getChannelList();
} else {
return {};
}
}
} // namespace dhtnet } // namespace dhtnet
...@@ -1204,4 +1204,21 @@ ChannelSocket::getRemoteAddress() const ...@@ -1204,4 +1204,21 @@ ChannelSocket::getRemoteAddress() const
return {}; return {};
} }
std::vector<std::map<std::string, std::string>>
MultiplexedSocket::getChannelList() const
{
std::vector<std::map<std::string, std::string>> channelsList;
for (const auto& [_, channel] : pimpl_->sockets) {
if (channel) {
std::map<std::string, std::string> channelMap;
channelMap["channel"] = std::to_string(channel->channel());
channelMap["channelName"]= channel->name();
channelsList.emplace_back(std::move(channelMap));
}
}
return channelsList;
}
} // namespace dhtnet } // namespace dhtnet
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment