aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSami Littow <sami.littow@qt.io>2023-03-13 13:38:43 +0200
committerSami Littow <sami.littow@qt.io>2023-03-16 15:57:54 +0200
commit69132ea752eb1b222f7db1b2464fedfbaac31616 (patch)
treed4eb579c51fd9c4b2cb1f149119e55e135d4b322
parentefa178f16ca785e00ec288f1814948d420e66c9d (diff)
Change in client storage
- Client storage vector changed to std::unordered_map, key is the socket ID - Socket ID is now the client ID - Some changes/fixes in socket handling Change-Id: I57596ab286685d1a46ea932a95125299b7a64624 Reviewed-by: Arttu Tarkiainen <arttu.tarkiainen@qt.io>
-rw-r--r--src/libs/qlicenseservice/clienthandler.cpp30
-rw-r--r--src/libs/qlicenseservice/daemon_clients/clienthandler.h5
-rw-r--r--src/libs/qlicenseservice/daemon_clients/squishhandler.h7
-rw-r--r--src/libs/qlicenseservice/licenser.cpp88
-rw-r--r--src/libs/qlicenseservice/licenser.h4
5 files changed, 72 insertions, 62 deletions
diff --git a/src/libs/qlicenseservice/clienthandler.cpp b/src/libs/qlicenseservice/clienthandler.cpp
index c13c2a0..8ecb6c5 100644
--- a/src/libs/qlicenseservice/clienthandler.cpp
+++ b/src/libs/qlicenseservice/clienthandler.cpp
@@ -92,6 +92,9 @@ int ClientHandler::parseRequest()
bool argFound = false;
std::string arg;
for (const std::string &item : params) {
+ if (item.empty()) {
+ continue;
+ }
if (!argFound) {
if (item[0] == '-') {
arg = item;
@@ -102,7 +105,7 @@ int ClientHandler::parseRequest()
std::cout << "Not a valid argument: \"" << item << "\"\n";
return e_bad_request;
}
- } else if (item[0] != '-' && !item.empty()) {
+ } else {
if (arg == "-a") m_request.appName = utils::strToLower(item);
else if (arg == "-v") m_request.appVersion = item;
else if (arg == "-u") m_request.userId = item;
@@ -117,7 +120,7 @@ int ClientHandler::parseRequest()
}
argFound = false;
arg = "";
- } else break;
+ }
}
// Check if we're run out of items in argument list without getting the value:
if (argFound) {
@@ -170,6 +173,11 @@ void ClientHandler::updateLicense(const std::string &responseJson)
m_license.user_id = json.get("user_id");
}
+void ClientHandler::addChildClient(ClientHandler *client)
+{
+ m_childClients[client->getSocketId()] = client;
+}
+
void ClientHandler::removeCachedFile() {
utils::deleteFile(m_request.licenseFile);
}
@@ -181,23 +189,19 @@ void ClientHandler::resetTime()
bool ClientHandler::removeChildClient(uint16_t socketId)
{
- for (uint8_t i = 0; i < m_childClients.size(); i++ ) {
- if (m_childClients.at(i)->getSocketId() == socketId) {
- ClientHandler *client = m_childClients[i];
- m_childClients.erase(m_childClients.begin() + i);
- delete client;
- return true;
- }
+ if (m_childClients.find(socketId) != m_childClients.end()) {
+ ClientHandler *client = m_childClients[socketId];
+ m_childClients.erase(socketId);
+ delete client;
+ return true;
}
return false;
}
bool ClientHandler::clientInStorage(uint16_t socketId)
{
- for (auto client : m_childClients) {
- if (client->getSocketId() == socketId) {
- return true;
- }
+ if (m_childClients.find(socketId) != m_childClients.end()) {
+ return true;
}
return false;
}
diff --git a/src/libs/qlicenseservice/daemon_clients/clienthandler.h b/src/libs/qlicenseservice/daemon_clients/clienthandler.h
index cdd5e7e..084f343 100644
--- a/src/libs/qlicenseservice/daemon_clients/clienthandler.h
+++ b/src/libs/qlicenseservice/daemon_clients/clienthandler.h
@@ -8,6 +8,7 @@
#include <iostream>
#include <string>
#include <vector>
+#include <unordered_map>
#include "commonsetup.h"
#include "licdsetup.h"
@@ -44,7 +45,7 @@ class ClientHandler
void resetTime();
bool hasFloatingLicense() { return m_floatingLicense; }
bool hasParent() { return m_hasParent; }
- void addChildClient(ClientHandler *client) { m_childClients.push_back(std::move(client)); }
+ void addChildClient(ClientHandler *client);
bool removeChildClient(uint16_t socketId);
bool hasChildren() { return !m_childClients.empty(); }
bool stopped() { return m_stoppedWorking; }
@@ -52,7 +53,7 @@ class ClientHandler
bool clientInStorage(uint16_t socketId);
protected:
- std::vector<ClientHandler*> m_childClients;
+ std::unordered_map<uint16_t, ClientHandler*> m_childClients;
License m_license;
RequestInfo m_request;
LicdSetup m_settings;;
diff --git a/src/libs/qlicenseservice/daemon_clients/squishhandler.h b/src/libs/qlicenseservice/daemon_clients/squishhandler.h
index 729561c..9116eaa 100644
--- a/src/libs/qlicenseservice/daemon_clients/squishhandler.h
+++ b/src/libs/qlicenseservice/daemon_clients/squishhandler.h
@@ -107,11 +107,12 @@ class SquishHandler : public ClientHandler {
bool isLicenseRequestDue() override
{
// First check if this client is a subprocess - no reporting
- if (m_hasParent)
+ if (m_hasParent) {
return false;
-
+ }
uint64_t now = utils::getTimestampNow();
- if (m_license.last_timestamp == 0) return true; // startup
+ if (m_license.last_timestamp == 0)
+ return true; // startup
if ((now - m_license.last_timestamp) > m_updateInterval)
return true;
return false;
diff --git a/src/libs/qlicenseservice/licenser.cpp b/src/libs/qlicenseservice/licenser.cpp
index 574fedd..f2364d6 100644
--- a/src/libs/qlicenseservice/licenser.cpp
+++ b/src/libs/qlicenseservice/licenser.cpp
@@ -52,8 +52,8 @@ Licenser::~Licenser()
int Licenser::listen()
{
m_infoString = "";
- uint16_t socket = 0; // Placeholder for whatever socket gets active
- std::string input = m_tcpServer->listenToClients(socket);
+ uint16_t socketId = 0; // Placeholder for whatever socket gets active
+ std::string input = m_tcpServer->listenToClients(socketId);
input = utils::trimStr(input);
if (input.empty()) {
@@ -63,23 +63,23 @@ int Licenser::listen()
return 0; //continue;
}
if (input == SOCKET_CLOSED_MSG) {
- std::cout << "Client disconnected, socket id " << socket << std::endl;
- removeReservation(socket);
+ std::cout << "Client disconnected, socket id " << socketId << std::endl;
+ removeReservation(socketId);
return 0;
}
std::cout << "Got a request: " << input << std::endl;
// Check if we already have this client in storage (floating one):
- if (clientInStorage(socket)) {
+ if (clientInStorage(socketId)) {
// do nothing - floating clients should only send request at startup
- std::cout << "Floating client with ID " << socket << " sent something while working: ignoring\n";
- m_tcpServer->sendResponse(socket, "NOK\n");
+ std::cout << "Floating client with ID " << socketId << " sent something while working: ignoring\n";
+ m_tcpServer->sendResponse(socketId, "NOK\n");
return 0;
}
std::string reply = ""; // Holds server response first (if got any). After parsing, holds reply to the client
bool removeRes = false;
- if (parseInputAndCreateCLient(socket, input)) {
+ if (parseInputAndCreateCLient(socketId, input)) {
if (m_currentClient->parseRequest() != e_bad_request) {
RequestType reqType = m_currentClient->getRequestType();
if (reqType == RequestType::reservation_query) {
@@ -87,8 +87,8 @@ int Licenser::listen()
} else if (reqType == RequestType::daemon_version) {
reply = getDaemonVersion();
} else {
- std::cout << "Initiating a request to the server\n";
if (m_currentClient->isLicenseRequestDue()) {
+ std::cout << "Initiating a request to the server\n";
if (sendServerRequest(reply) == e_bad_connection) {
// Bad server connection: Check the existing license file for expiry date
if (!m_currentClient->isCachedReservationValid(reply)) {
@@ -105,11 +105,15 @@ int Licenser::listen()
}
} else {
reply = replyString[e_bad_request];
+ removeRes = true;
}
} else {
reply = replyString[e_bad_request];
+ removeRes = true;
}
- if (m_currentClient->hasFloatingLicense() && !clientInStorage(socket)) {
+ if (m_currentClient->hasFloatingLicense()
+ && !clientInStorage(socketId)
+ && !removeRes) {
// Store QA tool, Coco or Squish client (floating license) if not already stored
if (m_currentClient->hasParent()) {
if (!addClientToParent()) {
@@ -118,7 +122,7 @@ int Licenser::listen()
}
} else {
std::cout << "Storing client in main cache\n";
- m_floatingClients.push_back(std::move(m_currentClient));
+ m_floatingClients[socketId] = std::move(m_currentClient);
}
}
if (!m_infoString.empty()) {
@@ -126,13 +130,14 @@ int Licenser::listen()
reply += m_infoString;
}
reply +="\n";
- m_tcpServer->sendResponse(socket, reply);
- std::cout << "Replied to socket " << socket << ": " << reply << std::endl;
+ m_tcpServer->sendResponse(socketId, reply);
+ std::cout << "Replied to socket " << socketId << ": " << reply << std::endl;
if (removeRes) {
// No license, remove reservation from cache (floating license)
// or license file (site license)
- removeReservation(socket);
+ removeReservation(socketId);
+ return 0;
}
if (m_floatingClients.size() > 0) {
@@ -145,21 +150,19 @@ int Licenser::listen()
int Licenser::checkTasksDue() {
// Check if there's any floating clients which has tasks to be done
- ClientHandler *client;
- for (int i = 0 ; i < m_floatingClients.size(); i++) {
- client = m_floatingClients[i];
+ for (auto entry : m_floatingClients) {
// First check if (parent) client has stopped and no children left
- if (client->stopped() && !client->hasChildren()) {
- removeReservation(client->getSocketId());
+ if (entry.second->stopped() && !entry.second->hasChildren()) {
+ removeReservation(entry.first);
return 0;
}
// Then check if there is any server pings due
- if (client->isLicenseRequestDue()) {
+ if (entry.second->isLicenseRequestDue()) {
std::string reply;
if (sendServerRequest(reply) != e_bad_connection) {
- std::cout << "Reported alive floating reservation with socket ID " << client->getSocketId() << std::endl;
- std::cout << "Client has " << client->getNumberOfClients() << " sub-processes running\n";
- client->resetTime();
+ std::cout << "Reported alive floating reservation with socket ID " << entry.first << std::endl;
+ std::cout << "Client has " << entry.second->getNumberOfClients() << " sub-processes running\n";
+ entry.second->resetTime();
}
}
}
@@ -237,12 +240,11 @@ void Licenser::doHmacHashSha256(const std::string &payload, const std::string &s
for (uint8_t x : out) {
ss_result << std::hex << std::setfill('0') << std::setw(2) << (int)x;
}
-
authKey = ss_result.str();
JsonHandler pay(payload);
-
}
+
std::string Licenser::checkReservations()
{
// Open all license files
@@ -270,12 +272,13 @@ std::string Licenser::checkReservations()
return reply.str();
}
+
bool Licenser::addClientToParent()
{
bool found = false;
- for (int i = 0; i < m_floatingClients.size(); i++) {
- if (m_floatingClients.at(i)->getReservationId() == m_currentClient->getParentReservationId()) {
- m_floatingClients.at(i)->addChildClient(m_currentClient);
+ for (auto parent : m_floatingClients) {
+ if (parent.second->getReservationId() == m_currentClient->getParentReservationId()) {
+ parent.second->addChildClient(m_currentClient);
found = true;
std::cout << "Stored client under reservation ID "
<< m_currentClient->getParentReservationId() << std::endl;
@@ -292,19 +295,19 @@ bool Licenser::addClientToParent()
void Licenser::removeReservation(int socketId) {
- // Check if the client had a floating license, or is a child of one:
- ClientHandler *client;
- for (int i = 0; i < m_floatingClients.size(); i++) {
- client = m_floatingClients[i];
- if (client->getSocketId() == socketId) {
- // If parent has no running children left, we can release the reservation
+ // Close the socket
+ m_tcpServer->closeClientSocket(socketId);
+ // Check if the client had a floating license, or is a child of one.
+ // Need to loop through all of them because socketId can be under any parent
+ for (auto element : m_floatingClients) {
+ ClientHandler* client = element.second;
+ if (element.first == socketId) {
if (!client->stopped()) {
client->prepareRelease();
- m_tcpServer->closeClientSocket(socketId);
// Don't remove parent yet, it might have child processes left
}
if (!client->hasChildren()) {
- // No child processes: remove it
+ // If client has no running children left, we can release the reservation and remove client
std::string reply;
client->release();
client->buildRequestJson();
@@ -312,28 +315,28 @@ void Licenser::removeReservation(int socketId) {
if (sendServerRequest(reply) != e_bad_connection) {
// if connection succeeds, we can forget about this client
std::cout << "Removing floating reservation with ID " << client->getReservationId() << std::endl;
- m_floatingClients.erase(m_floatingClients.begin() + i);
+ m_floatingClients.erase(socketId);
delete client;
+
}
}
return;
} else if (client->removeChildClient(socketId)) {
std::cout << "Removed child client under reservation ID " << client->getReservationId() << std::endl;
- m_tcpServer->closeClientSocket(socketId);
return;
}
}
- m_tcpServer->closeClientSocket(socketId);
return;
}
+
bool Licenser::clientInStorage(uint16_t socketId) {
for (auto client : m_floatingClients) {
- if (client->getSocketId() == socketId) {
+ if (client.first == socketId) {
return true;
}
- if (client->hasChildren()) {
- if (client->clientInStorage(socketId)) {
+ if (client.second->hasChildren()) {
+ if (client.second->clientInStorage(socketId)) {
return true;
}
}
@@ -341,6 +344,7 @@ bool Licenser::clientInStorage(uint16_t socketId) {
return false;
}
+
std::string Licenser::getDaemonVersion()
{
std::string version = "Qt License Daemon (qtlicd) v";
diff --git a/src/libs/qlicenseservice/licenser.h b/src/libs/qlicenseservice/licenser.h
index 0c916a2..0c77c9b 100644
--- a/src/libs/qlicenseservice/licenser.h
+++ b/src/libs/qlicenseservice/licenser.h
@@ -9,7 +9,7 @@
#include <fstream>
#include <sstream>
#include <string>
-#include <vector>
+#include <unordered_map>
#include <ctime>
#include <cassert>
#if _WIN32
@@ -40,7 +40,7 @@ private:
uint64_t m_mocInterval;
std::string m_infoString;
ClientHandler *m_currentClient;
- std::vector<ClientHandler*> m_floatingClients;
+ std::unordered_map<uint16_t, ClientHandler*> m_floatingClients;
bool parseInputAndCreateCLient(uint16_t socketId, const std::string &incoming);
bool addClientToParent();