]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
provide for detached / detachable fake requests
authorAlan T. DeKok <aland@freeradius.org>
Mon, 11 Sep 2017 19:18:08 +0000 (15:18 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 11 Sep 2017 19:22:20 +0000 (15:22 -0400)
src/include/radiusd.h
src/main/request.c

index 40619c1383425fb5ef1b283868bc70f1dae17f11..c2b0ccbbb9df1d5e9c467be0ca6b0f22afafbcfe 100644 (file)
@@ -403,6 +403,9 @@ char                *rad_ajoin(TALLOC_CTX *ctx, char const **argv, int argc, char c);
 REQUEST                *request_alloc(TALLOC_CTX *ctx);
 REQUEST                *request_alloc_fake(REQUEST *oldreq);
 REQUEST                *request_alloc_proxy(REQUEST *request);
+REQUEST                *request_alloc_detachable(REQUEST *request);
+int            request_detach(REQUEST *fake);
+
 int            request_data_add(REQUEST *request, void const *unique_ptr, int unique_int, void *opaque,
                                 bool free_on_replace, bool free_on_parent, bool persist);
 void           *request_data_get(REQUEST *request, void const *unique_ptr, int unique_int);
index 27a252ddf13ff3d94e45f58e85c589b84a204783..98f835dd5e70a71aeada9614a789a2e8a8bdedab 100644 (file)
@@ -130,20 +130,8 @@ REQUEST *request_alloc(TALLOC_CTX *ctx)
        return request;
 }
 
-
-/*
- *     Create a new REQUEST, based on an old one.
- *
- *     This function allows modules to inject fake requests
- *     into the server, for tunneled protocols like TTLS & PEAP.
- */
-REQUEST *request_alloc_fake(REQUEST *request)
+static REQUEST *request_init_fake(REQUEST *request, REQUEST *fake)
 {
-       REQUEST *fake;
-
-       fake = request_alloc(request);
-       if (!fake) return NULL;
-
        fake->number = request->number;
        fake->seq_start = request->seq_start;
 
@@ -218,6 +206,74 @@ REQUEST *request_alloc_fake(REQUEST *request)
        return fake;
 }
 
+
+/*
+ *     Create a new REQUEST, based on an old one.
+ *
+ *     This function allows modules to inject fake requests
+ *     into the server, for tunneled protocols like TTLS & PEAP.
+ */
+REQUEST *request_alloc_fake(REQUEST *request)
+{
+       REQUEST *fake;
+
+       fake = request_alloc(request);
+       if (!fake) return NULL;
+
+       return request_init_fake(request, fake);
+}
+
+/** Allocate a fake request which is detachable from the parent.
+ * i.e. if the parent goes away, sometimes the child MAY continue to
+ * run.
+ *
+ */
+REQUEST *request_alloc_detachable(REQUEST *request)
+{
+       REQUEST *fake;
+
+       fake = request_alloc(NULL);
+       if (!fake) return NULL;
+
+       if (!request_init_fake(request, fake)) return NULL;
+
+       /*
+        *      Associate the child with the parent, using the child's
+        *      pointer as a unique identifier.  Free it if the parent
+        *      goes away, but don't persist it across
+        *      challenge-response boundaries.
+        */
+       if (request_data_add(request, fake, 0, fake, true, true, false) < 0) {
+               talloc_free(fake);
+               return NULL;
+       }
+
+       return fake;
+}
+
+
+/** Detach a detachable request.
+ *
+ *  @note the caller still has to set fake->async->detached
+ */
+int request_detach(REQUEST *fake)
+{
+       REQUEST *request = fake->parent;
+
+       rad_assert(request != NULL);
+       rad_assert(talloc_parent(fake) != request);
+
+       /*
+        *      Unlink the child from the parent.
+        */
+       if (!request_data_get(request, fake, 0)) {
+               return -1;
+       }
+
+       fake->parent = NULL;
+       return 0;
+}
+
 REQUEST *request_alloc_proxy(REQUEST *request)
 {
        request->proxy = request_alloc(request);