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/protocol/eap/aka-sim/dictionary.h>
33#include <freeradius-devel/server/module_rlm.h>
34
35#include "attrs.h"
36#include "sigtran.h"
37
38static pthread_mutex_t ctrl_pipe_mutex = PTHREAD_MUTEX_INITIALIZER;
39
40/**
41 * $Id: a3b2e80bb4b1a6d92238adc714d04fa8b89bc3e0 $
42 * @file rlm_sigtran/client.c
43 * @brief Talk to the event loop.
44 */
46{
47 ssize_t len;
48 void *ptr;
49
50 if (write(fd, &txn, sizeof(txn)) < 0) {
51 ERROR("worker - ctrl_pipe (%i) write failed: %s", fd, fr_syserror(errno));
52 return -1;
53 }
54
55 /*
56 * Block until libosmo responds
57 */
58 len = read(fd, &ptr, sizeof(ptr));
59 if (len < 0) {
60 ERROR("worker - ctrl_pipe (%i) read failed : %s", fd, fr_syserror(errno));
61 return -1;
62 }
63
64 if (len != sizeof(ptr)) {
65 ERROR("worker - ctrl_pipe (%i) data too short, expected %zu bytes, got %zi bytes",
66 fd, sizeof(ptr), len);
67 return -1;
68 }
69
70 if (ptr != txn) {
71 ERROR("worker - ctrl_pipe (%i) response ptr (%p) does not match request (%p)", fd, ptr, txn);
72 return -1;
73 }
74
75 /*
76 * Check talloc header is still OK
77 */
78 talloc_get_type_abort(ptr, sigtran_transaction_t);
79
80 return 0;
81}
82
84{
85 int ret;
86
87 fr_assert(ctrl_pipe[0] >= 0);
88
89 pthread_mutex_lock(&ctrl_pipe_mutex);
91 pthread_mutex_unlock(&ctrl_pipe_mutex);
92
93 return ret;
94}
95
96/** This should never happen
97 *
98 */
99static void _sigtran_pipe_error(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, int fd_errno, UNUSED void *uctx)
100{
101 ERROR("worker - ctrl_pipe (%i) read failed : %s", fd, fr_syserror(fd_errno));
102 fr_assert(0);
103}
104
105/** Drain any data we received
106 *
107 * We don't care about this data, we just don't want the kernel to
108 * signal the other side that our read buffer's full.
109 */
110static void _sigtran_pipe_read(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, UNUSED void *uctx)
111{
112 ssize_t len;
113 void *ptr;
115
116 len = read(fd, &ptr, sizeof(ptr));
117 if (len < 0) {
118 ERROR("worker - ctrl_pipe (%i) read failed : %s", fd, fr_syserror(errno));
119 return;
120 }
121
122 if (len != sizeof(ptr)) {
123 ERROR("worker - ctrl_pipe (%i) data too short, expected %zu bytes, got %zi bytes",
124 fd, sizeof(ptr), len);
125 return;
126 }
127
128 /*
129 * Check talloc header is still OK
130 */
131 txn = talloc_get_type_abort(ptr, sigtran_transaction_t);
132 if (txn->ctx.defunct) return; /* Request was stopped */
133
134 fr_assert(txn->ctx.request);
135 unlang_interpret_mark_runnable(txn->ctx.request); /* Continue processing */
136}
137
138/** Called by a new thread to register a new req_pipe
139 *
140 * @return
141 * - The client side of the req_pipe on success.
142 * - -1 on error.
143 */
145{
146 int req_pipe[2] = { -1, -1 };
148
149 /*
150 * Create the pipe on our side, and pass over
151 * the remote end to be registered.
152 */
153 if (socketpair(AF_UNIX, SOCK_STREAM, 0, req_pipe) < 0) {
154 ERROR("worker - Failed creating req_pipe: %s", fr_syserror(errno));
155 return -1;
156 }
157
158 fr_assert((req_pipe[0] >= 0) && (req_pipe[1] >= 0));
159
160 txn = talloc_zero(NULL, sigtran_transaction_t);
162 txn->request.data = &req_pipe[1];
163
164 if ((sigtran_client_do_ctrl_transaction(txn) < 0) || (txn->response.type != SIGTRAN_RESPONSE_OK)) {
165 ERROR("worker - Failed registering thread");
166 error:
167 close(req_pipe[0]);
168 close(req_pipe[1]);
169 talloc_free(txn);
170 return -1;
171 }
172 DEBUG3("worker - Thread register acked by osmocom thread");
173 talloc_free(txn);
174
175 /*
176 * Read data coming back on the pipe,
177 * and resume requests which are
178 * waiting.
179 */
180 if (fr_event_fd_insert(NULL, NULL, el, req_pipe[0], _sigtran_pipe_read, NULL, _sigtran_pipe_error, NULL) < 0) {
181 ERROR("worker - Failed listening on osmocom pipe");
182 goto error;
183 }
184
185 return req_pipe[0];
186}
187
188/** Signal that libosmo should unregister the other side of the pipe
189 *
190 * @param[in] el the request pipe was registered to.
191 * @param[in] req_pipe_fd The rlm_sigtran side of the req_pipe.
192 */
194{
196
197 txn = talloc_zero(NULL, sigtran_transaction_t);
199
200 /*
201 * The signal to unregister *MUST* be sent on the
202 * request pipe itself, so that the osmocom thread
203 * knows *WHICH* pipe to close on its side.
204 */
205 if ((sigtran_client_do_transaction(req_pipe_fd, txn) < 0) || (txn->response.type != SIGTRAN_RESPONSE_OK)) {
206 ERROR("worker - Failed unregistering thread");
207 talloc_free(txn);
208 return -1;
209 }
210 DEBUG3("worker - Thread unregister acked by osmocom thread");
211 talloc_free(txn);
212
214 close(req_pipe_fd);
215
216 return 0;
217}
218
219/** Create a new connection
220 *
221 * Register the required links for a connection.
222 *
223 * @todo Return struct representing the connection
224 */
226{
228
229 txn = talloc_zero(NULL, sigtran_transaction_t);
231 memcpy(&txn->request.data, &conn_conf, sizeof(txn->request.data));
232
233 if ((sigtran_client_do_ctrl_transaction(txn) < 0) || (txn->response.type != SIGTRAN_RESPONSE_OK)) {
234 ERROR("worker - Failed bringing up link");
235 talloc_free(txn);
236 return -1;
237 }
238 DEBUG3("worker - Link up acked by osmocom thread");
239 *out = talloc_get_type_abort(txn->response.data, sigtran_conn_t);
240 talloc_free(txn);
241
242 return 0;
243}
244
245/** Destroy a connection
246 *
247 * Gracefully shutdown the links for a connection and free it.
248 *
249 */
251{
253
254 if (!*conn || !(*conn)->mtp3_link) return 0; /* Ignore if there is no link */
255
256 txn = talloc_zero(NULL, sigtran_transaction_t);
258 memcpy(&txn->request.data, conn, sizeof(txn->request.data));
259
260 if ((sigtran_client_do_ctrl_transaction(txn) < 0) || (txn->response.type != SIGTRAN_RESPONSE_OK)) {
261 ERROR("worker - Failed taking down the link");
262 talloc_free(txn);
263 return -1;
264 }
265 DEBUG3("worker - Link down acked by osmocom thread");
266 talloc_free(txn);
267 *conn = NULL;
268
269 return 0;
270}
271
272static void sigtran_client_signal(module_ctx_t const *mctx, UNUSED request_t *request, UNUSED fr_signal_t action)
273{
274 sigtran_transaction_t *txn = talloc_get_type_abort(mctx->rctx, sigtran_transaction_t);
275
276 txn->ctx.defunct = true; /* Mark the transaction up as needing to be freed */
277 txn->ctx.request = NULL; /* remove the link to the (now dead) request */
278}
279
281{
282 sigtran_transaction_t *txn = talloc_get_type_abort(mctx->rctx, sigtran_transaction_t);
283 rlm_rcode_t rcode;
284 fr_assert(request == txn->ctx.request);
285
286 /*
287 * Process response
288 */
289 switch (txn->response.type) {
291 {
292 unsigned int i = 0;
293 fr_pair_t *vp;
294 sigtran_vector_t *vec;
295 sigtran_map_send_auth_info_res_t *res = talloc_get_type_abort(txn->response.data,
297
298 for (vec = res->vector; vec; vec = vec->next) {
299 switch (vec->type) {
301 fr_assert(vec->sim.rand);
302 fr_assert(vec->sim.sres);
303 fr_assert(vec->sim.kc);
304
305 RDEBUG2("SIM auth vector %i", i);
306 RINDENT();
307 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_rand));
308 MEM(fr_pair_value_memdup_buffer(vp, vec->sim.rand, true) == 0);
309 TALLOC_FREE(vec->sim.rand);
310 RDEBUG2("&control.%pP", vp);
311 fr_pair_append(&request->control_pairs, vp);
312
313 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_sres));
314 MEM(fr_pair_value_memdup_buffer(vp, vec->sim.sres, true) == 0);
315 TALLOC_FREE(vec->sim.sres);
316 RDEBUG2("&control.%pP", vp);
317 fr_pair_append(&request->control_pairs, vp);
318
319 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_kc));
320 MEM(fr_pair_value_memdup_buffer(vp, vec->sim.kc, true) == 0);
321 TALLOC_FREE(vec->sim.kc);
322 RDEBUG2("&control.%pP", vp);
323 fr_pair_append(&request->control_pairs, vp);
324 REXDENT();
325
326 i++;
327 break;
328
330 fr_assert(vec->umts.rand);
331 fr_assert(vec->umts.xres);
332 fr_assert(vec->umts.ck);
333 fr_assert(vec->umts.ik);
334 fr_assert(vec->umts.authn);
335
336 RDEBUG2("UMTS auth vector %i", i);
337 RINDENT();
338 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_rand));
339 MEM(fr_pair_value_memdup_buffer(vp, vec->umts.rand, true) == 0);
340 TALLOC_FREE(vec->umts.rand);
341 RDEBUG2("&control.%pP", vp);
342 fr_pair_append(&request->control_pairs, vp);
343
344 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_xres));
345 MEM(fr_pair_value_memdup_buffer(vp, vec->umts.xres, true) == 0);
346 TALLOC_FREE(vec->umts.xres);
347 RDEBUG2("&control.%pP", vp);
348 fr_pair_append(&request->control_pairs, vp);
349
350 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_ck));
351 MEM(fr_pair_value_memdup_buffer(vp, vec->umts.ck, true) == 0);
352 TALLOC_FREE(vec->umts.ck);
353 RDEBUG2("&control.%pP", vp);
354 fr_pair_append(&request->control_pairs, vp);
355
356 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_ik));
357 MEM(fr_pair_value_memdup_buffer(vp, vec->umts.ik, true) == 0);
358 TALLOC_FREE(vec->umts.ik);
359 RDEBUG2("&control.%pP", vp);
360 fr_pair_append(&request->control_pairs, vp);
361
362 MEM(vp = fr_pair_afrom_da(request->control_ctx, attr_eap_aka_sim_autn));
363 MEM(fr_pair_value_memdup_buffer(vp, vec->umts.authn, true) == 0);
364 TALLOC_FREE(vec->umts.authn);
365 RDEBUG2("&control.%pP", vp);
366 fr_pair_append(&request->control_pairs, vp);
367 REXDENT();
368
369 i++;
370 break;
371 }
372 }
373 rcode = RLM_MODULE_OK;
374 }
375 break;
376
378 rcode = RLM_MODULE_NOOP;
379 break;
380
382 rcode = RLM_MODULE_NOTFOUND;
383 break;
384
385 default:
386 fr_assert(0);
388
390 rcode = RLM_MODULE_FAIL;
391 break;
392 }
393 talloc_free(txn);
394
395 RETURN_MODULE_RCODE(rcode);
396}
397
398/** Create a MAP_SEND_AUTH_INFO request
399 *
400 * @param p_result Where to write the result.
401 * @param inst of rlm_sigtran.
402 * @param request The current request.
403 * @param conn current connection.
404 * @param fd file descriptor on which the transaction is done
405 */
407 sigtran_conn_t const *conn, int fd)
408{
411 char *imsi;
412 size_t len;
413
414 fr_assert((fd != ctrl_pipe[0]) && (fd != ctrl_pipe[1]));
415
416 txn = talloc_zero(NULL, sigtran_transaction_t);
418
419 req = talloc(txn, sigtran_map_send_auth_info_req_t);
420 req->conn = conn;
421
422 if (tmpl_aexpand(request, &req->version, request, inst->conn_conf.map_version, NULL, NULL) < 0) {
423 ERROR("Failed retrieving version");
424 error:
425 talloc_free(txn);
427 }
428
429 switch (req->version) {
430 case 2:
431 case 3:
432 break;
433
434 default:
435 REDEBUG("%i is not a valid version", req->version);
436 goto error;
437 }
438
439 txn->request.data = req;
440 txn->ctx.request = request;
441
442 if (tmpl_aexpand(req, &imsi, request, inst->imsi, NULL, NULL) < 0) {
443 REDEBUG("Failed retrieving IMSI");
444 goto error;
445 }
446
447 len = talloc_array_length(imsi) - 1;
448 if ((len != 16) && (len != 15)) {
449 REDEBUG("IMSI must be 15 or 16 digits got %zu digits", len);
450 goto error;
451 }
452
453 if (sigtran_ascii_to_tbcd(req, &req->imsi, imsi) < 0) {
454 REDEBUG("Failed converting ASCII to BCD");
455 goto error;
456 }
457
458 if (RDEBUG_ENABLED2) {
459 RDEBUG2("Sending MAPv%u request with IMSI \"%pV\"", req->version, fr_box_strvalue_buffer(imsi));
460 } else if (RDEBUG_ENABLED3){
461 RDEBUG3("Sending MAPv%u request with IMSI \"%pV\" (TBCD %pV)",
463 }
464
465 /*
466 * FIXME - We shouldn't assume the pipe is always writable
467 */
468 if (write(fd, &txn, sizeof(txn)) < 0) {
469 REDEBUG("worker - ctrl_pipe (%i) write failed: %s", fd, fr_syserror(errno));
470 goto error;
471 }
472
474}
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:322
#define UNUSED
Definition build.h:315
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:41
#define fr_event_fd_insert(...)
Definition event.h:232
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
Definition event.h:62
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
Definition interpret.c:1359
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_kc
Definition base.c:80
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_ck
Definition base.c:65
HIDDEN fr_dict_attr_t const * attr_eap_aka_sim_rand
Definition attrs.h:39
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition log.h:443
#define DEBUG3(_fmt,...)
Definition log.h:266
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Definition log.h:335
#define RDEBUG3(fmt,...)
Definition log.h:343
#define RINDENT()
Indent R* messages by one level.
Definition log.h:430
talloc_free(reap)
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:1260
Stores all information relating to an event list.
Definition event.c:411
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:78
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:3011
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:1345
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:283
VQP attributes.
#define fr_assert(_expr)
Definition rad_assert.h:38
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG_ENABLED2()
Definition radclient.h:50
#define RDEBUG2(fmt,...)
Definition radclient.h:54
#define RETURN_MODULE_RCODE(_rcode)
Definition rcode.h:64
#define RETURN_MODULE_FAIL
Definition rcode.h:56
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:43
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:42
@ RLM_MODULE_NOTFOUND
User not found.
Definition rcode.h:47
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:48
#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:1070
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
uint8_t * imsi
BCD encoded IMSI.
Definition sigtran.h:193
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
struct sigtran_transaction::@176 ctx
sigtran_vector_t * next
Next vector in list.
Definition sigtran.h:220
struct sigtran_transaction::@175 response
struct sigtran_transaction::@174 request
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:419
int sigtran_client_thread_register(fr_event_list_t *el)
Called by a new thread to register a new req_pipe.
Definition client.c:144
unlang_action_t sigtran_client_map_send_auth_info(rlm_rcode_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:406
static unlang_action_t sigtran_client_map_resume(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition client.c:280
int sigtran_client_link_up(sigtran_conn_t const **out, sigtran_conn_conf_t const *conn_conf)
Create a new connection.
Definition client.c:225
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:193
int sigtran_client_link_down(sigtran_conn_t const **conn)
Destroy a connection.
Definition client.c:250
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:99
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:110
static void sigtran_client_signal(module_ctx_t const *mctx, UNUSED request_t *request, UNUSED fr_signal_t action)
Definition client.c:272
int sigtran_client_do_transaction(int fd, sigtran_transaction_t *txn)
Definition client.c:45
static int sigtran_client_do_ctrl_transaction(sigtran_transaction_t *txn)
Definition client.c:83
static pthread_mutex_t ctrl_pipe_mutex
Definition client.c:38
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
close(uq->fd)
static fr_event_list_t * el
#define fr_box_strvalue_buffer(_val)
Definition value.h:289
#define fr_box_octets_buffer(_val)
Definition value.h:290
static size_t char ** out
Definition value.h:997