diff options
| author | Fabiano Fidêncio <fidencio@redhat.com> | 2016-11-30 16:00:33 +0100 |
|---|---|---|
| committer | Lukas Slebodnik <lslebodn@redhat.com> | 2017-01-23 18:46:37 +0100 |
| commit | 560daa14ef013aa14e2aedeea10b07f623d84ec8 (patch) | |
| tree | a98a5df150b1bf36ff3b70458ec4f50ab59ce902 /src | |
| parent | 151a6de4793e0045a7085d4d72b975947662e566 (diff) | |
| download | sssd-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.h | 1 | ||||
| -rw-r--r-- | src/responder/common/responder_common.c | 40 |
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); |
