From 9d2b16c353f183885ec23a33e064ff2044603676 Mon Sep 17 00:00:00 2001 From: Shantanu Goel Date: Mon, 18 Jun 2012 10:54:44 -0400 Subject: Add support for terminating idle connections --- src/responder/common/responder.h | 2 + src/responder/common/responder_common.c | 75 +++++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 29bfff06..6301af31 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -120,6 +120,8 @@ struct cli_ctx { int netgrent_cur; time_t pam_timeout; + + struct tevent_timer *idle; }; struct sss_cmd_table { diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c index 86582f58..e15f3916 100644 --- a/src/responder/common/responder_common.c +++ b/src/responder/common/responder_common.c @@ -94,12 +94,12 @@ static int client_destructor(struct cli_ctx *ctx) if ((ctx->cfd > 0) && close(ctx->cfd) < 0) { ret = errno; - DEBUG(SSSDBG_CRIT_FAILURE, + DEBUG(1, ("Failed to close fd [%d]: [%s]\n", ctx->cfd, strerror(ret))); } - DEBUG(SSSDBG_TRACE_INTERNAL, + DEBUG(9, ("Terminated client [%p][%d]\n", ctx, ctx->cfd)); return 0; @@ -222,12 +222,24 @@ static void client_recv(struct cli_ctx *cctx) return; } +static errno_t reset_idle_timer(struct cli_ctx *cctx); + static void client_fd_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *ptr) { + errno_t ret; struct cli_ctx *cctx = talloc_get_type(ptr, struct cli_ctx); + /* Always reset the idle timer on any activity */ + ret = reset_idle_timer(cctx); + if (ret != EOK) { + DEBUG(1, + ("Could not create idle timer for client. " + "This connection may not auto-terminate\n")); + /* Non-fatal, continue */ + } + if (flags & TEVENT_FD_READ) { client_recv(cctx); return; @@ -238,11 +250,21 @@ static void client_fd_handler(struct tevent_context *ev, } } +struct accept_fd_ctx { + struct resp_ctx *rctx; + bool is_private; +}; + +static void idle_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *data); + /* TODO: this is a copy of accept_fd_handler, maybe both can be put into on * handler. */ static void accept_priv_fd_handler(struct tevent_context *ev, - struct tevent_fd *fde, - uint16_t flags, void *ptr) + struct tevent_fd *fde, + uint16_t flags, void *ptr) { /* accept and attach new event handler */ struct resp_ctx *rctx = talloc_get_type(ptr, struct resp_ctx); @@ -371,6 +393,15 @@ static void accept_fd_handler(struct tevent_context *ev, DEBUG(4, ("Client connected!\n")); + /* Set up the idle timer */ + ret = reset_idle_timer(cctx); + if (ret != EOK) { + DEBUG(1, + ("Could not create idle timer for client. " + "This connection may not auto-terminate\n")); + /* Non-fatal, continue */ + } + return; } @@ -407,6 +438,42 @@ static int sss_monitor_init(struct resp_ctx *rctx, return EOK; } +static errno_t reset_idle_timer(struct cli_ctx *cctx) +{ + struct timeval tv; + + /* TODO: make this configurable */ + tv = tevent_timeval_current_ofs(60, 0); + + talloc_zfree(cctx->idle); + + cctx->idle = tevent_add_timer(cctx->ev, cctx, tv, idle_handler, cctx); + if (!cctx->idle) return ENOMEM; + + DEBUG(9, + ("Idle timer re-set for client [%p][%d]\n", + cctx, cctx->cfd)); + + return EOK; +} + +static void idle_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *data) +{ + /* This connection is idle. Terminate it */ + struct cli_ctx *cctx = + talloc_get_type(data, struct cli_ctx); + + DEBUG(8, + ("Terminating idle client [%p][%d]\n", + cctx, cctx->cfd)); + + /* The cli_ctx destructor will handle the rest */ + talloc_free(cctx); +} + static int sss_dp_init(struct resp_ctx *rctx, struct sbus_interface *intf, const char *cli_name, -- cgit