The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
client.c
Go to the documentation of this file.
1/*
2 * @copyright (c) 2016, Network RADIUS SAS (license@networkradius.com)
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Network RADIUS SAS nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27#define LOG_PREFIX "sigtran"
28
29#include <freeradius-devel/server/base.h>
30#include <freeradius-devel/util/debug.h>
31#include <freeradius-devel/protocol/eap/aka-sim/dictionary.h>
32#include <freeradius-devel/server/module_rlm.h>
33
34#include "attrs.h"
35#include "sigtran.h"
36
37static pthread_mutex_t ctrl_pipe_mutex = PTHREAD_MUTEX_INITIALIZER;
38
39/**
40 * $Id: b5472d06837f7c320206414c7bbc7ae0df871bc9 $
41 * @file rlm_sigtran/client.c
42 * @brief Talk to the event loop.
43 */
45{
46 ssize_t len;
47 void *ptr;
48
49 if (write(fd, &txn, sizeof(txn)) < 0) {
50 ERROR("worker - ctrl_pipe (%i) write failed: %s", fd, fr_syserror(errno));
51 return -1;
52 }
53
54 /*
55 * Block until libosmo responds
56 */
57 len = read(fd, &ptr, sizeof(ptr));
58 if (len < 0) {
59 ERROR("worker - ctrl_pipe (%i) read failed : %s", fd, fr_syserror(errno));
60 return -1;
61 }
62
63 if (len != sizeof(ptr)) {
64 ERROR("worker - ctrl_pipe (%i) data too short, expected %zu bytes, got %zi bytes",
65 fd, sizeof(ptr), len);
66 return -1;
67 }
68
69 if (ptr != txn) {
70 ERROR("worker - ctrl_pipe (%i) response ptr (%p) does not match request (%p)", fd, ptr, txn);
71 return -1;
72 }
73
74 /*
75 * Check talloc header is still OK
76 */
77 talloc_get_type_abort(ptr, sigtran_transaction_t);
78
79 return 0;
80}
81
83{
84 int ret;
85
86 fr_assert(ctrl_pipe[0] >= 0);
87
88 pthread_mutex_lock(&ctrl_pipe_mutex);
90 pthread_mutex_unlock(&ctrl_pipe_mutex);
91
92 return ret;
93}
94
95/** This should never happen
96 *
97 */
98static void _sigtran_pipe_error(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, int fd_errno, UNUSED void *uctx)
99{
100 ERROR("worker - ctrl_pipe (%i) read failed : %s", fd, fr_syserror(fd_errno));
101 fr_assert(0);
102}
103
104/** Drain any data we received
105 *
106 * We don't care about this data, we just don't want the kernel to
107 * signal the other side that our read buffer's full.
108 */
109static void _sigtran_pipe_read(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, UNUSED void *uctx)
110{
111 ssize_t len;
112 void *ptr;
114
115 len = read(fd, &ptr, sizeof(ptr));
116 if (len < 0) {
117 ERROR("worker - ctrl_pipe (%i) read failed : %s", fd, fr_syserror(errno));
118 return;
119 }
120
121 if (len != sizeof(ptr)) {
122 ERROR("worker - ctrl_pipe (%i) data too short, expected %zu bytes, got %zi bytes",
123 fd, sizeof(ptr), len);
124 return;
125 }
126
127 /*
128 * Check talloc header is still OK
129 */
130 txn = talloc_get_type_abort(ptr, sigtran_transaction_t);
131 if (txn->ctx.defunct) return; /* Request was stopped */
132
133 fr_assert(txn->ctx.request);
134 unlang_interpret_mark_runnable(txn->ctx.request); /* Continue processing */
135}
136
137/** Called by a new thread to register a new req_pipe
138 *
139 * @return
140 * - The client side of the req_pipe on success.
141 * - -1 on error.
142 */
144{
145 int req_pipe[2] = { -1, -1 };
147
148 /*
149 * Create the pipe on our side, and pass over
150 * the remote end to be registered.
151 */
152 if (socketpair(AF_UNIX, SOCK_STREAM, 0, req_pipe) < 0) {
153 ERROR("worker - Failed creating req_pipe: %s", fr_syserror(errno));
154 return -1;
155 }
156
157 fr_assert((req_pipe[0] >= 0) && (req_pipe[1] >= 0));
158
159 txn = talloc_zero(NULL, sigtran_transaction_t);
161 txn->request.data = &req_pipe[1];
162
163 if ((sigtran_client_do_ctrl_transaction(txn) < 0) || (txn->response.type != SIGTRAN_RESPONSE_OK)) {
164 ERROR("worker - Failed registering thread");
165 error:
166 close(req_pipe[0]);
167 close(req_pipe[1]);
168 talloc_free(txn);
169 return -1;
170 }
171 DEBUG3("worker - Thread register acked by osmocom thread");
172 talloc_free(txn);
173
174 /*
175 * Read data coming back on the pipe,
176 * and resume requests which are
177 * waiting.
178 */
179 if (fr_event_fd_insert(NULL, NULL, el, req_pipe[0], _sigtran_pipe_read, NULL, _sigtran_pipe_error, NULL) < 0) {
180 ERROR("worker - Failed listening on osmocom pipe");
181 goto error;
182 }
183
184 return req_pipe[0];
185}
186
187/** Signal that libosmo should unregister the other side of the pipe
188 *
189 * @param[in] el the request pipe was registered to.
190 * @param[in] req_pipe_fd The rlm_sigtran side of the req_pipe.
191 */
193{
195
196 txn = talloc_zero(NULL, sigtran_transaction_t);
198
199 /*
200 * The signal to unregister *MUST* be sent on the
201 * request pipe itself, so that the osmocom thread
202 * knows *WHICH* pipe to close on its side.
203 */
204 if ((sigtran_client_do_transaction(req_pipe_fd, txn) < 0) || (txn->response.type != SIGTRAN_RESPONSE_OK)) {
205 ERROR("worker - Failed unregistering thread");
206 talloc_free(txn);
207 return -1;
208 }
209 DEBUG3("worker - Thread unregister acked by osmocom thread");
210 talloc_free(txn);
211
213 close(req_pipe_fd);
214
215 return 0;
216}
217
218/** Create a new connection
219 *
220 * Register the required links for a connection.
221 *
222 * @todo Return struct representing the connection
223 */
225{
227
228 txn = talloc_zero(NULL, sigtran_transaction_t);
230 memcpy(&txn->request.data, &conn_conf, sizeof(txn->request.data));
231
232 if ((sigtran_client_do_ctrl_transaction(txn) < 0) || (txn->response.type != SIGTRAN_RESPONSE_OK)) {
233 ERROR("worker - Failed bringing up link");
234 talloc_free(txn);
235 return -1;
236 }
237 DEBUG3("worker - Link up acked by osmocom thread");
238 *out = talloc_get_type_abort(txn->response.data, sigtran_conn_t);
239 talloc_free(txn);
240
241 return 0;
242}
243
244/** Destroy a connection
245 *
246 * Gracefully shutdown the links for a connection and free it.
247 *
248 */
250{
252
253 if (!*conn || !(*conn)->mtp3_link) return 0; /* Ignore if there is no link */
254
255 txn = talloc_zero(NULL, sigtran_transaction_t);
257 memcpy(&txn->request.data, conn, sizeof(txn->request.data));
258
259 if ((sigtran_client_do_ctrl_transaction(txn) < 0) || (txn->response.type != SIGTRAN_RESPONSE_OK)) {
260 ERROR("worker - Failed taking down the link");
261 talloc_free(txn);
262 return -1;
263 }
264 DEBUG3("worker - Link down acked by osmocom thread");
265 talloc_free(txn);
266 *conn = NULL;
267
268 return 0;
269}
270
271static void sigtran_client_signal(module_ctx_t const *mctx, UNUSED request_t *request, UNUSED fr_signal_t action)
272{
273 sigtran_transaction_t *txn = talloc_get_type_abort(mctx->rctx, sigtran_transaction_t);
274
275 txn->ctx.defunct = true; /* Mark the transaction up as needing to be freed */
276 txn->ctx.request = NULL; /* remove the link to the (now dead) request */
277}
278
280{
281 sigtran_transaction_t *txn = talloc_get_type_abort(mctx->rctx, sigtran_transaction_t);
282 rlm_rcode_t rcode;
283 fr_assert(request == txn->ctx.request);
284
285 /*
286 * Process response
287 */
288 switch (txn->response.type) {
290 {
291 unsigned int i = 0;
292 fr_pair_t *vp;
293 sigtran_vector_t *vec;
294 sigtran_map_send_auth_info_res_t *res = talloc_get_type_abort(txn->response.data,
296
297 for (vec = res->vector; vec; vec = vec->next) {
298 switch (vec->type) {
300 fr_assert(vec->sim.rand);
301 fr_assert(vec->sim.sres);
302 fr_assert(vec->sim.kc);
303
304 RDEBUG2("SIM auth vector %i", i);
305 RINDENT();
306 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_rand));
307 MEM(fr_pair_value_memdup_buffer(vp, vec->sim.rand, true) == 0);
308 TALLOC_FREE(vec->sim.rand);
309 RDEBUG2("control.%pP", vp);
310 fr_pair_append(&request->control_pairs, vp);
311
312 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_sres));
313 MEM(fr_pair_value_memdup_buffer(vp, vec->sim.sres, true) == 0);
314 TALLOC_FREE(vec->sim.sres);
315 RDEBUG2("control.%pP", vp);
316 fr_pair_append(&request->control_pairs, vp);
317
318 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_kc));
319 MEM(fr_pair_value_memdup_buffer(vp, vec->sim.kc, true) == 0);
320 TALLOC_FREE(vec->sim.kc);
321 RDEBUG2("control.%pP", vp);
322 fr_pair_append(&request->control_pairs, vp);
323 REXDENT();
324
325 i++;
326 break;
327
329 fr_assert(vec->umts.rand);
330 fr_assert(vec->umts.xres);
331 fr_assert(vec->umts.ck);
332 fr_assert(vec->umts.ik);
333 fr_assert(vec->umts.authn);
334
335 RDEBUG2("UMTS auth vector %i", i);
336 RINDENT();
337 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_rand));
338 MEM(fr_pair_value_memdup_buffer(vp, vec->umts.rand, true) == 0);
339 TALLOC_FREE(vec->umts.rand);
340 RDEBUG2("control.%pP", vp);
341 fr_pair_append(&request->control_pairs, vp);
342
343 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_xres));
344 MEM(fr_pair_value_memdup_buffer(vp, vec->umts.xres, true) == 0);
345 TALLOC_FREE(vec->umts.xres);
346 RDEBUG2("control.%pP", vp);
347 fr_pair_append(&request->control_pairs, vp);
348
349 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_ck));
350 MEM(fr_pair_value_memdup_buffer(vp, vec->umts.ck, true) == 0);
351 TALLOC_FREE(vec->umts.ck);
352 RDEBUG2("control.%pP", vp);
353 fr_pair_append(&request->control_pairs, vp);
354
355 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_ik));
356 MEM(fr_pair_value_memdup_buffer(vp, vec->umts.ik, true) == 0);
357 TALLOC_FREE(vec->umts.ik);
358 RDEBUG2("control.%pP", vp);
359 fr_pair_append(&request->control_pairs, vp);
360
361 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_autn));
362 MEM(fr_pair_value_memdup_buffer(vp, vec->umts.authn, true) == 0);
363 TALLOC_FREE(vec->umts.authn);
364 RDEBUG2("control.%pP", vp);
365 fr_pair_append(&request->control_pairs, vp);
366 REXDENT();
367
368 i++;
369 break;
370 }
371 }
372 rcode = RLM_MODULE_OK;
373 }
374 break;
375
377 rcode = RLM_MODULE_NOOP;
378 break;
379
381 rcode = RLM_MODULE_NOTFOUND;
382 break;
383
384 default:
385 fr_assert(0);
387
389 rcode = RLM_MODULE_FAIL;
390 break;
391 }
392 talloc_free(txn);
393
394 RETURN_UNLANG_RCODE(rcode);
395}
396
397/** Create a MAP_SEND_AUTH_INFO request
398 *
399 * @param p_result Where to write the result.
400 * @param inst of rlm_sigtran.
401 * @param request The current request.
402 * @param conn current connection.
403 * @param fd file descriptor on which the transaction is done
404 */
406 sigtran_conn_t const *conn, int fd)
407{
410 char *imsi;
411 size_t len;
412
413 fr_assert((fd != ctrl_pipe[0]) && (fd != ctrl_pipe[1]));
414
415 txn = talloc_zero(NULL, sigtran_transaction_t);
417
418 req = talloc(txn, sigtran_map_send_auth_info_req_t);
419 req->conn = conn;
420
421 if (tmpl_aexpand(request, &req->version, request, inst->conn_conf.map_version, NULL, NULL) < 0) {
422 ERROR("Failed retrieving version");
423 error:
424 talloc_free(txn);
426 }
427
428 switch (req->version) {
429 case 2:
430 case 3:
431 break;
432
433 default:
434 REDEBUG("%i is not a valid version", req->version);
435 goto error;
436 }
437
438 txn->request.data = req;
439 txn->ctx.request = request;
440
441 if (tmpl_aexpand(req, &imsi, request, inst->imsi, NULL, NULL) < 0) {
442 REDEBUG("Failed retrieving IMSI");
443 goto error;
444 }
445
446 len = talloc_strlen(imsi);
447 if ((len != 16) && (len != 15)) {
448 REDEBUG("IMSI must be 15 or 16 digits got %zu digits", len);
449 goto error;
450 }
451
452 if (sigtran_ascii_to_tbcd(req, &req->imsi, imsi) < 0) {
453 REDEBUG("Failed converting ASCII to BCD");
454 goto error;
455 }
456
457 if (RDEBUG_ENABLED3) {
458 RDEBUG3("Sending MAPv%u request with IMSI \"%pV\" (TBCD %pV)",
460 } else if (RDEBUG_ENABLED2) {
461 RDEBUG2("Sending MAPv%u request with IMSI \"%pV\"", req->version, fr_box_strvalue_buffer(imsi));
462 }
463
464 /*
465 * FIXME - We shouldn't assume the pipe is always writable
466 */
467 if (write(fd, &txn, sizeof(txn)) < 0) {
468 REDEBUG("worker - ctrl_pipe (%i) write failed: %s", fd, fr_syserror(errno));
469 goto error;
470 }
471
473}
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
Definition build.h:343
#define UNUSED
Definition build.h:336
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:40
#define fr_event_fd_insert(...)
Definition event.h:247
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
Definition event.h:83
talloc_free(hp)
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
Definition interpret.c:1990
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_xres
Definition base.c:101
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_sres
Definition base.c:98
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_ik
Definition base.c:75
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_autn
Definition base.c:61
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_rand
Definition base.c:94
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_kc
Definition base.c:80
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_ck
Definition base.c:65
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition log.h:455
#define DEBUG3(_fmt,...)
Definition log.h:266
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Definition log.h:347
#define RDEBUG3(fmt,...)
Definition log.h:355
#define RINDENT()
Indent R* messages by one level.
Definition log.h:442
int fr_event_fd_delete(fr_event_list_t *el, int fd, fr_event_filter_t filter)
Remove a file descriptor from the event loop.
Definition event.c:1203
Stores all information relating to an event list.
Definition event.c:377
long int ssize_t
void * rctx
Resume ctx that a module previously set.
Definition module_ctx.h:45
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
int ctrl_pipe[2]
Definition event.c:76
int fr_pair_value_memdup_buffer(fr_pair_t *vp, uint8_t const *src, bool tainted)
Copy data from a talloced buffer into an "octets" data type.
Definition pair.c:2992
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition pair.c:1352
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
Definition pair.c:290
VQP attributes.
#define fr_assert(_expr)
Definition rad_assert.h:37
#define REDEBUG(fmt,...)
#define RDEBUG_ENABLED2()
#define RDEBUG2(fmt,...)
#define RETURN_UNLANG_RCODE(_rcode)
Definition rcode.h:61
#define RETURN_UNLANG_FAIL
Definition rcode.h:63
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:44
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:49
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:48
@ RLM_MODULE_NOTFOUND
User not found.
Definition rcode.h:53
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:54
#define tmpl_aexpand(_ctx, _out, _request, _vpt, _escape, _escape_ctx)
Expand a tmpl to a C type, allocing a new buffer to hold the string.
Definition tmpl.h:1064
fr_signal_t
Signals that can be generated/processed by request signal handlers.
Definition signal.h:38
@ FR_SIGNAL_CANCEL
Request has been cancelled.
Definition signal.h:40
int sigtran_ascii_to_tbcd(TALLOC_CTX *ctx, uint8_t **out, char const *digits)
Definition sigtran.c:93
Declarations for various sigtran functions.
@ SIGTRAN_VECTOR_TYPE_UMTS_QUINTUPLETS
RAND, XRES, CK, IK, AUTN.
Definition sigtran.h:66
@ SIGTRAN_VECTOR_TYPE_SIM_TRIPLETS
RAND, SRES, Kc.
Definition sigtran.h:65
@ SIGTRAN_REQUEST_THREAD_REGISTER
New worker thread to register.
Definition sigtran.h:43
@ SIGTRAN_REQUEST_MAP_SEND_AUTH_INFO
Request auth info.
Definition sigtran.h:47
@ SIGTRAN_REQUEST_LINK_DOWN
Take down a link.
Definition sigtran.h:46
@ SIGTRAN_REQUEST_THREAD_UNREGISTER
Worker thread to unregister.
Definition sigtran.h:44
@ SIGTRAN_REQUEST_LINK_UP
Bring up a link.
Definition sigtran.h:45
@ SIGTRAN_RESPONSE_OK
Request succeeded.
Definition sigtran.h:55
@ SIGTRAN_RESPONSE_NOOP
Request did nothing.
Definition sigtran.h:56
@ SIGTRAN_RESPONSE_FAIL
Request failed.
Definition sigtran.h:58
@ SIGTRAN_RESPONSE_NOTFOUND
User or device Not found.
Definition sigtran.h:57
struct sigtran_transaction::@187 request
uint8_t * imsi
BCD encoded IMSI.
Definition sigtran.h:193
struct sigtran_transaction::@189 ctx
struct sigtran_transaction::@188 response
sigtran_vector_type_t type
Type of vector returned.
Definition sigtran.h:218
sigtran_conn_t const * conn
Connection to send request on.
Definition sigtran.h:192
uint8_t version
Application context version.
Definition sigtran.h:194
struct mtp_link * mtp3_link
Definition sigtran.h:185
sigtran_vector_t * vector
Linked list of vectors.
Definition sigtran.h:228
sigtran_vector_t * next
Next vector in list.
Definition sigtran.h:220
Represents a connection to a remote SS7 entity.
Definition sigtran.h:180
Configures a M3UA/MTP3/SCCP stack.
Definition sigtran.h:143
MAP send auth info request.
Definition sigtran.h:191
MAP send auth info response.
Definition sigtran.h:226
Request and response from the event loop.
Definition sigtran.h:75
Authentication vector returned by HLR.
Definition sigtran.h:203
unlang_action_t unlang_module_yield(request_t *request, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
Definition module.c:431
int sigtran_client_thread_register(fr_event_list_t *el)
Called by a new thread to register a new req_pipe.
Definition client.c:143
int sigtran_client_link_up(sigtran_conn_t const **out, sigtran_conn_conf_t const *conn_conf)
Create a new connection.
Definition client.c:224
int sigtran_client_thread_unregister(fr_event_list_t *el, int req_pipe_fd)
Signal that libosmo should unregister the other side of the pipe.
Definition client.c:192
int sigtran_client_link_down(sigtran_conn_t const **conn)
Destroy a connection.
Definition client.c:249
unlang_action_t sigtran_client_map_send_auth_info(unlang_result_t *p_result, rlm_sigtran_t const *inst, request_t *request, sigtran_conn_t const *conn, int fd)
Create a MAP_SEND_AUTH_INFO request.
Definition client.c:405
static unlang_action_t sigtran_client_map_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition client.c:279
static void _sigtran_pipe_error(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, int fd_errno, UNUSED void *uctx)
This should never happen.
Definition client.c:98
static void _sigtran_pipe_read(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, UNUSED void *uctx)
Drain any data we received.
Definition client.c:109
static void sigtran_client_signal(module_ctx_t const *mctx, UNUSED request_t *request, UNUSED fr_signal_t action)
Definition client.c:271
int sigtran_client_do_transaction(int fd, sigtran_transaction_t *txn)
Definition client.c:44
static int sigtran_client_do_ctrl_transaction(sigtran_transaction_t *txn)
Definition client.c:82
static pthread_mutex_t ctrl_pipe_mutex
Definition client.c:37
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition syserror.c:243
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
Definition talloc.h:143
static fr_event_list_t * el
#define fr_box_strvalue_buffer(_val)
Definition value.h:312
#define fr_box_octets_buffer(_val)
Definition value.h:313
static size_t char ** out
Definition value.h:1030