session BUGFIX do not mix real and monotonic time
Fixes #43
diff --git a/src/session_p.h b/src/session_p.h
index 62e07ee..a76b576 100644
--- a/src/session_p.h
+++ b/src/session_p.h
@@ -392,8 +392,8 @@
} client;
struct {
/* server side only data */
- time_t session_start; /**< time the session was created */
- time_t last_rpc; /**< time the last RPC was received on this session */
+ time_t session_start; /**< real time the session was created */
+ time_t last_rpc; /**< monotonic time (seconds) the last RPC was received on this session */
int ntf_status; /**< flag whether the session is subscribed to any stream */
pthread_mutex_t *ch_lock; /**< Call Home thread lock */
pthread_cond_t *ch_cond; /**< Call Home thread condition */
diff --git a/src/session_server.c b/src/session_server.c
index 06cfbd7..39a510f 100644
--- a/src/session_server.c
+++ b/src/session_server.c
@@ -601,6 +601,7 @@
nc_accept_inout(int fdin, int fdout, const char *username, struct nc_session **session)
{
NC_MSG_TYPE msgtype;
+ struct timespec ts_cur;
if (!server_opts.ctx) {
ERRINIT;
@@ -654,7 +655,12 @@
*session = NULL;
return msgtype;
}
- (*session)->opts.server.session_start = (*session)->opts.server.last_rpc = time(NULL);
+
+ nc_gettimespec_mono(&ts_cur);
+ (*session)->opts.server.last_rpc = ts_cur.tv_sec;
+ nc_gettimespec_real(&ts_cur);
+ (*session)->opts.server.session_start = ts_cur.tv_sec;
+
(*session)->status = NC_STATUS_RUNNING;
return msgtype;
@@ -1173,7 +1179,7 @@
* NC_PSPOLL_SSH_MSG
*/
static int
-nc_ps_poll_session(struct nc_session *session, time_t now, char *msg)
+nc_ps_poll_session(struct nc_session *session, time_t now_mono, char *msg)
{
struct pollfd pfd;
int r, ret;
@@ -1183,7 +1189,7 @@
/* check timeout first */
if (!(session->flags & NC_SESSION_CALLHOME) && !session->opts.server.ntf_status && server_opts.idle_timeout
- && (now >= session->opts.server.last_rpc + server_opts.idle_timeout)) {
+ && (now_mono >= session->opts.server.last_rpc + server_opts.idle_timeout)) {
sprintf(msg, "session idle timeout elapsed");
session->status = NC_STATUS_INVALID;
session->term_reason = NC_SESSION_TERM_TIMEOUT;
@@ -1480,7 +1486,7 @@
cur_ps_session->state = NC_PS_STATE_NONE;
}
} else {
- cur_session->opts.server.last_rpc = time(NULL);
+ cur_session->opts.server.last_rpc = ts_cur.tv_sec;
/* process RPC, not needed afterwards */
ret |= nc_server_send_reply(cur_session, rpc);
@@ -1850,6 +1856,7 @@
int sock, ret;
char *host = NULL;
uint16_t port, bind_idx;
+ struct timespec ts_cur;
if (!server_opts.ctx) {
ERRINIT;
@@ -1962,7 +1969,11 @@
*session = NULL;
return msgtype;
}
- (*session)->opts.server.session_start = (*session)->opts.server.last_rpc = time(NULL);
+
+ nc_gettimespec_mono(&ts_cur);
+ (*session)->opts.server.last_rpc = ts_cur.tv_sec;
+ nc_gettimespec_real(&ts_cur);
+ (*session)->opts.server.session_start = ts_cur.tv_sec;
(*session)->status = NC_STATUS_RUNNING;
return msgtype;
@@ -2624,6 +2635,7 @@
{
NC_MSG_TYPE msgtype;
int sock, ret;
+ struct timespec ts_cur;
sock = nc_sock_connect(endpt->address, endpt->port);
if (sock < 0) {
@@ -2698,7 +2710,11 @@
if (msgtype != NC_MSG_HELLO) {
goto fail;
}
- (*session)->opts.server.session_start = (*session)->opts.server.last_rpc = time(NULL);
+
+ nc_gettimespec_mono(&ts_cur);
+ (*session)->opts.server.last_rpc = ts_cur.tv_sec;
+ nc_gettimespec_real(&ts_cur);
+ (*session)->opts.server.session_start = ts_cur.tv_sec;
(*session)->status = NC_STATUS_RUNNING;
return msgtype;
@@ -2793,6 +2809,7 @@
idle_timeout = client->conn.period.idle_timeout;
}
+ nc_gettimespec_mono(&ts);
if (!session->opts.server.ntf_status && idle_timeout && (ts.tv_sec >= session->opts.server.last_rpc + idle_timeout)) {
VRB("Call Home client \"%s\" session %u: session idle timeout elapsed.", client->name, session->id);
session->status = NC_STATUS_INVALID;
diff --git a/src/session_server_ssh.c b/src/session_server_ssh.c
index f48bee6..b46bf56 100644
--- a/src/session_server_ssh.c
+++ b/src/session_server_ssh.c
@@ -22,6 +22,7 @@
#include <shadow.h>
#include <crypt.h>
#include <errno.h>
+#include <time.h>
#include "session_server.h"
#include "session_server_ch.h"
@@ -1481,6 +1482,7 @@
{
NC_MSG_TYPE msgtype;
struct nc_session *new_session = NULL;
+ struct timespec ts_cur;
if (!orig_session) {
ERRARG("orig_session");
@@ -1522,7 +1524,10 @@
return msgtype;
}
- new_session->opts.server.session_start = new_session->opts.server.last_rpc = time(NULL);
+ nc_gettimespec_real(&ts_cur);
+ new_session->opts.server.session_start = ts_cur.tv_sec;
+ nc_gettimespec_mono(&ts_cur);
+ new_session->opts.server.last_rpc = ts_cur.tv_sec;
new_session->status = NC_STATUS_RUNNING;
*session = new_session;
@@ -1535,6 +1540,7 @@
uint8_t q_id;
NC_MSG_TYPE msgtype;
struct nc_session *new_session = NULL, *cur_session;
+ struct timespec ts_cur;
uint16_t i;
if (!ps) {
@@ -1591,7 +1597,10 @@
return msgtype;
}
- new_session->opts.server.session_start = new_session->opts.server.last_rpc = time(NULL);
+ nc_gettimespec_real(&ts_cur);
+ new_session->opts.server.session_start = ts_cur.tv_sec;
+ nc_gettimespec_mono(&ts_cur);
+ new_session->opts.server.last_rpc = ts_cur.tv_sec;
new_session->status = NC_STATUS_RUNNING;
*session = new_session;