The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
proto_load_step.c
Go to the documentation of this file.
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: aeaa1220962929419bd4355056ff120bba00eccb $
19  * @file proto_load_step.c
20  * @brief Generic protocol load generator
21  *
22  * @copyright 2019 The FreeRADIUS server project.
23  * @copyright 2019 Network RADIUS SAS (legal@networkradius.com)
24  */
25 #include <netdb.h>
26 #include <fcntl.h>
27 #include <freeradius-devel/server/protocol.h>
28 #include <freeradius-devel/io/application.h>
29 #include <freeradius-devel/io/listen.h>
30 #include <freeradius-devel/io/schedule.h>
31 #include <freeradius-devel/io/load.h>
32 
33 #include "proto_load.h"
34 
36 
38 
39 typedef struct {
40  fr_event_list_t *el; //!< event list
41  fr_network_t *nr; //!< network handler
42 
43  char const *name; //!< socket name
44  bool done;
45  bool suspended;
46 
47  fr_time_t recv_time; //!< recv time of the last packet
48 
50  fr_load_t *l; //!< load generation handler
51  fr_load_config_t load; //!< load configuration
52  fr_stats_t stats; //!< statistics for this socket
53 
54  int fd; //!< for CSV files
55  fr_event_timer_t const *ev; //!< for writing statistics
56 
57  fr_listen_t *parent; //!< master IO handler
59 
62 
63  CONF_SECTION *cs; //!< our configuration
64 
65  char const *filename; //!< where to read input packet from
66  fr_pair_list_t pair_list; //!< for input packet
67 
68  int code;
69  uint32_t max_attributes; //!< Limit maximum decodable attributes
70 
71  fr_client_t *client; //!< static client
72 
73  fr_load_config_t load; //!< load configuration
74  bool repeat; //!, do we repeat the load generation
75  char const *csv; //!< where to write CSV stats
76 };
77 
78 
81  { FR_CONF_OFFSET("csv", proto_load_step_t, csv) },
82 
83  { FR_CONF_OFFSET("max_attributes", proto_load_step_t, max_attributes), .dflt = STRINGIFY(RADIUS_MAX_ATTRIBUTES) } ,
84 
85  { FR_CONF_OFFSET("start_pps", proto_load_step_t, load.start_pps) },
86  { FR_CONF_OFFSET("max_pps", proto_load_step_t, load.max_pps) },
87  { FR_CONF_OFFSET("duration", proto_load_step_t, load.duration) },
88  { FR_CONF_OFFSET("step", proto_load_step_t, load.step) },
89  { FR_CONF_OFFSET("max_backlog", proto_load_step_t, load.milliseconds) },
90  { FR_CONF_OFFSET("parallel", proto_load_step_t, load.parallel) },
91  { FR_CONF_OFFSET("repeat", proto_load_step_t, repeat) },
92 
94 };
95 
96 
97 static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time_p, uint8_t *buffer, size_t buffer_len, size_t *leftover)
98 {
100  proto_load_step_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_load_step_thread_t);
101  fr_io_address_t *address, **address_p;
102 
103  if (thread->done) return -1;
104 
105  /*
106  * Suspend reading on the FD, because we let the timers
107  * take over the load generation.
108  */
109  if (!thread->suspended) {
110  static fr_event_update_t pause[] = {
113  { 0 }
114  };
115 
116  if (fr_event_filter_update(thread->el, li->fd, FR_EVENT_FILTER_IO, pause) < 0) {
117  fr_assert(0);
118  }
119 
120  thread->suspended = true;
121  }
122 
123  *leftover = 0; /* always for load generation */
124 
125  /*
126  * Where the addresses should go. This is a special case
127  * for proto_radius.
128  */
129  address_p = (fr_io_address_t **) packet_ctx;
130  address = *address_p;
131 
132  memset(address, 0, sizeof(*address));
133  address->socket.inet.src_ipaddr.af = AF_INET;
134  address->socket.inet.dst_ipaddr.af = AF_INET;
135  address->radclient = inst->client;
136 
137  *recv_time_p = thread->recv_time;
138 
139  if (buffer_len < 1) {
140  DEBUG2("proto_load_step read buffer is too small for input packet");
141  return 0;
142  }
143 
144  buffer[0] = 0;
145 
146  /*
147  * Print out what we received.
148  */
149  DEBUG2("proto_load_step - reading packet for %s",
150  thread->name);
151 
152  return 1;
153 }
154 
155 
156 static ssize_t mod_write(fr_listen_t *li, UNUSED void *packet_ctx, fr_time_t request_time,
157  UNUSED uint8_t *buffer, size_t buffer_len, UNUSED size_t written)
158 {
159  proto_load_step_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_load_step_thread_t);
160  fr_load_reply_t state;
161 
162  /*
163  * @todo - share a stats interface with the parent? or
164  * put the stats in the listener, so that proto_radius
165  * can update them, too.. <sigh>
166  */
167  thread->stats.total_responses++;
168 
169  /*
170  * Tell the load generatopr subsystem that we have a
171  * reply. Then if the load test is done, exit the
172  * server.
173  */
174  state = fr_load_generator_have_reply(thread->l, request_time);
175  if (state == FR_LOAD_DONE) {
176  if (!thread->inst->repeat) {
177  thread->done = true;
178  } else {
179  (void) fr_load_generator_stop(thread->l); /* ensure l->ev is gone */
180  (void) fr_load_generator_start(thread->l);
181  }
182  }
183 
184  return buffer_len;
185 }
186 
187 
188 /** Open a load listener
189  *
190  */
191 static int mod_open(fr_listen_t *li)
192 {
194  proto_load_step_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_load_step_thread_t);
195 
196  fr_ipaddr_t ipaddr;
197 
198  /*
199  * We never read or write to this file, but we need a
200  * readable FD in order to bootstrap the process.
201  */
202  li->fd = open(inst->filename, O_RDONLY);
203 
204  memset(&ipaddr, 0, sizeof(ipaddr));
205  ipaddr.af = AF_INET;
206  li->app_io_addr = fr_socket_addr_alloc_inet_src(li, IPPROTO_UDP, 0, &ipaddr, 0);
207 
208  fr_assert((cf_parent(inst->cs) != NULL) && (cf_parent(cf_parent(inst->cs)) != NULL)); /* listen { ... } */
209 
210  thread->name = talloc_typed_asprintf(thread, "load_step from filename %s", inst->filename);
211  thread->parent = talloc_parent(li);
212 
213  return 0;
214 }
215 
216 
217 /** Generate traffic.
218  *
219  */
220 static int mod_generate(fr_time_t now, void *uctx)
221 {
222  fr_listen_t *li = uctx;
223  proto_load_step_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_load_step_thread_t);
224 
225  thread->recv_time = now;
226 
227  /*
228  * Tell the network side to call our read routine.
229  */
230  fr_network_listen_read(thread->nr, thread->parent);
231 
232  return 0;
233 }
234 
235 
236 static void write_stats(fr_event_list_t *el, fr_time_t now, void *uctx)
237 {
238  proto_load_step_thread_t *thread = uctx;
239  size_t len;
240  char buffer[1024];
241 
242  (void) fr_event_timer_in(thread, el, &thread->ev, fr_time_delta_from_sec(1), write_stats, thread);
243 
244  len = fr_load_generator_stats_sprint(thread->l, now, buffer, sizeof(buffer));
245  if (write(thread->fd, buffer, len) < 0) {
246  DEBUG("Failed writing to %s - %s", thread->inst->csv, fr_syserror(errno));
247  }
248 }
249 
250 
251 /** Decode the packet
252  *
253  */
254 static int mod_decode(void const *instance, request_t *request, UNUSED uint8_t *const data, UNUSED size_t data_len)
255 {
257  fr_io_track_t const *track = talloc_get_type_abort_const(request->async->packet_ctx, fr_io_track_t);
258  fr_io_address_t const *address = track->address;
259 
260  /*
261  * Set the request dictionary so that we can do
262  * generic->protocol attribute conversions as
263  * the request runs through the server.
264  */
265  request->dict = inst->parent->dict;
266 
267  /*
268  * Hacks for now until we have a lower-level decode routine.
269  */
270  if (inst->code) request->packet->code = inst->code;
271  request->packet->id = fr_rand() & 0xff;
272  request->reply->id = request->packet->id;
273  memset(request->packet->vector, 0, sizeof(request->packet->vector));
274 
275  request->packet->data = talloc_zero_array(request->packet, uint8_t, 1);
276  request->packet->data_len = 1;
277 
278  (void) fr_pair_list_copy(request->request_ctx, &request->request_pairs, &inst->pair_list);
279 
280  /*
281  * Set the rest of the fields.
282  */
283  request->client = UNCONST(fr_client_t *, address->radclient);
284 
285  request->packet->socket = address->socket;
286  fr_socket_addr_swap(&request->reply->socket, &address->socket);
287 
288  REQUEST_VERIFY(request);
289 
290  return 0;
291 }
292 
293 /** Set the event list for a new socket
294  *
295  * @param[in] li the listener
296  * @param[in] el the event list
297  * @param[in] nr context from the network side
298  */
299 static void mod_event_list_set(fr_listen_t *li, fr_event_list_t *el, void *nr)
300 {
302  proto_load_step_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_load_step_thread_t);
303  size_t len;
304  char buffer[256];
305 
306  thread->el = el;
307  thread->nr = nr;
308  thread->inst = inst;
309  thread->load = inst->load;
310 
311  thread->l = fr_load_generator_create(thread, el, &thread->load, mod_generate, li);
312  if (!thread->l) return;
313 
314  (void) fr_load_generator_start(thread->l);
315 
316  if (!inst->csv) return;
317 
318  thread->fd = open(inst->csv, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0600);
319  if (thread->fd < 0) {
320  ERROR("Failed opening %s - %s", inst->csv, fr_syserror(errno));
321  return;
322  }
323 
324  (void) fr_event_timer_in(thread, thread->el, &thread->ev, fr_time_delta_from_sec(1), write_stats, thread);
325 
326  len = fr_load_generator_stats_sprint(thread->l, fr_time(), buffer, sizeof(buffer));
327  if (write(thread->fd, buffer, len) < 0) {
328  DEBUG("Failed writing to %s - %s", thread->inst->csv, fr_syserror(errno));
329  }
330 }
331 
332 static char const *mod_name(fr_listen_t *li)
333 {
334  proto_load_step_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_load_step_thread_t);
335 
336  return thread->name;
337 }
338 
339 
340 static int mod_bootstrap(module_inst_ctx_t const *mctx)
341 {
342  proto_load_step_t *inst = talloc_get_type_abort(mctx->inst->data, proto_load_step_t);
343  CONF_SECTION *conf = mctx->inst->conf;
344  dl_module_inst_t const *dl_inst;
345 
346  /*
347  * Find the dl_module_inst_t holding our instance data
348  * so we can find out what the parent of our instance
349  * was.
350  */
351  dl_inst = dl_module_instance_by_data(inst);
352  fr_assert(dl_inst);
353 
354  inst->parent = talloc_get_type_abort(dl_inst->parent->data, proto_load_t);
355  inst->cs = conf;
356 
357  FR_INTEGER_BOUND_CHECK("start_pps", inst->load.start_pps, >=, 10);
358  FR_INTEGER_BOUND_CHECK("start_pps", inst->load.start_pps, <, 400000);
359 
360  FR_INTEGER_BOUND_CHECK("step", inst->load.step, >=, 1);
361  FR_INTEGER_BOUND_CHECK("step", inst->load.step, <, 100000);
362 
363  if (inst->load.max_pps > 0) FR_INTEGER_BOUND_CHECK("max_pps", inst->load.max_pps, >, inst->load.start_pps);
364  FR_INTEGER_BOUND_CHECK("max_pps", inst->load.max_pps, <, 100000);
365 
366  FR_TIME_DELTA_BOUND_CHECK("duration", inst->load.duration, >=, fr_time_delta_from_sec(1));
367  FR_TIME_DELTA_BOUND_CHECK("duration", inst->load.duration, <, fr_time_delta_from_sec(10000));
368 
369 
370  FR_INTEGER_BOUND_CHECK("parallel", inst->load.parallel, >=, 1);
371  FR_INTEGER_BOUND_CHECK("parallel", inst->load.parallel, <, 1000);
372 
373  FR_INTEGER_BOUND_CHECK("max_backlog", inst->load.milliseconds, >=, 1);
374  FR_INTEGER_BOUND_CHECK("max_backlog", inst->load.milliseconds, <, 100000);
375 
376  return 0;
377 }
378 
380 {
382 
383  return inst->client;
384 }
385 
386 
387 static int mod_instantiate(module_inst_ctx_t const *mctx)
388 {
389  proto_load_step_t *inst = talloc_get_type_abort(mctx->inst->data, proto_load_step_t);
390  CONF_SECTION *conf = mctx->inst->conf;
391  fr_client_t *client;
392  fr_pair_t *vp;
393 
394  fr_pair_list_init(&inst->pair_list);
395  inst->client = client = talloc_zero(inst, fr_client_t);
396  if (!inst->client) return 0;
397 
398  client->ipaddr.af = AF_INET;
399  client->src_ipaddr = client->ipaddr;
400 
401  client->longname = client->shortname = inst->filename;
402  client->secret = talloc_strdup(client, "testing123");
403  client->nas_type = talloc_strdup(client, "load");
404  client->use_connected = false;
405 
406  if (inst->filename) {
407  FILE *fp;
408  bool done = false;
409 
410  fp = fopen(inst->filename, "r");
411  if (!fp) {
412  cf_log_err(conf, "Failed opening %s - %s",
413  inst->filename, fr_syserror(errno));
414  return -1;
415  }
416 
417  if (fr_pair_list_afrom_file(inst, inst->parent->dict, &inst->pair_list, fp, &done) < 0) {
418  cf_log_perr(conf, "Failed reading %s", inst->filename);
419  fclose(fp);
420  return -1;
421  }
422 
423  fclose(fp);
424  }
425 
426  vp = fr_pair_find_by_da(&inst->pair_list, NULL, inst->parent->attr_packet_type);
427  if (vp) inst->code = vp->vp_uint32;
428 
429  return 0;
430 }
431 
433  .common = {
434  .magic = MODULE_MAGIC_INIT,
435  .name = "load_step",
436  .config = load_listen_config,
437  .inst_size = sizeof(proto_load_step_t),
438  .thread_inst_size = sizeof(proto_load_step_thread_t),
439  .bootstrap = mod_bootstrap,
440  .instantiate = mod_instantiate
441  },
442  .default_message_size = 4096,
443  .track_duplicates = false,
444 
445  .open = mod_open,
446  .read = mod_read,
447  .write = mod_write,
448  .event_list_set = mod_event_list_set,
449  .client_find = mod_client_find,
450  .get_name = mod_name,
451 
452  .decode = mod_decode,
453 };
static int const char char buffer[256]
Definition: acutest.h:574
module_t common
Common fields to all loadable modules.
Definition: app_io.h:34
Public structure describing an I/O path for a protocol.
Definition: app_io.h:33
#define load(_var)
Definition: atomic_queue.h:46
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition: build.h:165
#define STRINGIFY(x)
Definition: build.h:195
#define UNUSED
Definition: build.h:313
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:626
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
Definition: cf_parse.h:486
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:268
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:256
#define FR_TIME_DELTA_BOUND_CHECK(_name, _var, _op, _bound)
Definition: cf_parse.h:497
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition: cf_parse.h:406
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Definition: cf_parse.h:412
@ CONF_FLAG_NOT_EMPTY
CONF_PAIR is required to have a non zero length value.
Definition: cf_parse.h:421
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:563
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:265
#define cf_parent(_cf)
Definition: cf_util.h:98
#define cf_log_perr(_cf, _fmt,...)
Definition: cf_util.h:272
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
#define DEBUG(fmt,...)
Definition: dhcpclient.c:39
dl_module_inst_t const * dl_module_instance_by_data(void const *data)
Lookup a dl_module_inst_t via instance data.
Definition: dl_module.c:215
void *_CONST data
Module instance's parsed configuration.
Definition: dl_module.h:165
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:65
CONF_SECTION *_CONST conf
Module's instance configuration.
Definition: dl_module.h:166
dl_module_inst_t const *_CONST parent
Parent module's instance (if any).
Definition: dl_module.h:167
A module/inst tuple.
Definition: dl_module.h:162
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
Definition: event.h:62
#define fr_event_filter_update(...)
Definition: event.h:224
#define FR_EVENT_SUSPEND(_s, _f)
Temporarily remove the filter for a func from kevent.
Definition: event.h:94
#define fr_event_timer_in(...)
Definition: event.h:255
Callbacks for the FR_EVENT_FILTER_IO filter.
Definition: event.h:173
Structure describing a modification to a filter's state.
Definition: event.h:75
int af
Address family.
Definition: inet.h:64
IPv4/6 prefix.
Definition: merged_model.c:272
fr_socket_t socket
src/dst ip and port.
Definition: base.h:336
fr_client_t const * radclient
old-style client definition
Definition: base.h:338
fr_socket_t * app_io_addr
for tracking duplicate sockets
Definition: listen.h:35
void const * app_io_instance
I/O path configuration context.
Definition: listen.h:32
void * thread_instance
thread / socket context
Definition: listen.h:33
int fd
file descriptor for this socket - set by open
Definition: listen.h:28
void fr_network_listen_read(fr_network_t *nr, fr_listen_t *li)
Signal the network to read from a listener.
Definition: network.c:311
fr_ipaddr_t ipaddr
IPv4/IPv6 address of the host.
Definition: client.h:80
char const * secret
Secret PSK.
Definition: client.h:87
fr_ipaddr_t src_ipaddr
IPv4/IPv6 address to send responses from (family must match ipaddr).
Definition: client.h:81
char const * nas_type
Type of client (arbitrary).
Definition: client.h:99
char const * longname
Client identifier.
Definition: client.h:84
char const * shortname
Client nickname.
Definition: client.h:85
bool use_connected
do we use connected sockets for this client
Definition: client.h:92
Describes a host allowed to send packets to the server.
Definition: client.h:77
Stores all information relating to an event list.
Definition: event.c:411
A timer event.
Definition: event.c:102
fr_load_t * fr_load_generator_create(TALLOC_CTX *ctx, fr_event_list_t *el, fr_load_config_t *config, fr_load_callback_t callback, void *uctx)
Definition: load.c:87
int fr_load_generator_start(fr_load_t *l)
Start the load generator.
Definition: load.c:230
int fr_load_generator_stop(fr_load_t *l)
Stop the load generation through the simple expedient of deleting the timer associated with it.
Definition: load.c:252
size_t fr_load_generator_stats_sprint(fr_load_t *l, fr_time_t now, char *buffer, size_t buflen)
Print load generator statistics in CVS format.
Definition: load.c:341
fr_load_reply_t fr_load_generator_have_reply(fr_load_t *l, fr_time_t request_time)
Tell the load generator that we have a reply to a packet we sent.
Definition: load.c:263
Definition: load.c:65
fr_load_reply_t
Whether or not the application should continue.
Definition: load.h:103
@ FR_LOAD_DONE
the load generator is done
Definition: load.h:105
Load generation configuration.
Definition: load.h:72
fr_io_address_t const * address
of this packet.. shared between multiple packets
Definition: master.h:54
unsigned int uint32_t
Definition: merged_model.c:33
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Definition: module_ctx.h:52
Temporary structure to hold arguments for instantiation calls.
Definition: module_ctx.h:51
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition: pair.c:688
int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from)
Duplicate a list of pairs.
Definition: pair.c:2316
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition: pair.c:46
int fr_pair_list_afrom_file(TALLOC_CTX *ctx, fr_dict_t const *dict, fr_pair_list_t *out, FILE *fp, bool *pfiledone)
Read valuepairs from the fp up to End-Of-File.
Definition: pair_legacy.c:572
Load master protocol handler.
fr_app_io_t proto_load_step
fr_listen_t * parent
master IO handler
fr_client_t * client
static client
fr_pair_list_t pair_list
for input packet
fr_load_config_t load
load configuration
static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time_p, uint8_t *buffer, size_t buffer_len, size_t *leftover)
static const conf_parser_t load_listen_config[]
CONF_SECTION * cs
our configuration
proto_load_step_t const * inst
static int mod_decode(void const *instance, request_t *request, UNUSED uint8_t *const data, UNUSED size_t data_len)
Decode the packet.
fr_load_config_t load
load configuration
char const * filename
where to read input packet from
static void write_stats(fr_event_list_t *el, fr_time_t now, void *uctx)
uint32_t max_attributes
Limit maximum decodable attributes.
struct proto_load_step_s proto_load_step_t
static int mod_bootstrap(module_inst_ctx_t const *mctx)
char const * csv
, do we repeat the load generation
static ssize_t mod_write(fr_listen_t *li, UNUSED void *packet_ctx, fr_time_t request_time, UNUSED uint8_t *buffer, size_t buffer_len, UNUSED size_t written)
fr_stats_t stats
statistics for this socket
static void mod_event_list_set(fr_listen_t *li, fr_event_list_t *el, void *nr)
Set the event list for a new socket.
static int mod_open(fr_listen_t *li)
Open a load listener.
fr_time_t recv_time
recv time of the last packet
fr_load_t * l
load generation handler
static char const * mod_name(fr_listen_t *li)
fr_event_timer_t const * ev
for writing statistics
fr_network_t * nr
network handler
static int mod_generate(fr_time_t now, void *uctx)
Generate traffic.
fr_event_list_t * el
event list
static fr_client_t * mod_client_find(fr_listen_t *li, UNUSED fr_ipaddr_t const *ipaddr, UNUSED int ipproto)
static int mod_instantiate(module_inst_ctx_t const *mctx)
char const * name
socket name
proto_load_t * parent
static int ipproto
Definition: radclient-ng.c:94
static bool done
Definition: radclient.c:80
#define DEBUG2(fmt,...)
Definition: radclient.h:43
#define RADIUS_MAX_ATTRIBUTES
Definition: radius.h:39
static rs_t * conf
Definition: radsniff.c:53
uint32_t fr_rand(void)
Return a 32-bit random number.
Definition: rand.c:106
#define REQUEST_VERIFY(_x)
Definition: request.h:275
fr_uint_t total_responses
Definition: stats.h:43
fr_assert(0)
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
#define fr_time()
Allow us to arbitrarily manipulate time.
Definition: state_test.c:8
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
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition: talloc.c:380
#define talloc_get_type_abort_const
Definition: talloc.h:270
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
Definition: time.h:588
"server local" time.
Definition: time.h:69
static fr_event_list_t * el
static fr_socket_t * fr_socket_addr_alloc_inet_src(TALLOC_CTX *ctx, int proto, int ifindex, fr_ipaddr_t const *ipaddr, int port)
A variant of fr_socket_addr_init_inet_src will also allocates a fr_socket_t.
Definition: socket.h:244
int af
AF_INET, AF_INET6, or AF_UNIX.
Definition: socket.h:78
static void fr_socket_addr_swap(fr_socket_t *dst, fr_socket_t const *src)
Swap src/dst information of a fr_socket_t.
Definition: socket.h:121
static fr_slen_t data
Definition: value.h:1259