Commit 5f0265920d4b80565fe3c8a83763cfc483e5efb8

Authored by Wiebe Cazemier
1 parent de87724a

Use monotonic clock for keep alive mechanism

client.cpp
@@ -21,6 +21,7 @@ License along with FlashMQ. If not, see <https://www.gnu.org/licenses/>. @@ -21,6 +21,7 @@ License along with FlashMQ. If not, see <https://www.gnu.org/licenses/>.
21 #include <sstream> 21 #include <sstream>
22 #include <iostream> 22 #include <iostream>
23 #include <cassert> 23 #include <cassert>
  24 +#include <chrono>
24 25
25 #include "logger.h" 26 #include "logger.h"
26 27
@@ -136,7 +137,7 @@ bool Client::readFdIntoBuffer() @@ -136,7 +137,7 @@ bool Client::readFdIntoBuffer()
136 return false; 137 return false;
137 } 138 }
138 139
139 - lastActivity = time(NULL); 140 + lastActivity = std::chrono::steady_clock::now();
140 if (session) 141 if (session)
141 session->touch(lastActivity); 142 session->touch(lastActivity);
142 143
@@ -273,17 +274,22 @@ bool Client::keepAliveExpired() @@ -273,17 +274,22 @@ bool Client::keepAliveExpired()
273 if (keepalive == 0) 274 if (keepalive == 0)
274 return false; 275 return false;
275 276
  277 + const std::chrono::time_point<std::chrono::steady_clock> now = std::chrono::steady_clock::now();
  278 +
276 if (!authenticated) 279 if (!authenticated)
277 - return lastActivity + 20 < time(NULL); 280 + return lastActivity + std::chrono::seconds(20) < now;
278 281
279 - bool result = (lastActivity + (keepalive*10/5)) < time(NULL); 282 + std::chrono::seconds x(keepalive*10/5);
  283 + bool result = (lastActivity + x) < now;
280 return result; 284 return result;
281 } 285 }
282 286
283 std::string Client::getKeepAliveInfoString() const 287 std::string Client::getKeepAliveInfoString() const
284 { 288 {
285 - std::string s = "authenticated: " + std::to_string(authenticated) + ", keep-alive: " + std::to_string(keepalive) + "s, last activity "  
286 - + std::to_string(time(NULL) - lastActivity) + " seconds ago."; 289 + std::chrono::seconds secondsSinceLastActivity = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - lastActivity);
  290 +
  291 + std::string s = formatString("authenticated=%s, keep-alive=%ss, last activity=%s seconds ago.", std::to_string(authenticated).c_str(), std::to_string(keepalive).c_str(),
  292 + std::to_string(secondsSinceLastActivity.count()).c_str());
287 return s; 293 return s;
288 } 294 }
289 295
client.h
@@ -65,7 +65,7 @@ class Client @@ -65,7 +65,7 @@ class Client
65 bool disconnectWhenBytesWritten = false; 65 bool disconnectWhenBytesWritten = false;
66 bool disconnecting = false; 66 bool disconnecting = false;
67 std::string disconnectReason; 67 std::string disconnectReason;
68 - time_t lastActivity = time(NULL); 68 + std::chrono::time_point<std::chrono::steady_clock> lastActivity;
69 69
70 std::string clientid; 70 std::string clientid;
71 std::string username; 71 std::string username;
session.cpp
@@ -164,15 +164,19 @@ uint64_t Session::sendPendingQosMessages() @@ -164,15 +164,19 @@ uint64_t Session::sendPendingQosMessages()
164 return count; 164 return count;
165 } 165 }
166 166
167 -void Session::touch(time_t val) 167 +std::chrono::time_point<std::chrono::steady_clock> zeroTime;
  168 +std::chrono::seconds expireAfter(EXPIRE_SESSION_AFTER);
  169 +
  170 +void Session::touch(std::chrono::time_point<std::chrono::steady_clock> val)
168 { 171 {
169 - time_t newval = val > 0 ? val : time(NULL); 172 + std::chrono::time_point<std::chrono::steady_clock> newval = val > zeroTime ? val : std::chrono::steady_clock::now();
170 lastTouched = newval; 173 lastTouched = newval;
171 } 174 }
172 175
173 bool Session::hasExpired() 176 bool Session::hasExpired()
174 { 177 {
175 - return clientDisconnected() && (lastTouched + EXPIRE_SESSION_AFTER) < time(NULL); 178 + std::chrono::time_point<std::chrono::steady_clock> now = std::chrono::steady_clock::now();
  179 + return clientDisconnected() && (lastTouched + expireAfter) < now;
176 } 180 }
177 181
178 void Session::addIncomingQoS2MessageId(uint16_t packet_id) 182 void Session::addIncomingQoS2MessageId(uint16_t packet_id)
session.h
@@ -51,7 +51,7 @@ class Session @@ -51,7 +51,7 @@ class Session
51 std::mutex qosQueueMutex; 51 std::mutex qosQueueMutex;
52 uint16_t nextPacketId = 0; 52 uint16_t nextPacketId = 0;
53 ssize_t qosQueueBytes = 0; 53 ssize_t qosQueueBytes = 0;
54 - time_t lastTouched = time(NULL); 54 + std::chrono::time_point<std::chrono::steady_clock> lastTouched;
55 Logger *logger = Logger::getInstance(); 55 Logger *logger = Logger::getInstance();
56 56
57 public: 57 public:
@@ -67,7 +67,7 @@ public: @@ -67,7 +67,7 @@ public:
67 void writePacket(const MqttPacket &packet, char max_qos, uint64_t &count); 67 void writePacket(const MqttPacket &packet, char max_qos, uint64_t &count);
68 void clearQosMessage(uint16_t packet_id); 68 void clearQosMessage(uint16_t packet_id);
69 uint64_t sendPendingQosMessages(); 69 uint64_t sendPendingQosMessages();
70 - void touch(time_t val = 0); 70 + void touch(std::chrono::time_point<std::chrono::steady_clock> val = std::chrono::time_point<std::chrono::steady_clock>());
71 bool hasExpired(); 71 bool hasExpired();
72 72
73 void addIncomingQoS2MessageId(uint16_t packet_id); 73 void addIncomingQoS2MessageId(uint16_t packet_id);