Add a timeout to side requests so they do not hang forever.

Tested with SIGSTOPping sssd_be and monitor and then waiting for the
request and later the idle timer to fire. Seem to work as expected here.

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York
>From 32f03cebf2570540c9d087c5d6d8fd8e46ec583e Mon Sep 17 00:00:00 2001
From: Simo Sorce <[email protected]>
Date: Fri, 14 Dec 2012 14:59:21 -0500
Subject: [PATCH] responder_dp: Add timeout to side requets

This is an additional proteciont in case the provider misbheaves to avoid
having requests pending forever.

Fixes: https://fedorahosted.org/sssd/ticket/1717
---
 src/responder/common/responder_dp.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c
index ecd5f39cd2aeb5e46f590a44fd76cf3ead65ac49..d15ca4dc9108d410cf750b2685e27fb56fb520a7 100644
--- a/src/responder/common/responder_dp.c
+++ b/src/responder/common/responder_dp.c
@@ -45,7 +45,6 @@ struct sss_dp_req {
 
     hash_key_t *key;
 
-    struct tevent_timer *tev;
     struct sss_dp_callback *cb_list;
 
     dbus_uint16_t dp_err;
@@ -126,6 +125,15 @@ static int sss_dp_req_destructor(void *ptr)
     return 0;
 }
 
+static void sss_dp_req_timeout(struct tevent_context *ev,
+                               struct tevent_timer *te,
+                               struct timeval t, void *ptr)
+{
+    /* ptr is a pointer to sidereq */
+    /* Just free it to kill all waiting requests when the timeout fires */
+    talloc_zfree(ptr);
+}
+
 void handle_requests_after_reconnect(struct resp_ctx *rctx)
 {
     int ret;
@@ -252,6 +260,8 @@ sss_dp_issue_request(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx,
     struct tevent_req *sidereq;
     struct sss_dp_req *sdp_req;
     struct sss_dp_callback *cb;
+    struct tevent_timer *te;
+    struct timeval tv;
     DBusMessage *msg;
     TALLOC_CTX *tmp_ctx = NULL;
     errno_t ret;
@@ -306,6 +316,20 @@ sss_dp_issue_request(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx,
         }
         tevent_req_set_callback(sidereq, sss_dp_req_done, NULL);
 
+        /* add timeout handling so we do not hang forever should something
+         * go worng in the provider. Use 2 sec less than the idle timeout to
+         * give it a chance to reply to the client before closing the
+         * connection. */
+        tv = tevent_timeval_current_ofs(rctx->client_idle_timeout - 2, 0);
+        te = tevent_add_timer(rctx->ev, sidereq, tv,
+                              sss_dp_req_timeout, sidereq);
+        if (!te) {
+            /* Nothing much we can do */
+            DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory?!\n"));
+            ret = ENOMEM;
+            goto fail;
+        }
+
         /* We should now be able to find the sdp_req in the hash table */
         hret = hash_lookup(rctx->dp_request_table, key, &value);
         if (hret != HASH_SUCCESS) {
-- 
1.8.0.1

_______________________________________________
sssd-devel mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to