summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFabiano Fidêncio <fidencio@redhat.com>2016-11-30 16:00:33 +0100
committerLukas Slebodnik <lslebodn@redhat.com>2017-01-23 18:46:37 +0100
commit560daa14ef013aa14e2aedeea10b07f623d84ec8 (patch)
treea98a5df150b1bf36ff3b70458ec4f50ab59ce902 /src
parent151a6de4793e0045a7085d4d72b975947662e566 (diff)
downloadsssd-560daa14ef013aa14e2aedeea10b07f623d84ec8.tar.gz
sssd-560daa14ef013aa14e2aedeea10b07f623d84ec8.tar.xz
sssd-560daa14ef013aa14e2aedeea10b07f623d84ec8.zip
RESPONDER: Change how client timeout is calculated
Taking Pavel Březina's suggestion, let's avoid always re-creating the idle timer and go for a simpler and not so precise approach where we store the time of the last operation done and then have a simple periodic timer that fires each "client_idle_time/2" and there it checks whether the "current time - last request time > client_idle_time". As said, it won't be as precise as the way done currently but it will save us lots of memory operations. Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com> Reviewed-by: Pavel Březina <pbrezina@redhat.com> Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/responder/common/responder.h1
-rw-r--r--src/responder/common/responder_common.c40
2 files changed, 33 insertions, 8 deletions
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index 9c8b5f942..d1fa532be 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -152,6 +152,7 @@ struct cli_ctx {
void *state_ctx;
struct tevent_timer *idle;
+ time_t last_request_time;
};
struct sss_cmd_table {
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index d46571d2b..67922bfcc 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -461,6 +461,8 @@ static void client_fd_handler(struct tevent_context *ev,
}
}
+static errno_t setup_client_idle_timer(struct cli_ctx *cctx);
+
struct accept_fd_ctx {
struct resp_ctx *rctx;
bool is_private;
@@ -587,7 +589,7 @@ static void accept_fd_handler(struct tevent_context *ev,
cctx->rctx = rctx;
/* Set up the idle timer */
- ret = reset_client_idle_timer(cctx);
+ ret = setup_client_idle_timer(cctx);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Could not create idle timer for client. "
@@ -607,22 +609,44 @@ static void client_idle_handler(struct tevent_context *ev,
struct timeval current_time,
void *data)
{
- /* This connection is idle. Terminate it */
+ time_t now = time(NULL);
struct cli_ctx *cctx = talloc_get_type(data, struct cli_ctx);
- DEBUG(SSSDBG_TRACE_INTERNAL,
- "Terminating idle client [%p][%d]\n",
- cctx, cctx->cfd);
+ if (cctx->last_request_time > now) {
+ DEBUG(SSSDBG_IMPORTANT_INFO,
+ "Time shift detected, re-scheduling the client timeout\n");
+ goto end;
+ }
+
+ if ((now - cctx->last_request_time) > cctx->rctx->client_idle_timeout) {
+ /* This connection is idle. Terminate it */
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ "Terminating idle client [%p][%d]\n",
+ cctx, cctx->cfd);
+
+ /* The cli_ctx destructor will handle the rest */
+ talloc_free(cctx);
+ return;
+ }
- /* The cli_ctx destructor will handle the rest */
- talloc_free(cctx);
+end:
+ setup_client_idle_timer(cctx);
}
errno_t reset_client_idle_timer(struct cli_ctx *cctx)
{
+ cctx->last_request_time = time(NULL);
+
+ return EOK;
+}
+
+static errno_t setup_client_idle_timer(struct cli_ctx *cctx)
+{
+ time_t now = time(NULL);
struct timeval tv =
- tevent_timeval_current_ofs(cctx->rctx->client_idle_timeout, 0);
+ tevent_timeval_current_ofs(cctx->rctx->client_idle_timeout/2, 0);
+ cctx->last_request_time = now;
talloc_zfree(cctx->idle);
cctx->idle = tevent_add_timer(cctx->ev, cctx, tv, client_idle_handler, cctx);