Coverage Report

Created: 2026-08-08 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/lib/unlang/io.c
Line
Count
Source
1
/*
2
 *   This program is free software; you can redistribute it and/or modify
3
 *   it under the terms of the GNU General Public License as published by
4
 *   the Free Software Foundation; either version 2 of the License, or
5
 *   (at your option) any later version.
6
 *
7
 *   This program is distributed in the hope that it will be useful,
8
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 *   GNU General Public License for more details.
11
 *
12
 *   You should have received a copy of the GNU General Public License
13
 *   along with this program; if not, write to the Free Software
14
 *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15
 */
16
17
/**
18
 * $Id: 9d9fdda106a3317961e23baa3a4b2d9c6b20b24d $
19
 *
20
 * @file unlang/io.c
21
 * @brief Shim I/O worker functions for running fake requests.
22
 *
23
 * @copyright 2006-2019 The FreeRADIUS server project
24
 */
25
RCSID("$Id: 9d9fdda106a3317961e23baa3a4b2d9c6b20b24d $")
26
27
#include <freeradius-devel/io/listen.h>
28
#include "unlang_priv.h"
29
30
/** Allocate a child request based on the parent.
31
 *
32
 * @param[in] parent    spawning the child request.
33
 * @param[in] namespace   the child request operates in. If NULL the parent's namespace is used.
34
 * @param[in] detachable  Allow/disallow the child to be detached.
35
 * @return
36
 *      - The new child request.
37
 *  - NULL on error.
38
 */
39
request_t *unlang_io_subrequest_alloc(request_t *parent, fr_dict_t const *namespace, bool detachable)
40
0
{
41
0
  request_t   *child;
42
0
  char const    *server;
43
44
0
  if (!namespace) namespace = parent->proto_dict;
45
46
  /*
47
   *  A child cannot refer to local variables in the parent context.
48
   */
49
0
  fr_assert(fr_dict_proto_dict(namespace) == namespace);
50
51
0
  child = request_local_alloc_internal(detachable ? NULL : parent,
52
0
               (&(request_init_args_t){
53
0
            .parent = parent,
54
0
            .namespace = namespace,
55
0
            .detachable = detachable
56
0
               }));
57
0
  if (!child) return NULL;
58
59
  /*
60
   *  Child gets its parent's interpreter
61
   */
62
0
  ((unlang_stack_t *)child->stack)->intp = ((unlang_stack_t *)parent->stack)->intp;
63
64
  /*
65
   *  Push the child, and set its top frame to be true.
66
   */
67
0
  child->log.indent.unlang = parent->log.indent.unlang;
68
69
  /*
70
   *  Initialize some basic information for the child.
71
   */
72
0
  child->number = parent->number;
73
74
  /*
75
   *  Initialize all of the async fields.
76
   */
77
0
  child->async = talloc_zero(child, fr_async_t);
78
79
0
#define COPY_FIELD(_x) child->async->_x = parent->async->_x
80
0
  COPY_FIELD(recv_time);
81
0
  fr_assert(request_is_internal(child));
82
83
0
  server = unlang_interpret_virtual_server(parent);
84
0
  if (server) {
85
0
    child->packet->socket = (fr_socket_t) {
86
0
      .af = AF_FR_VIRTUAL_SERVER,
87
0
      .virtual.server = server,
88
0
    };
89
0
    child->reply->socket = child->packet->socket;
90
0
  }
91
92
0
  REQUEST_VERIFY(child);
93
94
0
  return child;
95
0
}