Coverage Report

Created: 2026-03-31 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/lib/io/master.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: d086eae2cbb722dad9f4ac42d7f2c2b574b4ee3e $
19
 * @file io/master.c
20
 * @brief Master IO handler
21
 *
22
 * @copyright 2018 Alan DeKok (aland@freeradius.org)
23
 */
24
#include <freeradius-devel/io/listen.h>
25
#include <freeradius-devel/io/master.h>
26
27
28
#include <freeradius-devel/util/debug.h>
29
30
#include <freeradius-devel/util/syserror.h>
31
32
typedef struct {
33
  fr_event_list_t     *el;        //!< event list, for the master socket.
34
  fr_network_t      *nr;        //!< network for the master socket
35
36
  fr_trie_t     *trie;        //!< trie of clients
37
  fr_heap_t     *pending_clients;   //!< heap of pending clients
38
  fr_heap_t     *alive_clients;     //!< heap of active dynamic clients
39
40
  fr_listen_t     *listen;      //!< The master IO path
41
  fr_listen_t     *child;       //!< The child (app_io) IO path
42
  fr_schedule_t     *sc;        //!< the scheduler
43
44
  // @todo - count num_nak_clients, and num_nak_connections, too
45
  uint32_t      num_connections;    //!< number of dynamic connections
46
  uint32_t      num_pending_packets;      //!< number of pending packets
47
  uint64_t      client_id;      //!< Unique client identifier.
48
49
  struct {
50
    fr_rate_limit_t     accept_failed;
51
    fr_rate_limit_t     alloc_failed;
52
    fr_rate_limit_t     bad_type;
53
    fr_rate_limit_t     conn_alloc_failed;
54
    fr_rate_limit_t     max_connections;
55
    fr_rate_limit_t     queue_full;
56
    fr_rate_limit_t     repeat_nak;
57
    fr_rate_limit_t     too_many_pending;
58
    fr_rate_limit_t     tracking_failed;
59
    fr_rate_limit_t     unknown_client;
60
  } rate_limit;
61
} fr_io_thread_t;
62
63
/** A saved packet
64
 *
65
 */
66
typedef struct {
67
  fr_heap_index_t   heap_id;
68
  uint32_t    priority;
69
  fr_time_t   recv_time;
70
  fr_io_track_t   *track;
71
  uint8_t     *buffer;
72
  size_t      buffer_len;
73
} fr_io_pending_packet_t;
74
75
76
/** Client states
77
 *
78
 */
79
typedef enum {
80
  PR_CLIENT_INVALID = 0,
81
  PR_CLIENT_STATIC,       //!< static / global clients
82
  PR_CLIENT_NAK,          //!< negative cache entry
83
  PR_CLIENT_DYNAMIC,        //!< dynamically defined client
84
  PR_CLIENT_CONNECTED,        //!< dynamically defined client in a connected socket
85
  PR_CLIENT_PENDING,        //!< dynamic client pending definition
86
} fr_io_client_state_t;
87
88
/*
89
 *  Dynamic clients are run through the normal src/process/foo state machine.
90
 *
91
 *  request->async->packet_ctx is an fr_io_track_t
92
 *
93
 *  track->dynamic is set to a non-zero value.
94
 *
95
 *  The dynamic client code returns a buffer of 1 byte for a NAK.
96
 *
97
 *  If the client creation is successful, then it does talloc(NULL, fr_client_t),
98
 *  fills out the structure, and sends the pointer in the buffer (8 bytes).
99
 *
100
 *  This code will take over ownership of the structure, and
101
 *  create the dynamic client.
102
 */
103
104
typedef struct fr_io_connection_s fr_io_connection_t;
105
106
/** Client definitions for master IO
107
 *
108
 */
109
struct fr_io_client_s {
110
  fr_io_connection_t    *connection;  //!< parent connection
111
  fr_io_client_state_t    state;    //!< state of this client
112
  fr_ipaddr_t     src_ipaddr; //!< packets come from this address
113
  fr_ipaddr_t     network;  //!< network for dynamic clients
114
  fr_client_t     *radclient; //!< old-style definition of this client
115
116
  int       packets;  //!< number of packets using this client
117
  fr_heap_index_t     pending_id; //!< for pending clients
118
  fr_heap_index_t     alive_id; //!< for all clients
119
120
  bool        use_connected;  //!< does this client allow connected sub-sockets?
121
  bool        ready_to_delete; //!< are we ready to delete this client?
122
  bool        in_trie;  //!< is the client in the trie?
123
124
  fr_io_instance_t const    *inst;    //!< parent instance for master IO handler
125
  fr_io_thread_t      *thread;
126
  fr_timer_t      *ev;    //!< when we clean up the client
127
  fr_rb_tree_t      *table;   //!< tracking table for packets
128
129
  fr_heap_t     *pending; //!< pending packets for this client
130
  fr_hash_table_t     *addresses; //!< list of src/dst addresses used by this client
131
132
  pthread_mutex_t     mutex;    //!< for parent / child signaling
133
  fr_hash_table_t     *ht;    //!< for tracking connected sockets
134
};
135
136
/** Track a connection
137
 *
138
 *  This structure contains information about the connection,
139
 *  a pointer to the library instance so that we can clean up on exit,
140
 *  and the listener.
141
 *
142
 *  It also points to a client structure which is for this connection,
143
 *  and only this connection.
144
 *
145
 *  Finally, a pointer to the parent client, so that the child can
146
 *  tell the parent it's alive, and the parent can push packets to the
147
 *  child.
148
 */
149
struct fr_io_connection_s {
150
  char const      *name;    //!< taken from proto_FOO_TRANSPORT
151
  int       packets;  //!< number of packets using this connection
152
  fr_io_address_t       *address;       //!< full information about the connection.
153
  fr_listen_t     *listen;  //!< master listener for this socket
154
  fr_listen_t     *child;   //!< child listener (app_io) for this socket
155
  fr_io_client_t      *client;  //!< our local client (pending or connected).
156
  fr_io_client_t      *parent;  //!< points to the parent client.
157
  module_instance_t       *mi;    //!< for submodule
158
159
  bool        dead;   //!< roundabout way to get the network side to close a socket
160
  bool        paused;   //!< event filter doesn't like resuming something that isn't paused
161
  bool        in_parent_hash; //!< for tracking thread issues
162
  fr_event_list_t     *el;    //!< event list for this connection
163
  fr_network_t      *nr;    //!< network for this connection
164
};
165
166
static fr_event_update_t pause_read[] = {
167
  FR_EVENT_SUSPEND(fr_event_io_func_t, read),
168
  { 0 }
169
};
170
171
static fr_event_update_t resume_read[] = {
172
  FR_EVENT_RESUME(fr_event_io_func_t, read),
173
  { 0 }
174
};
175
176
static int track_free(fr_io_track_t *track)
177
0
{
178
0
  FR_TIMER_DELETE_RETURN(&track->ev);
179
0
  talloc_free_children(track);
180
181
0
  fr_assert(track->client->packets > 0);
182
0
  track->client->packets--;
183
184
0
  return 0;
185
0
}
186
187
static int track_dedup_free(fr_io_track_t *track)
188
0
{
189
0
  fr_assert(track->client->table != NULL);
190
0
  fr_assert(fr_rb_find(track->client->table, track) != NULL);
191
192
0
  if (!fr_rb_delete(track->client->table, track)) {
193
0
    fr_assert(0);
194
0
  }
195
196
0
  return track_free(track);
197
0
}
198
199
/*
200
 *  Return negative numbers to put 'one' at the top of the heap.
201
 *  Return positive numbers to put 'two' at the top of the heap.
202
 */
203
static int8_t pending_packet_cmp(void const *one, void const *two)
204
0
{
205
0
  fr_io_pending_packet_t const *a = talloc_get_type_abort_const(one, fr_io_pending_packet_t);
206
0
  fr_io_pending_packet_t const *b = talloc_get_type_abort_const(two, fr_io_pending_packet_t);
207
0
  int ret;
208
209
  /*
210
   *  Higher priority elements are larger than lower
211
   *  priority elements.  So if "a" is larger than "b", we
212
   *  wish to prefer "a".
213
   */
214
0
  ret = CMP_PREFER_LARGER(a->priority, b->priority);
215
0
  if (ret != 0) return ret;
216
217
  /*
218
   *  Smaller numbers mean packets were received earlier.
219
   *  We want to process packets in time order.  So if "a"
220
   *  is smaller than "b", we wish to prefer "a".
221
   *
222
   *  After that, it doesn't really matter what order the
223
   *  packets go in.  Since we'll never have two identical
224
   *  "recv_time" values, the code should never get here.
225
   */
226
0
  return CMP_PREFER_SMALLER(fr_time_unwrap(a->recv_time), fr_time_unwrap(b->recv_time));
227
0
}
228
229
/*
230
 *  Order clients in the pending_clients heap, based on the
231
 *  packets that they contain.
232
 */
233
static int8_t pending_client_cmp(void const *one, void const *two)
234
0
{
235
0
  fr_io_pending_packet_t const *a;
236
0
  fr_io_pending_packet_t const *b;
237
238
0
  fr_io_client_t const *c1 = talloc_get_type_abort_const(one, fr_io_client_t);
239
0
  fr_io_client_t const *c2 = talloc_get_type_abort_const(two, fr_io_client_t);
240
241
0
  a = fr_heap_peek(c1->pending);
242
0
  b = fr_heap_peek(c2->pending);
243
244
0
  fr_assert(a != NULL);
245
0
  fr_assert(b != NULL);
246
247
0
  return pending_packet_cmp(a, b);
248
0
}
249
250
251
static int8_t address_cmp(void const *one, void const *two)
252
0
{
253
0
  fr_io_address_t const *a = talloc_get_type_abort_const(one, fr_io_address_t);
254
0
  fr_io_address_t const *b = talloc_get_type_abort_const(two, fr_io_address_t);
255
0
  int8_t ret;
256
257
0
  CMP_RETURN(a, b, socket.inet.src_port);
258
0
  CMP_RETURN(a, b, socket.inet.dst_port);
259
0
  CMP_RETURN(a, b, socket.inet.ifindex);
260
261
0
  ret = fr_ipaddr_cmp(&a->socket.inet.src_ipaddr, &b->socket.inet.src_ipaddr);
262
0
  if (ret != 0) return ret;
263
264
0
  return fr_ipaddr_cmp(&a->socket.inet.dst_ipaddr, &b->socket.inet.dst_ipaddr);
265
0
}
266
267
static uint32_t connection_hash(void const *ctx)
268
0
{
269
0
  uint32_t hash;
270
0
  fr_io_connection_t const *c = talloc_get_type_abort_const(ctx, fr_io_connection_t);
271
272
0
  hash = fr_hash(&c->address->socket.inet.src_ipaddr, sizeof(c->address->socket.inet.src_ipaddr));
273
0
  hash = fr_hash_update(&c->address->socket.inet.src_port, sizeof(c->address->socket.inet.src_port), hash);
274
275
0
  hash = fr_hash_update(&c->address->socket.inet.ifindex, sizeof(c->address->socket.inet.ifindex), hash);
276
277
0
  hash = fr_hash_update(&c->address->socket.inet.dst_ipaddr, sizeof(c->address->socket.inet.dst_ipaddr), hash);
278
0
  return fr_hash_update(&c->address->socket.inet.dst_port, sizeof(c->address->socket.inet.dst_port), hash);
279
0
}
280
281
static int8_t connection_cmp(void const *one, void const *two)
282
0
{
283
0
  fr_io_connection_t const *a = talloc_get_type_abort_const(one, fr_io_connection_t);
284
0
  fr_io_connection_t const *b = talloc_get_type_abort_const(two, fr_io_connection_t);
285
286
0
  return address_cmp(a->address, b->address);
287
0
}
288
289
290
static int8_t track_cmp(void const *one, void const *two)
291
0
{
292
0
  fr_io_track_t const *a = talloc_get_type_abort_const(one, fr_io_track_t);
293
0
  fr_io_track_t const *b = talloc_get_type_abort_const(two, fr_io_track_t);
294
0
  int ret;
295
296
0
  fr_assert(a->client != NULL);
297
0
  fr_assert(b->client != NULL);
298
0
  fr_assert(a->client == b->client); /* tables are per-client */
299
300
0
  fr_assert(!a->client->connection);
301
0
  fr_assert(!b->client->connection);
302
303
  /*
304
   *  Unconnected sockets must check src/dst ip/port.
305
   */
306
0
  ret = address_cmp(a->address, b->address);
307
0
  if (ret != 0) return ret;
308
309
  /*
310
   *  Call the per-protocol comparison function.
311
   */
312
0
  ret = a->client->inst->app_io->track_compare(a->client->inst->app_io_instance,
313
0
                 a->client->thread->child->thread_instance,
314
0
                 a->client->radclient,
315
0
                 a->packet, b->packet);
316
0
  return CMP(ret, 0);
317
0
}
318
319
320
static int8_t track_connected_cmp(void const *one, void const *two)
321
0
{
322
0
  fr_io_track_t const *a = talloc_get_type_abort_const(one, fr_io_track_t);
323
0
  fr_io_track_t const *b = talloc_get_type_abort_const(two, fr_io_track_t);
324
0
  int ret;
325
326
0
  fr_assert(a->client != NULL);
327
0
  fr_assert(b->client != NULL);
328
329
0
  fr_assert(a->client->connection);
330
0
  fr_assert(b->client->connection);
331
0
  fr_assert(a->client == b->client);
332
0
  fr_assert(a->client->connection == b->client->connection);
333
334
  /*
335
   *  Note that we pass the connection "client", as
336
   *  we may do negotiation specific to this connection.
337
   */
338
0
  ret = a->client->inst->app_io->track_compare(a->client->inst->app_io_instance,
339
0
                 a->client->connection->child->thread_instance,
340
0
                 a->client->connection->client->radclient,
341
0
                 a->packet, b->packet);
342
0
  return CMP(ret, 0);
343
0
}
344
345
346
static fr_io_pending_packet_t *pending_packet_pop(fr_io_thread_t *thread)
347
0
{
348
0
  fr_io_client_t *client;
349
0
  fr_io_pending_packet_t *pending;
350
351
0
  client = fr_heap_pop(&thread->pending_clients);
352
0
  if (!client) {
353
0
    fr_assert(thread->num_pending_packets == 0);
354
355
    /*
356
     *  99% of the time we don't have pending clients.
357
     *  So we might as well free this, so that the
358
     *  caller doesn't keep checking us for every packet.
359
     */
360
0
    talloc_free(thread->pending_clients);
361
0
    thread->pending_clients = NULL;
362
0
    return NULL;
363
0
  }
364
365
0
  pending = fr_heap_pop(&client->pending);
366
0
  fr_assert(pending != NULL);
367
368
  /*
369
   *  If the client has more packets pending, add it back to
370
   *  the heap.
371
   */
372
0
  if (fr_heap_num_elements(client->pending) > 0) {
373
0
    if (fr_heap_insert(&thread->pending_clients, client) < 0) {
374
0
      fr_assert(0 == 1);
375
0
    }
376
0
  }
377
378
0
  fr_assert(thread->num_pending_packets > 0);
379
0
  thread->num_pending_packets--;
380
381
0
  return pending;
382
0
}
383
384
static fr_client_t *radclient_clone(TALLOC_CTX *ctx, fr_client_t const *parent)
385
0
{
386
0
  fr_client_t *c;
387
388
0
  if (!parent) return NULL;
389
390
0
  c = talloc_zero(ctx, fr_client_t);
391
0
  if (!c) return NULL;
392
393
  /*
394
   *  Do NOT set ipaddr or src_ipaddr.  The caller MUST do this!
395
   */
396
397
0
#define DUP_FIELD(_x) do { if (parent->_x) {c->_x = talloc_strdup(c, parent->_x); if (!c->_x) {goto error;}}} while (0)
398
0
#define COPY_FIELD(_x) c->_x = parent->_x
399
400
0
  DUP_FIELD(longname);
401
0
  DUP_FIELD(shortname);
402
0
  DUP_FIELD(secret);
403
0
  DUP_FIELD(nas_type);
404
0
  DUP_FIELD(server);
405
406
0
  COPY_FIELD(require_message_authenticator);
407
0
  COPY_FIELD(require_message_authenticator_is_set);
408
#ifdef NAS_VIOLATES_RFC
409
  COPY_FIELD(allow_vulnerable_clients);
410
#endif
411
0
  COPY_FIELD(limit_proxy_state);
412
0
  COPY_FIELD(limit_proxy_state_is_set);
413
0
  COPY_FIELD(received_message_authenticator);
414
0
  COPY_FIELD(first_packet_no_proxy_state);
415
  /* dynamic MUST be false */
416
0
  COPY_FIELD(server_cs);
417
0
  COPY_FIELD(cs);
418
0
  COPY_FIELD(proto);
419
0
  COPY_FIELD(active);
420
421
0
  COPY_FIELD(use_connected);
422
423
0
#ifdef WITH_TLS
424
0
  COPY_FIELD(tls_required);
425
0
#endif
426
427
0
  c->ipaddr = parent->ipaddr;
428
0
  c->src_ipaddr = parent->src_ipaddr;
429
430
0
  return c;
431
432
  /*
433
   *  @todo - fill in other fields, too!
434
   */
435
436
0
error:
437
0
  talloc_free(c);
438
0
  return NULL;
439
0
}
440
#undef COPY_FIELD
441
#undef DUP_FIELD
442
443
444
/** Count the number of connections used by active clients.
445
 *
446
 *  Unfortunately, we also count NAK'd connections, too, even if they
447
 *  are closed.  The alternative is to walk through all connections
448
 *  for each client, which would be a long time.
449
 */
450
static int count_connections(UNUSED uint8_t const *key, UNUSED size_t keylen, void *data, void *ctx)
451
0
{
452
0
  fr_io_client_t *client = talloc_get_type_abort(data, fr_io_client_t);
453
0
  int connections;
454
455
0
  pthread_mutex_lock(&client->mutex);
456
457
0
  if (!client->ht) {
458
0
    pthread_mutex_unlock(&client->mutex);
459
0
    return 0;
460
0
  }
461
462
0
  connections = fr_hash_table_num_elements(client->ht);
463
0
  pthread_mutex_unlock(&client->mutex);
464
465
0
  fr_assert(client->use_connected);
466
0
  *((uint32_t *) ctx) += connections;
467
468
0
  return 0;
469
0
}
470
471
472
static int _client_free(fr_io_client_t *client)
473
0
{
474
0
  if (client->use_connected) (void) pthread_mutex_destroy(&client->mutex);
475
476
0
  TALLOC_FREE(client->pending);
477
478
0
  return 0;
479
0
}
480
481
static void client_pending_free(fr_io_client_t *client)
482
0
{
483
0
  size_t num;
484
485
0
  fr_assert(!client->connection);
486
487
0
  if (!client->pending) return;
488
489
0
  num = fr_heap_num_elements(client->pending);
490
491
0
  fr_assert(client->thread->num_pending_packets >= num);
492
0
  client->thread->num_pending_packets -= num;
493
494
0
  TALLOC_FREE(client->pending);
495
0
}
496
497
498
static int connection_free(fr_io_connection_t *connection)
499
0
{
500
  /*
501
   *  This is it's own talloc context, as there are
502
   *  thousands of packets associated with it.
503
   */
504
0
  TALLOC_FREE(connection->client);
505
506
0
  return 0;
507
0
}
508
509
/** Create a new connection.
510
 *
511
 *  Called ONLY from the master socket.
512
 */
513
static fr_io_connection_t *fr_io_connection_alloc(fr_io_instance_t const *inst,
514
              fr_io_thread_t *thread,
515
              fr_io_client_t *client, int fd,
516
              fr_io_address_t *address,
517
              fr_io_connection_t *nak)
518
0
{
519
0
  int ret;
520
0
  fr_io_connection_t *connection;
521
0
  module_instance_t *mi = NULL;
522
0
  fr_listen_t *li;
523
0
  fr_client_t *radclient;
524
525
526
  /*
527
   *  Reload the app_io module as a "new" library.  This
528
   *  causes the link count for the library to be correct.
529
   *  It also allocates a new instance data for it, too.
530
   *  Passing CONF_SECTION of NULL ensures that there's no
531
   *  config for it, as we'll just clone it's contents from
532
   *  the original.  It also means that detach should be
533
   *  called when the instance data is freed.
534
   */
535
0
  if (!nak) {
536
0
    CONF_SECTION *cs;
537
0
    char *inst_name;
538
539
0
    if (inst->max_connections || client->radclient->limit.max_connections) {
540
0
      uint32_t max_connections = inst->max_connections ? inst->max_connections : client->radclient->limit.max_connections;
541
542
      /*
543
       *  We've hit the connection limit.  Walk
544
       *  over all clients with connections, and
545
       *  count the number of connections used.
546
       */
547
0
      if (thread->num_connections >= max_connections) {
548
0
        thread->num_connections = 0;
549
550
0
        (void) fr_trie_walk(thread->trie, &thread->num_connections, count_connections);
551
552
0
        if ((thread->num_connections + 1) >= max_connections) {
553
0
          RATE_LIMIT_LOCAL(&thread->rate_limit.max_connections, INFO,
554
0
               "proto_%s - Ignoring connection from client %s - 'max_connections' limit reached.",
555
0
               inst->app->common.name, client->radclient->shortname);
556
0
          if (fd >= 0) close(fd);
557
0
          return NULL;
558
0
        }
559
0
      }
560
0
    }
561
562
    /*
563
     *  Add a client module into a sublist
564
     */
565
0
    inst_name = talloc_asprintf(NULL, "%"PRIu64, thread->client_id++);
566
0
    mi = module_instance_copy(inst->clients, inst->submodule, inst_name);
567
0
    talloc_free(inst_name);
568
569
0
    cs = cf_section_dup(mi, NULL, inst->submodule->conf,
570
0
            cf_section_name1(inst->submodule->conf),
571
0
            cf_section_name2(inst->submodule->conf), false);
572
0
    if (module_instance_conf_parse(mi, cs) < 0) {
573
0
      cf_log_err(inst->server_cs, "Failed parsing module config");
574
0
      goto cleanup;
575
0
    }
576
577
    /* Thread local module lists never run bootstrap */
578
0
    if (module_instantiate(mi) < 0) {
579
0
      cf_log_err(inst->server_cs, "Failed instantiating module");
580
0
      goto cleanup;
581
0
    }
582
583
0
    if (module_thread_instantiate(mi, mi, thread->el) < 0) {
584
0
      cf_log_err(inst->server_cs, "Failed instantiating module");
585
0
      goto cleanup;
586
0
    }
587
588
    /*
589
     *  FIXME - Instantiate the new module?!
590
     */
591
0
    fr_assert(mi != NULL);
592
0
  } else {
593
0
    mi = talloc_init_const("nak");
594
0
  }
595
596
0
  MEM(connection = talloc_zero(mi, fr_io_connection_t));
597
0
  MEM(connection->address = talloc_memdup(connection, address, sizeof(*address)));
598
0
  (void) talloc_set_name_const(connection->address, "fr_io_address_t");
599
600
0
  connection->parent = client;
601
0
  connection->mi = mi;
602
603
0
  MEM(connection->client = talloc_named(NULL, sizeof(fr_io_client_t), "fr_io_client_t"));
604
0
  memset(connection->client, 0, sizeof(*connection->client));
605
606
0
  MEM(connection->client->radclient = radclient = radclient_clone(connection->client, client->radclient));
607
608
0
  talloc_set_destructor(connection->client, _client_free);
609
0
  talloc_set_destructor(connection, connection_free);
610
611
0
  connection->client->pending_id = FR_HEAP_INDEX_INVALID;
612
0
  connection->client->alive_id = FR_HEAP_INDEX_INVALID;
613
0
  connection->client->connection = connection;
614
615
  /*
616
   *  Create the packet tracking table for this client.
617
   *
618
   *  #todo - unify the code with static clients?
619
   */
620
0
  if (inst->app_io->track_duplicates) {
621
0
    MEM(connection->client->table = fr_rb_inline_talloc_alloc(client, fr_io_track_t, node,
622
0
                    track_connected_cmp, NULL));
623
0
  }
624
625
  /*
626
   *  Set this radclient to be dynamic, and active.
627
   */
628
0
  radclient->dynamic = true;
629
0
  radclient->active = true;
630
631
  /*
632
   *  address->socket.inet.client points to a "static" client.  We want
633
   *  to clean up everything associated with the connection
634
   *  when it closes.  So we need to point to our own copy
635
   *  of the client here.
636
   */
637
0
  connection->address->radclient = connection->client->radclient;
638
0
  connection->client->inst = inst;
639
0
  connection->client->thread = thread;
640
641
  /*
642
   *  Create a heap for packets which are pending for this
643
   *  client.
644
   */
645
0
  MEM(connection->client->pending = fr_heap_alloc(connection->client, pending_packet_cmp,
646
0
               fr_io_pending_packet_t, heap_id, 0));
647
648
  /*
649
   *  Clients for connected sockets are always a /32 or /128.
650
   */
651
0
  connection->client->src_ipaddr = address->socket.inet.src_ipaddr;
652
0
  connection->client->network = address->socket.inet.src_ipaddr;
653
654
  /*
655
   *  Don't initialize mutex or hash table.
656
   *  Connections cannot spawn other connections.
657
   */
658
659
  /*
660
   *  If this client state is pending, then the connection
661
   *  state is pending, too.  That allows NAT gateways to be
662
   *  defined dynamically, AND for them to have multiple
663
   *  connections, each with a different client.  This
664
   *  allows for different shared secrets to be used for
665
   *  different connections.  Once the client gets defined
666
   *  for this connection, it will be either "connected" or
667
   *  not.  If connected, then the parent client remains
668
   *  PENDING.  Otherwise, the parent client is moved to
669
   *  DYNAMIC
670
   *
671
   *  If this client state is static or dynamic,
672
   *  then we're just using connected sockets behind
673
   *  that client.  The connections here all use the
674
   *  same shared secret, but they use different
675
   *  sockets, so they allow for sharing of IO
676
   *  across CPUs / threads.
677
   */
678
0
  switch (client->state) {
679
0
  case PR_CLIENT_PENDING:
680
0
    connection->client->state = PR_CLIENT_PENDING;
681
682
    /*
683
     *  Needed for rlm_radius, which refuses to proxy packets
684
     *  that define a dynamic client.
685
     */
686
0
    radclient->active = false;
687
0
    break;
688
689
0
  case PR_CLIENT_STATIC:
690
0
  case PR_CLIENT_DYNAMIC:
691
0
    connection->client->state = PR_CLIENT_CONNECTED;
692
0
    break;
693
694
0
  case PR_CLIENT_INVALID:
695
0
  case PR_CLIENT_NAK:
696
0
  case PR_CLIENT_CONNECTED:
697
0
    fr_assert(0 == 1);
698
0
    goto cleanup;
699
0
  }
700
701
0
  if (!nak) {
702
    /*
703
     *  Get the child listener.
704
     */
705
0
    MEM(li = connection->child = talloc(connection, fr_listen_t));
706
0
    memcpy(li, thread->listen, sizeof(*li));
707
708
    /*
709
     *  Glue in the actual app_io
710
     */
711
0
    li->connected = true;
712
0
    li->app_io = thread->child->app_io;
713
0
    li->cs = inst->app_io_conf;
714
0
    li->thread_instance = connection;
715
0
    li->app_io_instance = mi->data;
716
0
    li->track_duplicates = thread->child->app_io->track_duplicates;
717
718
    /*
719
     *  Create writable thread instance data.
720
     */
721
0
    connection->child->thread_instance = talloc_zero_array(NULL, uint8_t,
722
0
                       inst->app_io->common.thread_inst_size);
723
0
    talloc_set_destructor(connection->child, fr_io_listen_free);
724
0
    talloc_set_name(connection->child->thread_instance, "proto_%s_thread_t",
725
0
        inst->app_io->common.name);
726
727
    /*
728
     *  This is "const", and the user can't
729
     *  touch it.  So we just reuse the same
730
     *  configuration everywhere.
731
     */
732
0
    connection->child->app_io_instance = inst->app_io_instance;
733
734
    /*
735
     *  Create the listener, based on our listener.
736
     */
737
0
    MEM(li = connection->listen = talloc(connection, fr_listen_t));
738
739
    /*
740
     *  Note that our instance is effectively 'const'.
741
     *
742
     *  i.e. we can't add things to it.  Instead, we have to
743
     *  put all variable data into the connection.
744
     */
745
0
    memcpy(li, thread->listen, sizeof(*li));
746
747
    /*
748
     *  Glue in the connection to the listener.
749
     */
750
0
    fr_assert(li->app_io == &fr_master_app_io);
751
752
0
    li->connected = true;
753
0
    li->thread_instance = connection;
754
0
    li->cs = inst->app_io_conf;
755
0
    li->app_io_instance = li->thread_instance;
756
0
    li->track_duplicates = thread->child->app_io->track_duplicates;
757
758
    /*
759
     *  Instantiate the child, and open the socket.
760
     */
761
0
    fr_assert(inst->app_io->connection_set != NULL);
762
763
0
    if (inst->app_io->connection_set(connection->child, connection->address) < 0) {
764
0
      DEBUG("proto_%s - Failed setting connection for socket.", inst->app->common.name);
765
0
      goto cleanup;
766
0
    }
767
768
    /*
769
     *  UDP sockets: open a new socket, and then
770
     *  connect it to the client.  This emulates the
771
     *  behavior of accept().
772
     *
773
     *  Note that there is a small window between the
774
     *  bind() and connect() where UDP packets for the
775
     *  wildcard socket can get received by this
776
     *  socket.  We hope that this time frame is as
777
     *  small as possible.
778
     *
779
     *  i.e. we ignore the problem, and don't
780
     *  currently check dst ip/port for UDP packets
781
     *  received on connected sockets.
782
     */
783
0
    if (fd < 0) {
784
0
      socklen_t salen;
785
0
      struct sockaddr_storage src;
786
787
0
      if (fr_ipaddr_to_sockaddr(&src, &salen,
788
0
              &connection->address->socket.inet.src_ipaddr,
789
0
              connection->address->socket.inet.src_port) < 0) {
790
0
        DEBUG("proto_%s - Failed getting IP address", inst->app->common.name);
791
0
        talloc_free(mi);
792
0
        return NULL;
793
0
      }
794
795
0
      if (inst->app_io->open(connection->child) < 0) {
796
0
        DEBUG("proto_%s - Failed opening connected socket.", inst->app->common.name);
797
0
        talloc_free(mi);
798
0
        return NULL;
799
0
      }
800
801
0
      fd = connection->child->fd;
802
803
0
      if (connect(fd, (struct sockaddr *) &src, salen) < 0) {
804
0
        ERROR("proto_%s - Failed in connect: %s", inst->app->common.name, fr_syserror(errno));
805
0
        goto cleanup;
806
0
      }
807
0
    } else {
808
0
      connection->child->fd = fd;
809
0
    }
810
811
    /*
812
     *  Set the new FD, and get the module to set it's connection name.
813
     */
814
0
    if (inst->app_io->fd_set(connection->child, fd) < 0) {
815
0
      DEBUG3("Failed setting FD to %s", inst->app_io->common.name);
816
0
      goto cleanup;
817
0
    }
818
819
0
    li->fd = fd;
820
821
0
    if (!inst->app_io->get_name) {
822
0
      connection->name = fr_asprintf(connection, "proto_%s from client %pV port "
823
0
                   "%u to server %pV port %u",
824
0
                   inst->app->common.name,
825
0
                   fr_box_ipaddr(connection->address->socket.inet.src_ipaddr),
826
0
                   connection->address->socket.inet.src_port,
827
0
                   fr_box_ipaddr(connection->address->socket.inet.dst_ipaddr),
828
0
                   connection->address->socket.inet.dst_port);
829
0
    } else {
830
0
      connection->name = inst->app_io->get_name(connection->child);
831
0
    }
832
833
    /*
834
     *  Set the names for the listeners.
835
     */
836
0
    connection->listen->name = connection->name;
837
0
    connection->child->name = connection->name;
838
0
  }
839
840
  /*
841
   *  Add the connection to the set of connections for this
842
   *  client.
843
   */
844
0
  pthread_mutex_lock(&client->mutex);
845
0
  if (client->ht) {
846
0
    if (nak) (void) fr_hash_table_delete(client->ht, nak);
847
0
    ret = fr_hash_table_insert(client->ht, connection);
848
0
    client->ready_to_delete = false;
849
0
    connection->in_parent_hash = true;
850
851
0
    if (!ret) {
852
0
      pthread_mutex_unlock(&client->mutex);
853
0
      ERROR("proto_%s - Failed inserting connection into tracking table.  "
854
0
            "Closing it, and discarding all packets for connection %s.",
855
0
            inst->app_io->common.name, connection->name);
856
0
      goto cleanup;
857
0
    }
858
0
  }
859
0
  pthread_mutex_unlock(&client->mutex);
860
861
  /*
862
   *  It's a NAK client.  Set the state to NAK, and don't
863
   *  add it to the scheduler.
864
   */
865
0
  if (nak) {
866
0
    INFO("proto_%s - Verification failed for packet from dynamic client %pV - adding IP address to the NAK cache",
867
0
         inst->app_io->common.name, fr_box_ipaddr(client->src_ipaddr));
868
869
0
    connection->name = talloc_strdup(connection, nak->name);
870
0
    connection->client->state = PR_CLIENT_NAK;
871
0
    connection->el = nak->el;
872
0
    return connection;
873
0
  }
874
875
0
  DEBUG("proto_%s - starting connection %s", inst->app_io->common.name, connection->name);
876
0
  connection->nr = fr_schedule_listen_add(thread->sc, connection->listen);
877
0
  if (!connection->nr) {
878
0
    ERROR("proto_%s - Failed inserting connection into scheduler.  "
879
0
          "Closing it, and diuscarding all packets for connection %s.",
880
0
          inst->app_io->common.name, connection->name);
881
0
    pthread_mutex_lock(&client->mutex);
882
0
    if (client->ht) (void) fr_hash_table_delete(client->ht, connection);
883
0
    pthread_mutex_unlock(&client->mutex);
884
885
0
  cleanup:
886
0
    if (fd >= 0) close(fd);
887
0
    talloc_free(mi);
888
0
    return NULL;
889
0
  }
890
891
  /*
892
   *  We have one more connection.  Note that we do
893
   *  NOT decrement this counter when a connection
894
   *  closes, as the close is done in a child
895
   *  thread.  Instead, we just let counter hit the
896
   *  limit, and then walk over the clients to reset
897
   *  the count.
898
   */
899
0
  thread->num_connections++;
900
901
0
  return connection;
902
0
}
903
904
905
/*
906
 *  And here we go into the rabbit hole...
907
 *
908
 *  @todo future - have a similar structure
909
 *  fr_io_connection_io, which will duplicate some code,
910
 *  but may make things simpler?
911
 */
912
static void get_inst(fr_listen_t *li, fr_io_instance_t const **inst, fr_io_thread_t **thread,
913
         fr_io_connection_t **connection, fr_listen_t **child)
914
0
{
915
0
  if (!li->connected) {
916
0
    *inst = li->app_io_instance;
917
0
    if (thread) *thread = li->thread_instance;
918
0
    *connection = NULL;
919
0
    if (child) *child = ((fr_io_thread_t *)li->thread_instance)->child;
920
921
0
  } else {
922
0
    fr_assert(connection != NULL);
923
924
0
    *connection = li->thread_instance;
925
0
    *inst = (*connection)->client->inst;
926
0
    if (thread) *thread = NULL;
927
0
    if (child) *child = (*connection)->child;
928
0
  }
929
0
}
930
931
932
static fr_client_t *radclient_alloc(TALLOC_CTX *ctx, int ipproto, fr_io_address_t *address)
933
0
{
934
0
  fr_client_t *radclient;
935
0
  char    *shortname;
936
937
0
  MEM(radclient = talloc_zero(ctx, fr_client_t));
938
939
0
  fr_value_box_aprint(radclient, &shortname, fr_box_ipaddr(address->socket.inet.src_ipaddr), NULL);
940
0
  radclient->longname = radclient->shortname = shortname;
941
942
0
  radclient->secret = radclient->nas_type = talloc_strdup(radclient, "");
943
944
0
  radclient->ipaddr = address->socket.inet.src_ipaddr;
945
946
0
  radclient->src_ipaddr = address->socket.inet.dst_ipaddr;
947
948
0
  radclient->proto = ipproto;
949
0
  radclient->dynamic = true;
950
951
0
  return radclient;
952
0
}
953
954
/*
955
 *  Remove a client from the list of "live" clients.
956
 *
957
 *  This function is only used for the "main" socket.  Clients
958
 *  from connections do not use it.
959
 */
960
static int _client_live_free(fr_io_client_t *client)
961
0
{
962
0
  talloc_get_type_abort(client, fr_io_client_t);
963
964
0
  fr_assert(client->in_trie);
965
0
  fr_assert(!client->connection);
966
0
  fr_assert(client->thread);
967
968
0
  if (client->pending) client_pending_free(client);
969
970
0
  (void) fr_trie_remove_by_key(client->thread->trie, &client->src_ipaddr.addr, client->src_ipaddr.prefix);
971
972
0
  if (client->thread->alive_clients) {
973
0
    fr_assert(fr_heap_num_elements(client->thread->alive_clients) > 0);
974
0
    (void) fr_heap_extract(&client->thread->alive_clients, client);
975
0
  }
976
977
0
  if (client->use_connected) (void) pthread_mutex_destroy(&client->mutex);
978
979
0
  return 0;
980
0
}
981
982
/** Allocate a dynamic client.
983
 *
984
 */
985
static fr_io_client_t *client_alloc(TALLOC_CTX *ctx, fr_io_client_state_t state,
986
            fr_io_instance_t const *inst, fr_io_thread_t *thread, fr_client_t *radclient,
987
            fr_ipaddr_t const *network)
988
0
{
989
0
  fr_io_client_t *client;
990
991
  /*
992
   *  Create our own local client.  This client
993
   *  holds our state which really shouldn't go into
994
   *  fr_client_t.
995
   *
996
   *  Note that we create a new top-level talloc
997
   *  context for this client, as there may be tens
998
   *  of thousands of packets associated with this
999
   *  client.  And we want to avoid problems with
1000
   *  O(N) issues in talloc.
1001
   */
1002
0
  MEM(client = talloc_named(ctx, sizeof(fr_io_client_t), "fr_io_client_t"));
1003
0
  memset(client, 0, sizeof(*client));
1004
1005
0
  client->state = state;
1006
0
  client->src_ipaddr = radclient->ipaddr;
1007
0
  client->radclient = radclient;
1008
0
  client->inst = inst;
1009
0
  client->thread = thread;
1010
1011
0
  if (network) {
1012
0
    client->network = *network;
1013
0
  } else {
1014
0
    client->network = client->src_ipaddr;
1015
0
  }
1016
1017
  /*
1018
   *  At this point, this variable can only be true
1019
   *  for STATIC clients.  PENDING clients may set
1020
   *  it to true later, after they've been defined.
1021
   */
1022
0
  client->use_connected = radclient->use_connected;
1023
1024
  /*
1025
   *  Create the pending heap for pending clients.
1026
   */
1027
0
  if (state == PR_CLIENT_PENDING) {
1028
0
    MEM(client->pending = fr_heap_alloc(client, pending_packet_cmp,
1029
0
                fr_io_pending_packet_t, heap_id, 0));
1030
0
  }
1031
1032
  /*
1033
   *  Create the packet tracking table for this client.
1034
   */
1035
0
  if (inst->app_io->track_duplicates) {
1036
0
    fr_assert(inst->app_io->track_compare != NULL);
1037
0
    MEM(client->table = fr_rb_inline_talloc_alloc(client, fr_io_track_t, node, track_cmp, NULL));
1038
0
  }
1039
1040
  /*
1041
   *  Allow connected sockets to be set on a
1042
   *  per-client basis.
1043
   */
1044
0
  if (client->use_connected) {
1045
0
    fr_assert(client->state == PR_CLIENT_STATIC);
1046
1047
0
    (void) pthread_mutex_init(&client->mutex, NULL);
1048
0
    MEM(client->ht = fr_hash_table_alloc(client, connection_hash, connection_cmp, NULL));
1049
0
  }
1050
1051
  /*
1052
   *  Add the newly defined client to the trie of
1053
   *  allowed clients.
1054
   */
1055
0
  if (fr_trie_insert_by_key(thread->trie, &client->src_ipaddr.addr, client->src_ipaddr.prefix, client)) {
1056
0
    ERROR("proto_%s - Failed inserting client %s into tracking table.  Discarding client, and all packets for it.",
1057
0
          inst->app_io->common.name, client->radclient->shortname);
1058
0
    if (client->use_connected) (void) pthread_mutex_destroy(&client->mutex);
1059
0
    talloc_free(client);
1060
0
    return NULL;
1061
0
  }
1062
1063
0
  client->in_trie = true;
1064
1065
  /*
1066
   *  It's a static client.  Don't insert it into the list of alive clients, as those are only for
1067
   *  dynamic clients.
1068
   */
1069
0
  if (state == PR_CLIENT_STATIC) return client;
1070
1071
0
  fr_assert(thread->alive_clients != NULL);
1072
1073
  /*
1074
   *  Track the live clients so that we can clean
1075
   *  them up.
1076
   */
1077
0
  (void) fr_heap_insert(&thread->alive_clients, client);
1078
0
  client->pending_id = FR_HEAP_INDEX_INVALID;
1079
1080
  /*
1081
   *  Now that we've inserted it into the heap and
1082
   *  incremented the numbers, set the destructor
1083
   *  function.
1084
   */
1085
0
  talloc_set_destructor(client, _client_live_free);
1086
1087
0
  return client;
1088
0
}
1089
1090
1091
static fr_io_track_t *fr_io_track_add(fr_listen_t const *li, fr_io_client_t *client,
1092
              fr_io_address_t *address,
1093
              uint8_t const *packet, size_t packet_len,
1094
              fr_time_t recv_time, bool *is_dup)
1095
0
{
1096
0
  size_t len;
1097
0
  fr_io_track_t *track, *old;
1098
1099
0
  *is_dup = false;
1100
1101
  /*
1102
   *  Allocate a new tracking structure.  Most of the time
1103
   *  there are no duplicates, so this is fine.
1104
   */
1105
0
  if (client->connection) {
1106
0
    MEM(track = talloc_zero_pooled_object(client, fr_io_track_t, 1, sizeof(*track) + 64));
1107
0
    track->address = client->connection->address;
1108
0
  } else {
1109
0
    fr_io_address_t *my_address;
1110
1111
0
    MEM(track = talloc_zero_pooled_object(client, fr_io_track_t, 1, sizeof(*track) + sizeof(*track->address) + 64));
1112
0
    MEM(track->address = my_address = talloc(track, fr_io_address_t));
1113
1114
0
    *my_address = *address;
1115
0
    my_address->radclient = client->radclient;
1116
0
  }
1117
1118
0
  track->li = li;
1119
0
  track->client = client;
1120
1121
0
  track->timestamp = recv_time;
1122
0
  track->packets = 1;
1123
1124
  /*
1125
   *  We're not tracking duplicates, so just return the
1126
   *  tracking entry.  This tracks src/dst IP/port, client,
1127
   *  receive time, etc.
1128
   */
1129
0
  if (!client->inst->app_io->track_duplicates) {
1130
0
    client->packets++;
1131
0
    talloc_set_destructor(track, track_free);
1132
0
    return track;
1133
0
  }
1134
1135
  /*
1136
   *  We are checking for duplicates, see if there is a dup
1137
   *  already in the tree.
1138
   */
1139
0
  track->packet = client->inst->app_io->track_create(client->inst->app_io_instance,
1140
0
                 client->thread->child->thread_instance,
1141
0
                 client->radclient,
1142
0
                 track, packet, packet_len);
1143
0
  if (!track->packet) {
1144
0
    talloc_free(track);
1145
0
    return NULL;
1146
0
  }
1147
1148
  /*
1149
   *  No existing duplicate.  Return the new tracking entry.
1150
   */
1151
0
  old = fr_rb_find(client->table, track);
1152
0
  if (!old) goto do_insert;
1153
1154
0
  fr_assert(old->client == client);
1155
1156
  /*
1157
   *  It cannot be both in the free list and in the tracking table.
1158
   *
1159
   *  2020-08-17, this assertion fails randomly in travis.
1160
   *  Which means that "track" was in the free list, *and*
1161
   *  in the rbtree.
1162
   */
1163
0
  fr_assert(old != track);
1164
1165
  /*
1166
   *  The new packet has the same dedup fields as the old
1167
   *  one, BUT it may be a conflicting packet.  Check for
1168
   *  that via a simple memcmp().
1169
   *
1170
   *  It's an exact duplicate.  Drop the new one and
1171
   *  use the old one.
1172
   *
1173
   *  If there's a cached reply, the caller will take care
1174
   *  of sending it to the network layer.
1175
   */
1176
0
  len = talloc_array_length(old->packet);
1177
0
  if ((len == talloc_array_length(track->packet)) &&
1178
0
      (memcmp(old->packet, track->packet, len) == 0)) {
1179
0
    fr_assert(old != track);
1180
1181
    /*
1182
     *  Ignore duplicates while the client is
1183
     *  still pending.
1184
     */
1185
0
    if (client->state == PR_CLIENT_PENDING) {
1186
0
      DEBUG("Ignoring duplicate packet while client %s is still pending dynamic definition",
1187
0
            client->radclient->shortname);
1188
0
      talloc_free(track);
1189
0
      return NULL;
1190
0
    }
1191
1192
0
    *is_dup = true;
1193
0
    old->packets++;
1194
0
    talloc_free(track);
1195
1196
    /*
1197
     *  Retransmits can sit in the outbound queue for
1198
     *  a while.  We don't want to time out this
1199
     *  struct while the packet is in the outbound
1200
     *  queue.
1201
     */
1202
0
    FR_TIMER_DISARM(old->ev);
1203
0
    return old;
1204
0
  }
1205
1206
  /*
1207
   *  Else it's a conflicting packet.  Which is OK if we
1208
   *  already have a reply.  We just delete the old entry,
1209
   *  and insert the new one.
1210
   *
1211
   *  If there's no reply, then the old request is still
1212
   *  "live".  Delete the old one from the tracking tree,
1213
   *  and return the new one.
1214
   */
1215
0
  if (old->reply_len || old->do_not_respond) {
1216
0
    talloc_free(old);
1217
1218
0
  } else {
1219
0
    fr_assert(client == old->client);
1220
1221
0
    if (!fr_rb_delete(client->table, old)) {
1222
0
      fr_assert(0);
1223
0
    }
1224
0
    FR_TIMER_DELETE(&old->ev);
1225
1226
0
    talloc_set_destructor(old, track_free);
1227
1228
0
    old->discard = true; /* don't send any reply, there's nowhere for it to go */
1229
0
  }
1230
1231
0
do_insert:
1232
0
  if (!fr_rb_insert(client->table, track)) {
1233
0
    fr_assert(0);
1234
0
  }
1235
1236
0
  client->packets++;
1237
0
  talloc_set_destructor(track, track_dedup_free);
1238
0
  return track;
1239
0
}
1240
1241
1242
static int pending_free(fr_io_pending_packet_t *pending)
1243
0
{
1244
0
  fr_io_track_t *track = pending->track;
1245
1246
  /*
1247
   *  Note that we don't check timestamps, replies, etc.  If
1248
   *  a packet is pending, then any conflicting packet gets
1249
   *  the "pending" entry marked as such, and a new entry
1250
   *  added.  Any duplicate packet gets suppressed.  And
1251
   *  because the packets are pending, track->reply MUST be
1252
   *  NULL.
1253
   */
1254
0
  fr_assert(track->packets > 0);
1255
0
  track->packets--;
1256
1257
  /*
1258
   *  No more packets using this tracking entry,
1259
   *  delete it.
1260
   */
1261
0
  if (track->packets == 0) talloc_free(track);
1262
1263
0
  return 0;
1264
0
}
1265
1266
static fr_io_pending_packet_t *fr_io_pending_alloc(fr_io_connection_t *connection, fr_io_client_t *client,
1267
               uint8_t const *buffer, size_t packet_len,
1268
               fr_io_track_t *track,
1269
               int priority)
1270
0
{
1271
0
  fr_io_pending_packet_t *pending;
1272
1273
0
  MEM(pending = talloc_zero(client->pending, fr_io_pending_packet_t));
1274
1275
0
  MEM(pending->buffer = talloc_memdup(pending, buffer, packet_len));
1276
0
  pending->buffer_len = packet_len;
1277
0
  pending->priority = priority;
1278
0
  pending->track = track;
1279
0
  pending->recv_time = track->timestamp; /* there can only be one */
1280
1281
0
  talloc_set_destructor(pending, pending_free);
1282
1283
  /*
1284
   *  Insert the pending packet for this client.  If it
1285
   *  fails, silently discard the packet.
1286
   */
1287
0
  if (fr_heap_insert(&client->pending, pending) < 0) {
1288
0
    talloc_free(pending);
1289
0
    return NULL;
1290
0
  }
1291
1292
  /*
1293
   *  We only track pending packets for the
1294
   *  main socket.  For connected sockets,
1295
   *  we pause the FD, so the number of
1296
   *  pending packets will always be small.
1297
   */
1298
0
  if (!connection) client->thread->num_pending_packets++;
1299
1300
0
  return pending;
1301
0
}
1302
1303
1304
/*
1305
 *  Order clients in the alive_clients heap, based on their IP
1306
 *  address.
1307
 *
1308
 *  This function is only used for the "main" socket.  Clients
1309
 *  from connections do not use it.
1310
 */
1311
static int8_t alive_client_cmp(void const *one, void const *two)
1312
0
{
1313
0
  fr_io_client_t const *a = talloc_get_type_abort_const(one, fr_io_client_t);
1314
0
  fr_io_client_t const *b = talloc_get_type_abort_const(two, fr_io_client_t);
1315
1316
0
  return fr_ipaddr_cmp(&a->src_ipaddr, &b->src_ipaddr);
1317
0
}
1318
1319
/**  Implement 99% of the read routines.
1320
 *
1321
 *  The app_io->read does the transport-specific data read.
1322
 */
1323
static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time_p,
1324
      uint8_t *buffer, size_t buffer_len, size_t *leftover)
1325
0
{
1326
0
  fr_io_instance_t const  *inst;
1327
0
  fr_io_thread_t    *thread;
1328
0
  ssize_t     packet_len = -1;
1329
0
  fr_time_t   recv_time = fr_time_wrap(0);
1330
0
  fr_io_client_t    *client;
1331
0
  fr_io_address_t   address;
1332
0
  fr_io_connection_t  my_connection, *connection;
1333
0
  fr_io_pending_packet_t  *pending = NULL;
1334
0
  fr_io_track_t   *track;
1335
0
  fr_listen_t   *child;
1336
0
  int     value, accept_fd = -1;
1337
0
  uint32_t    priority = PRIORITY_NORMAL;
1338
1339
/** Log that we ignore clients in debug mode, or when it's enabled for a listener
1340
 */
1341
0
#define LOG_IGNORED_CLIENTS(_inst) ((_inst)->log_ignored_clients || fr_debug_lvl >= 1)
1342
1343
0
  get_inst(li, &inst, &thread, &connection, &child);
1344
1345
0
  track = NULL;
1346
1347
  /*
1348
   *  There was data left over from the previous read, go
1349
   *  get the rest of it now.  We MUST do this instead of
1350
   *  popping a pending packet, because the leftover bytes
1351
   *  are already in the output buffer.
1352
   */
1353
0
  if (*leftover) goto do_read;
1354
1355
0
redo:
1356
  /*
1357
   *  Read one pending packet.  The packet may be pending
1358
   *  because of dynamic client definitions, or because it's
1359
   *  for a connected UDP socket, and was sent over by the
1360
   *  "master" UDP socket.
1361
   */
1362
0
  if (connection) {
1363
    /*
1364
     *  The connection is dead.  Tell the network side
1365
     *  to close it.
1366
     */
1367
0
    if (connection->dead) {
1368
0
      DEBUG("Dead connection %s", connection->name);
1369
0
      return -1;
1370
0
    }
1371
1372
0
    pending = fr_heap_pop(&connection->client->pending);
1373
1374
0
  } else if (thread->pending_clients) {
1375
0
    pending = pending_packet_pop(thread);
1376
1377
0
  } else {
1378
0
    pending = NULL;
1379
0
  }
1380
1381
0
  if (pending) {
1382
0
    fr_assert(buffer_len >= pending->buffer_len);
1383
0
    track = pending->track;
1384
1385
    /*
1386
     *  Clear the destructor as we now own the
1387
     *  tracking entry.
1388
     */
1389
0
    talloc_set_destructor(pending, NULL);
1390
1391
    /*
1392
     *  We received a conflicting packet while this
1393
     *  packet was pending.  Discard this entry and
1394
     *  try to get another one.
1395
     *
1396
     *  Note that the pending heap is *simple*.  We
1397
     *  just track priority and recv_time.  This means
1398
     *  it's fast, but also that it's hard to look up
1399
     *  random packets in the pending heap.
1400
     */
1401
0
    if (fr_time_neq(pending->recv_time, track->timestamp)) {
1402
0
      DEBUG3("Discarding old packet");
1403
0
      TALLOC_FREE(pending);
1404
0
      goto redo;
1405
0
    }
1406
1407
    /*
1408
     *  We have a valid packet.  Copy it over to the
1409
     *  caller, and return.
1410
     */
1411
0
    *packet_ctx = track;
1412
0
    *leftover = 0;
1413
0
    recv_time = *recv_time_p = pending->recv_time;
1414
0
    client = track->client;
1415
1416
0
    memcpy(buffer, pending->buffer, pending->buffer_len);
1417
0
    packet_len = pending->buffer_len;
1418
1419
    /*
1420
     *  Shouldn't be necessary, but what the heck...
1421
     */
1422
0
    memcpy(&address, track->address, sizeof(address));
1423
0
    TALLOC_FREE(pending);
1424
1425
    /*
1426
     *  Skip over all kinds of logic to find /
1427
     *  allocate the client, when we don't need to do
1428
     *  it any more.
1429
     */
1430
0
    goto have_client;
1431
1432
0
  } else if (!connection && (inst->ipproto == IPPROTO_TCP)) {
1433
0
    struct sockaddr_storage saremote;
1434
0
    socklen_t salen;
1435
1436
0
    salen = sizeof(saremote);
1437
1438
    /*
1439
     *  We're a TCP socket but are NOT connected.  We
1440
     *  must be the master socket.  Accept the new
1441
     *  connection, and figure out src/dst IP/port.
1442
     */
1443
0
    accept_fd = accept(child->fd,
1444
0
           (struct sockaddr *) &saremote, &salen);
1445
1446
    /*
1447
     *  Couldn't open a NEW socket, but THIS ONE is
1448
     *  OK.  So don't return -1.
1449
     */
1450
0
    if (accept_fd < 0) {
1451
0
      RATE_LIMIT_LOCAL(&thread->rate_limit.accept_failed,
1452
0
           INFO, "proto_%s - failed to accept new socket: %s",
1453
0
           inst->app->common.name, fr_syserror(errno));
1454
0
      return 0;
1455
0
    }
1456
1457
    /*
1458
     *  Set the new descriptor to be non-blocking.
1459
     */
1460
0
    (void) fr_nonblock(accept_fd);
1461
1462
#ifdef STATIC_ANALYZER
1463
    saremote.ss_family = AF_INET; /* static analyzer doesn't know that accept() initializes this */
1464
#endif
1465
1466
    /*
1467
     *  Get IP addresses only if we have IP addresses.
1468
     */
1469
0
    if ((saremote.ss_family == AF_INET) || (saremote.ss_family == AF_INET6)) {
1470
0
      memset(&address.socket, 0, sizeof(address.socket));
1471
0
      (void) fr_ipaddr_from_sockaddr(&address.socket.inet.src_ipaddr, &address.socket.inet.src_port,
1472
0
                   &saremote, salen);
1473
0
      salen = sizeof(saremote);
1474
1475
      /*
1476
       *  @todo - only if the local listen address is "*".
1477
       */
1478
0
      (void) getsockname(accept_fd, (struct sockaddr *) &saremote, &salen);
1479
0
      (void) fr_ipaddr_from_sockaddr(&address.socket.inet.dst_ipaddr, &address.socket.inet.dst_port,
1480
0
                   &saremote, salen);
1481
0
      address.socket.type = (inst->ipproto == IPPROTO_TCP) ? SOCK_STREAM : SOCK_DGRAM;
1482
0
      address.socket.fd = accept_fd;
1483
0
    }
1484
1485
0
  } else {
1486
0
    fr_io_address_t *local_address;
1487
1488
    /*
1489
     *  We're either not a TCP socket, or we are a
1490
     *  connected TCP socket.  Just read it.
1491
     */
1492
0
do_read:
1493
0
    local_address = &address;
1494
1495
    /*
1496
     *  @todo - For connected TCP sockets which are
1497
     *  dynamically defined, the app_io read()
1498
     *  function should stop reading the socket if the
1499
     *  server is busy.  That change puts TCP
1500
     *  backpressure on the client.
1501
     *
1502
     *  @todo TLS - for TLS and dynamic sockets, do
1503
     *  the SSL setup here, but have a structure which
1504
     *  describes the TLS data and run THAT through
1505
     *  the dynamic client definition, instead of
1506
     *  using normal packets.  Or, rely on the app_io
1507
     *  read() function to do all TLS work?  Given
1508
     *  that some protocols have "starttls" beginning
1509
     *  after a clear-text exchange, it's likely best
1510
     *  to have yet another layer of trampoline
1511
     *  functions which do all of the TLS work.
1512
     */
1513
0
    packet_len = inst->app_io->read(child, (void **) &local_address, &recv_time,
1514
0
            buffer, buffer_len, leftover);
1515
0
    if (packet_len <= 0) {
1516
0
      return packet_len;
1517
0
    }
1518
1519
    /*
1520
     *  Not allowed?  Discard it.  The priority()
1521
     *  function has done any complaining, if
1522
     *  necessary.
1523
     */
1524
0
    if (inst->app->priority) {
1525
0
      value = inst->app->priority(inst->app_instance, buffer, packet_len);
1526
0
      if (value <= 0) {
1527
0
        static fr_rate_limit_t bad_type;
1528
1529
        /*
1530
         *  @todo - unix sockets.  We need to use
1531
         *  the "name" of the socket, in the
1532
         *  listener?
1533
         */
1534
0
        if (LOG_IGNORED_CLIENTS(inst)) {
1535
0
          RATE_LIMIT_LOCAL(thread ? &thread->rate_limit.bad_type : &bad_type, INFO,
1536
0
               "proto_%s - ignoring packet from IP %pV. It is not configured as 'type = ...'",
1537
0
               inst->app_io->common.name, fr_box_ipaddr(address.socket.inet.src_ipaddr));
1538
0
        }
1539
0
        return 0;
1540
0
      }
1541
0
      priority = value;
1542
0
    }
1543
1544
    /*
1545
     *  If the connection is pending, pause reading of
1546
     *  more packets.  If mod_write() accepts the
1547
     *  connection, it will resume reading.
1548
     *  Otherwise, it will close the socket without
1549
     *  resuming it.
1550
     */
1551
0
    if (connection &&
1552
0
        (connection->client->state == PR_CLIENT_PENDING)) {
1553
0
      fr_assert(!connection->paused);
1554
1555
0
      connection->paused = true;
1556
0
      (void) fr_event_filter_update(connection->el,
1557
0
                  child->fd,
1558
0
                  FR_EVENT_FILTER_IO, pause_read);
1559
0
    }
1560
0
  }
1561
1562
  /*
1563
   *  Look up the client, unless we already have one (for a
1564
   *  connected socket).
1565
   */
1566
0
  if (!connection) {
1567
0
    client = fr_trie_lookup_by_key(thread->trie,
1568
0
          &address.socket.inet.src_ipaddr.addr, address.socket.inet.src_ipaddr.prefix);
1569
0
    fr_assert(!client || !client->connection);
1570
1571
0
  } else {
1572
0
    client = connection->client;
1573
1574
    /*
1575
     *  We don't care what the read function says
1576
     *  about address.  We have it already.
1577
     */
1578
0
    address = *connection->address;
1579
0
  }
1580
1581
  /*
1582
   *  Negative cache entry.  Drop the packet.
1583
   */
1584
0
  if (client && client->state == PR_CLIENT_NAK) {
1585
0
    if (accept_fd >= 0) close(accept_fd);
1586
0
    return 0;
1587
0
  }
1588
1589
  /*
1590
   *  If there's no client, try to pull one from the global
1591
   *  / static client list.  Or if dynamic clients are
1592
   *  allowed, try to define a dynamic client.
1593
   */
1594
0
  if (!client) {
1595
0
    fr_client_t *radclient = NULL;
1596
0
    fr_io_client_state_t state;
1597
0
    fr_ipaddr_t const *network = NULL;
1598
0
    char const *error;
1599
1600
    /*
1601
     *  We MUST be the master socket.
1602
     */
1603
0
    fr_assert(!connection);
1604
1605
0
    radclient = inst->app_io->client_find(thread->child, &address.socket.inet.src_ipaddr, inst->ipproto);
1606
0
    if (radclient) {
1607
0
      state = PR_CLIENT_STATIC;
1608
1609
      /*
1610
       *  Make our own copy that we can modify it.
1611
       */
1612
0
      MEM(radclient = radclient_clone(thread, radclient));
1613
0
      radclient->active = true;
1614
1615
0
    } else if (inst->dynamic_clients) {
1616
0
      if (inst->max_clients && (fr_heap_num_elements(thread->alive_clients) >= inst->max_clients)) {
1617
0
        error = "Too many dynamic clients have been defined";
1618
0
        goto ignore;
1619
0
      }
1620
1621
      /*
1622
       *  Look up the allowed networks.
1623
       */
1624
0
      network = fr_trie_lookup_by_key(inst->networks, &address.socket.inet.src_ipaddr.addr,
1625
0
             address.socket.inet.src_ipaddr.prefix);
1626
0
      if (!network) {
1627
0
        error = "Address is outside of the the 'allow' network range";
1628
0
        goto ignore;
1629
0
      }
1630
1631
      /*
1632
       *  It exists, but it's a "deny" rule, ignore it.
1633
       */
1634
0
      if (network->af == AF_UNSPEC) {
1635
0
        error = "Address is forbidden by the 'deny' network range";
1636
0
        goto ignore;
1637
0
      }
1638
1639
      /*
1640
       *  Allocate our local radclient as a
1641
       *  placeholder for the dynamic client.
1642
       */
1643
0
      radclient = radclient_alloc(thread, inst->ipproto, &address);
1644
0
      state = PR_CLIENT_PENDING;
1645
1646
0
    } else {
1647
0
      char const *msg;
1648
1649
0
      error = "No matching 'client' definition was found";
1650
1651
0
    ignore:
1652
0
      if (accept_fd < 0) {
1653
0
        msg = "packet";
1654
0
      } else {
1655
0
        msg = "connection attempt";
1656
0
        close(accept_fd);
1657
0
      }
1658
1659
0
      if (LOG_IGNORED_CLIENTS(inst)) {
1660
0
        static fr_rate_limit_t unknown_client;
1661
0
        RATE_LIMIT_LOCAL(thread ? &thread->rate_limit.unknown_client : &unknown_client,
1662
0
             ERROR, "proto_%s - Ignoring %s from IP address %pV - %s",
1663
0
             inst->app_io->common.name, msg, fr_box_ipaddr(address.socket.inet.src_ipaddr),
1664
0
             error);
1665
0
      }
1666
1667
0
      return 0;
1668
0
    }
1669
1670
0
    MEM(client = client_alloc(thread, state, inst, thread, radclient, network));
1671
1672
    /*
1673
     *  Parent the dynamic client radclient off the client - it
1674
     *  is the client which gets freed by the dynamic client timers.
1675
     */
1676
0
    if (state == PR_CLIENT_PENDING) talloc_steal(client, radclient);
1677
0
  }
1678
1679
0
have_client:
1680
0
  fr_assert(client->state != PR_CLIENT_INVALID);
1681
0
  fr_assert(client->state != PR_CLIENT_NAK);
1682
1683
  /*
1684
   *  We've accepted a new connection.  Go allocate it, and
1685
   *  let it read from the socket.
1686
   */
1687
0
  if (accept_fd >= 0) {
1688
0
    if (!fr_io_connection_alloc(inst, thread, client, accept_fd, &address, NULL)) {
1689
0
      static fr_rate_limit_t alloc_failed;
1690
1691
0
      RATE_LIMIT_LOCAL(thread ? &thread->rate_limit.conn_alloc_failed : &alloc_failed,
1692
0
           ERROR, "Failed to allocate connection from client %s", client->radclient->shortname);
1693
0
    }
1694
1695
0
    return 0;
1696
0
  }
1697
1698
  /*
1699
   *  No connected sockets, OR we are the connected socket.
1700
   *
1701
   *  Track this packet and return it if necessary.
1702
   */
1703
0
  if (connection || !client->use_connected) {
1704
0
    fr_io_track_t *to_free = NULL;
1705
1706
    /*
1707
     *  Add the packet to the tracking table, if it's
1708
     *  not already there.  Pending packets will be in
1709
     *  the tracking table, but won't be counted as
1710
     *  "live" packets.
1711
     */
1712
0
    if (!track) {
1713
0
      static  fr_rate_limit_t tracking_failed;
1714
0
      bool  is_dup = false;
1715
1716
0
      track = fr_io_track_add(li, client, &address, buffer, packet_len, recv_time, &is_dup);
1717
0
      if (!track) {
1718
0
        RATE_LIMIT_LOCAL(thread ? &thread->rate_limit.tracking_failed : &tracking_failed,
1719
0
             ERROR, "Failed tracking packet from client %s - discarding it",
1720
0
             client->radclient->shortname);
1721
0
        return 0;
1722
0
      }
1723
1724
      /*
1725
       *  If there's a cached reply, just send that and don't do anything else.
1726
       */
1727
0
      if (is_dup) {
1728
0
        fr_network_t *nr;
1729
1730
0
        if (track->do_not_respond) {
1731
0
          DEBUG("Ignoring retransmit from client %s - we are not responding to this request", client->radclient->shortname);
1732
0
          return 0;
1733
0
        }
1734
1735
0
        if (track->discard) {
1736
0
          DEBUG("Ignoring transmit from client %s - we previously received a newer / conflicting packet", client->radclient->shortname);
1737
0
          return 0;
1738
0
        }
1739
1740
0
        if (!track->reply) {
1741
0
          fr_assert(!track->finished);
1742
0
          DEBUG("Ignoring retransmit from client %s - we are still processing the request", client->radclient->shortname);
1743
0
          return 0;
1744
0
        }
1745
1746
0
        if (connection) {
1747
0
          nr = connection->nr;
1748
0
        } else {
1749
0
          nr = thread->nr;
1750
0
        }
1751
1752
        /*
1753
         *  @todo - mark things up so that we know to keep 'track' around
1754
         *  until the packet is actually written to the network.  OR, add
1755
         *  a network API so that the talloc_free() function can remove
1756
         *  the packet from the queue of packets to be retransmitted.
1757
         *
1758
         *  Perhaps via having fr_network_listen_write() return a pointer
1759
         *  to the localized message, and then caching that in the tracking
1760
         *  structure.
1761
         */
1762
0
        DEBUG("Sending duplicate reply to client %s", client->radclient->shortname);
1763
0
        fr_network_listen_write(nr, li, track->reply, track->reply_len,
1764
0
              track, track->timestamp);
1765
0
        return 0;
1766
0
      }
1767
1768
      /*
1769
       *  Got to free this if we don't process the packet.
1770
       */
1771
0
      to_free = track;
1772
0
    }
1773
1774
    /*
1775
     *  This is a pending dynamic client.  See if we
1776
     *  have to either run the dynamic client code to
1777
     *  define the client, OR to push the packet onto
1778
     *  the pending queue for this client.
1779
     */
1780
0
    if (client->state == PR_CLIENT_PENDING) {
1781
      /*
1782
       *  Track pending packets for the master
1783
       *  socket.  Connected sockets are paused
1784
       *  as soon as they are defined, so we
1785
       *  won't be reading any more packets from
1786
       *  them.
1787
       *
1788
       *  Since we don't have pending packets
1789
       *  for connected sockets, we don't need
1790
       *  to track pending packets.
1791
       */
1792
0
      if (!connection && inst->max_pending_packets && (thread->num_pending_packets >= inst->max_pending_packets)) {
1793
0
        RATE_LIMIT_LOCAL(&thread->rate_limit.too_many_pending,
1794
0
             ERROR, "Too many pending dynamic client packets for listener - discarding packet from %pV",
1795
0
             fr_box_ipaddr(client->src_ipaddr));
1796
1797
0
      discard:
1798
0
        talloc_free(to_free);
1799
0
        return 0;
1800
0
      }
1801
1802
      /*
1803
       *  Allocate the pending packet structure.
1804
       */
1805
0
      pending = fr_io_pending_alloc(connection, client, buffer, packet_len,
1806
0
                  track, priority);
1807
0
      if (!pending) {
1808
0
        static fr_rate_limit_t alloc_failed;
1809
0
        RATE_LIMIT_LOCAL(thread ? &thread->rate_limit.alloc_failed : &alloc_failed,
1810
0
             ERROR, "proto_%s - Failed allocating space for dynamic client %pV - discarding packet",
1811
0
             inst->app_io->common.name, fr_box_ipaddr(client->src_ipaddr));
1812
0
        goto discard;
1813
0
      }
1814
1815
0
      if (fr_heap_num_elements(client->pending) > 1) {
1816
0
        DEBUG("Verification is still pending for dynamic client %pV - queuing additional packet(s)",
1817
0
              fr_box_ipaddr(client->src_ipaddr));
1818
0
        return 0;
1819
0
      }
1820
1821
      /*
1822
       *  Tell this packet that it's defining a
1823
       *  dynamic client.
1824
       */
1825
0
      track->dynamic = recv_time;
1826
1827
0
      INFO("proto_%s - Verification started for packet from dynamic client %pV - queuing new packets",
1828
0
           inst->app_io->common.name,  fr_box_ipaddr(client->src_ipaddr));
1829
0
    }
1830
1831
    /*
1832
     *  Remove all cleanup timers for the client /
1833
     *  connection.  It's still in use, so we don't
1834
     *  want to clean it up.
1835
     */
1836
0
    if (fr_timer_armed(client->ev)) {
1837
0
      FR_TIMER_DELETE_RETURN(&client->ev);
1838
0
      client->ready_to_delete = false;
1839
0
    }
1840
1841
    /*
1842
     *  Remove cleanup timers for the connection parent.
1843
     */
1844
0
    if (connection && fr_timer_armed(connection->parent->ev)) {
1845
0
      FR_TIMER_DELETE_RETURN(&connection->parent->ev);
1846
0
      connection->parent->ready_to_delete = false;
1847
0
    }
1848
1849
    /*
1850
     *  Return the packet.
1851
     */
1852
0
    *recv_time_p = track->timestamp;
1853
0
    *packet_ctx = track;
1854
0
    return packet_len;
1855
0
  }
1856
1857
  /*
1858
   *
1859
   */
1860
0
  fr_assert(!pending);
1861
1862
  /*
1863
   *  This must be the main UDP socket which creates
1864
   *  connections.
1865
   */
1866
0
  fr_assert(inst->ipproto == IPPROTO_UDP);
1867
1868
  /*
1869
   *  We're using connected sockets, but this socket isn't
1870
   *  connected.  It must be the master socket.  The master
1871
   *  can either be STATIC, DYNAMIC, or PENDING.  Whatever
1872
   *  the state, the child socket will take care of handling
1873
   *  the packet.  e.g. dynamic clients, etc.
1874
   */
1875
0
  {
1876
0
    bool nak = false;
1877
1878
0
    my_connection.address = &address;
1879
1880
0
    pthread_mutex_lock(&client->mutex);
1881
0
    connection = fr_hash_table_find(client->ht, &my_connection);
1882
0
    if (connection) nak = (connection->client->state == PR_CLIENT_NAK);
1883
0
    pthread_mutex_unlock(&client->mutex);
1884
1885
    /*
1886
     *  The connection is in NAK state, ignore packets
1887
     *  for it.
1888
     */
1889
0
    if (nak) {
1890
0
      RATE_LIMIT_LOCAL(&thread->rate_limit.repeat_nak, ERROR, "proto_%s - Discarding repeated packet from NAK'd dynamic client %pV",
1891
0
           inst->app_io->common.name, fr_box_ipaddr(address.socket.inet.src_ipaddr));
1892
1893
0
      DEBUG("Discarding packet to NAKed connection %s", connection->name);
1894
0
      return 0;
1895
0
    }
1896
0
  }
1897
1898
  /*
1899
   *  No existing connection, create one.
1900
   */
1901
0
  if (!connection) {
1902
0
    connection = fr_io_connection_alloc(inst, thread, client, -1, &address, NULL);
1903
0
    if (!connection) {
1904
0
      RATE_LIMIT_LOCAL(&thread->rate_limit.conn_alloc_failed,
1905
0
           ERROR, "Failed to allocate connection from client %s.  Discarding packet.", client->radclient->shortname);
1906
0
      return 0;
1907
0
    }
1908
0
  }
1909
1910
0
  DEBUG("Sending packet to connection %s", connection->name);
1911
1912
  /*
1913
   *  Inject the packet into the connected socket.  It will
1914
   *  process the packet as if it came in from the network.
1915
   *
1916
   *  @todo future - after creating the connection, put the
1917
   *  current packet into connection->pending, instead of
1918
   *  inject?, and then call fr_network_listen_read() from
1919
   *  the child's instantiation routine???
1920
   *
1921
   *  @todo TCP - for ACCEPT sockets, we don't have a
1922
   *  packet, so don't do this.  Instead, the connection
1923
   *  will take care of figuring out what to do.
1924
   *
1925
   *  We don't need "to_free" after this, as it will be
1926
   *  tracked in the connected socket.
1927
   */
1928
0
  if (fr_network_listen_inject(connection->nr, connection->listen,
1929
0
             buffer, packet_len, recv_time) < 0) {
1930
0
    RATE_LIMIT_LOCAL(&thread->rate_limit.queue_full, PERROR,
1931
0
         "proto_%s - Discarding packet from dynamic client %pV - cannot push packet to connected socket",
1932
0
         inst->app_io->common.name, fr_box_ipaddr(address.socket.inet.src_ipaddr));
1933
    /*
1934
     *  Don't return an error, because that will cause the listener to close its socket.
1935
     */
1936
0
  }
1937
1938
0
  return 0;
1939
0
}
1940
1941
/** Inject a packet to a connection.
1942
 *
1943
 *  Always called in the context of the network.
1944
 */
1945
static int mod_inject(fr_listen_t *li, uint8_t const *buffer, size_t buffer_len, fr_time_t recv_time)
1946
0
{
1947
0
  fr_io_instance_t const *inst;
1948
0
  int   priority;
1949
0
  bool    is_dup = false;
1950
0
  fr_io_connection_t *connection;
1951
0
  fr_io_pending_packet_t *pending;
1952
0
  fr_io_track_t *track;
1953
1954
0
  get_inst(li, &inst, NULL, &connection, NULL);
1955
1956
0
  if (!connection) {
1957
0
    DEBUG2("Received injected packet for an unconnected socket.");
1958
0
    return -1;
1959
0
  }
1960
1961
0
  if (inst->app->priority) {
1962
0
    priority = inst->app->priority(inst->app_instance, buffer, buffer_len);
1963
0
    if (priority <= 0) {
1964
0
      return -1;
1965
0
    }
1966
0
  } else {
1967
0
    priority = PRIORITY_NORMAL;
1968
0
  }
1969
1970
  /*
1971
   *  Track this packet, because that's what mod_read expects.
1972
   */
1973
0
  track = fr_io_track_add(li, connection->client, connection->address,
1974
0
        buffer, buffer_len, recv_time, &is_dup);
1975
0
  if (!track) {
1976
0
    DEBUG2("Failed injecting packet to tracking table");
1977
0
    return -1;
1978
0
  }
1979
1980
0
  talloc_get_type_abort(track, fr_io_track_t);
1981
1982
  /*
1983
   *  @todo future - what to do with duplicates?
1984
   */
1985
0
  fr_assert(!is_dup);
1986
1987
  /*
1988
   *  Remember to restore this packet later.
1989
   */
1990
0
  pending = fr_io_pending_alloc(connection, connection->client, buffer, buffer_len,
1991
0
              track, priority);
1992
0
  if (!pending) {
1993
0
    DEBUG2("Failed injecting packet due to allocation error");
1994
0
    return -1;
1995
0
  }
1996
1997
0
  return 0;
1998
0
}
1999
2000
/** Open a new listener
2001
 *
2002
 */
2003
static int mod_open(fr_listen_t *li)
2004
0
{
2005
0
  fr_io_thread_t *thread;
2006
0
  fr_io_instance_t const *inst;
2007
2008
0
  thread = li->thread_instance;
2009
0
  inst = li->app_io_instance;
2010
2011
0
  if (inst->app_io->open(thread->child) < 0) return -1;
2012
2013
0
  li->fd = thread->child->fd; /* copy this back up */
2014
2015
  /*
2016
   *  Set the name of the socket.
2017
   */
2018
0
  if (!li->app_io->get_name) {
2019
0
    li->name = li->app_io->common.name;
2020
0
  } else {
2021
0
    li->name = li->app_io->get_name(li);
2022
0
  }
2023
2024
  /*
2025
   *  Note that we're opening a child socket, so we don't
2026
   *  put it into the list of global listeners.
2027
   */
2028
2029
0
  return 0;
2030
0
}
2031
2032
2033
/** Set the event list for a new socket
2034
 *
2035
 * @param[in] li the listener
2036
 * @param[in] el the event list
2037
 * @param[in] nr context from the network side
2038
 */
2039
static void mod_event_list_set(fr_listen_t *li, fr_event_list_t *el, void *nr)
2040
0
{
2041
0
  fr_io_instance_t const *inst;
2042
0
  fr_io_connection_t *connection;
2043
0
  fr_io_thread_t *thread;
2044
0
  fr_listen_t *child;
2045
2046
0
  get_inst(li, &inst, &thread, &connection, &child);
2047
2048
  /*
2049
   *  We're not doing IO, so there are no timers for
2050
   *  cleaning up packets, dynamic clients, or connections.
2051
   */
2052
0
  if (!inst->submodule) return;
2053
2054
0
  if (inst->app_io->event_list_set) {
2055
0
    inst->app_io->event_list_set(child, el, nr);
2056
0
  }
2057
2058
  /*
2059
   *  Set event list and network side for this socket.
2060
   */
2061
0
  if (!connection) {
2062
0
    thread->el = el;
2063
0
    thread->nr = nr;
2064
2065
0
  } else {
2066
0
    connection->el = el;
2067
0
    connection->nr = nr;
2068
0
  }
2069
0
}
2070
2071
2072
static void client_expiry_timer(fr_timer_list_t *tl, fr_time_t now, void *uctx)
2073
0
{
2074
0
  fr_io_client_t    *client = talloc_get_type_abort(uctx, fr_io_client_t);
2075
0
  fr_io_instance_t const  *inst;
2076
0
  fr_io_connection_t  *connection;
2077
0
  fr_time_delta_t   delay;
2078
0
  int     connections;
2079
2080
  /*
2081
   *  No event list?  We don't need to expire the client.
2082
   */
2083
0
  if (!tl) return;
2084
2085
  // @todo - print out what we plan on doing next
2086
0
  connection = client->connection;
2087
0
  inst = client->inst;
2088
2089
0
  fr_assert(client->state != PR_CLIENT_STATIC);
2090
2091
  /*
2092
   *  Called from the read or write functions with
2093
   *  now==0, to signal that we have to *set* the timer.
2094
   */
2095
0
  if (fr_time_eq(now, fr_time_wrap(0))) {
2096
    /*
2097
     *  The timer is already set, don't do anything.
2098
     */
2099
0
    if (fr_timer_armed(client->ev)) return;
2100
2101
0
    switch (client->state) {
2102
0
    case PR_CLIENT_CONNECTED:
2103
0
      fr_assert(connection != NULL);
2104
0
      delay = inst->idle_timeout;
2105
0
      if (fr_time_delta_ispos(client->radclient->limit.idle_timeout) &&
2106
0
          (fr_time_delta_lt(client->radclient->limit.idle_timeout, inst->idle_timeout))) {
2107
0
        delay = client->radclient->limit.idle_timeout;
2108
0
      }
2109
0
      break;
2110
2111
0
    case PR_CLIENT_DYNAMIC:
2112
0
      delay = inst->dynamic_timeout;
2113
0
      break;
2114
2115
0
    case PR_CLIENT_NAK:
2116
0
      delay = inst->nak_lifetime;
2117
0
      break;
2118
2119
0
    default:
2120
0
      fr_assert(0 == 1);
2121
0
      return;
2122
0
    }
2123
2124
0
    DEBUG("TIMER - setting idle timeout to %pVs for connection from client %s", fr_box_time_delta(delay), client->radclient->shortname);
2125
2126
0
    goto reset_timer;
2127
0
  }
2128
2129
  /*
2130
   *  It's a negative cache entry.  Just delete it.
2131
   */
2132
0
  if (client->state == PR_CLIENT_NAK) {
2133
0
    INFO("proto_%s - Expiring NAK'd dynamic client %pV - permitting new packets to be verified",
2134
0
         inst->app_io->common.name, fr_box_ipaddr(client->src_ipaddr));
2135
2136
0
  delete_client:
2137
0
    fr_assert(client->packets == 0);
2138
2139
    /*
2140
     *  It's a connected socket.  Remove it from the
2141
     *  parents list of connections, and delete it.
2142
     */
2143
0
    if (connection) {
2144
0
      pthread_mutex_lock(&connection->parent->mutex);
2145
0
      if (connection->in_parent_hash) {
2146
0
        connection->in_parent_hash = false;
2147
0
        (void) fr_hash_table_delete(connection->parent->ht, connection);
2148
0
      }
2149
0
      pthread_mutex_unlock(&connection->parent->mutex);
2150
2151
      /*
2152
       *  Mark the connection as dead, and tell
2153
       *  the network side to stop reading from
2154
       *  it.
2155
       */
2156
0
      connection->dead = true;
2157
0
      fr_network_listen_read(connection->nr, connection->listen);
2158
0
      return;
2159
0
    }
2160
2161
0
    talloc_free(client);
2162
0
    return;
2163
0
  }
2164
2165
0
  DEBUG2("TIMER - checking status of dynamic client %s %pV", client->radclient->shortname, fr_box_ipaddr(client->src_ipaddr));
2166
2167
  /*
2168
   *  It's a dynamically defined client.  If no one is using
2169
   *  it, clean it up after an idle timeout.
2170
   */
2171
0
  if ((client->state == PR_CLIENT_DYNAMIC) ||
2172
0
      (client->state == PR_CLIENT_CONNECTED)) {
2173
0
    if (client->packets > 0) {
2174
0
      client->ready_to_delete = false;
2175
0
      return;
2176
0
    }
2177
2178
    /*
2179
     *  No packets, check / set idle timeout.
2180
     */
2181
0
    goto idle_timeout;
2182
0
  }
2183
2184
  /*
2185
   *  The client is pending definition.  It's either a
2186
   *  dynamic client which has timed out, OR it's a
2187
   *  "place-holder" client for connected sockets.
2188
   */
2189
0
  fr_assert(client->state == PR_CLIENT_PENDING);
2190
2191
  /*
2192
   *  This is a dynamic client pending definition.
2193
   *  But it's taken too long to define, so we just
2194
   *  delete the client, and all packets for it.  A
2195
   *  new packet will cause the dynamic definition
2196
   *  to be run again.
2197
   */
2198
0
  if (!client->use_connected) {
2199
0
    if (!client->packets) {
2200
0
      DEBUG("proto_%s - No packets are using unconnected socket", inst->app_io->common.name);
2201
0
      goto delete_client;
2202
0
    }
2203
2204
    /*
2205
     *  Tell the writer to NOT dynamically define the
2206
     *  client.  We've run into a problem.  Then,
2207
     *  return.  The writer will take care of calling
2208
     *  us again when it notices that a PENDING client
2209
     *  is ready to delete.
2210
     *
2211
     *  TBH... that shouldn't happen?  We should rely
2212
     *  on the write to do this all of the time...
2213
     */
2214
0
    client->ready_to_delete = true;
2215
0
    return;
2216
0
  }
2217
2218
0
  fr_assert(!connection);
2219
2220
  /*
2221
   *  Find out how many connections are using this
2222
   *  client.
2223
   */
2224
0
  pthread_mutex_lock(&client->mutex);
2225
0
  fr_assert(client->ht != NULL);
2226
0
  connections = fr_hash_table_num_elements(client->ht);
2227
0
  pthread_mutex_unlock(&client->mutex);
2228
2229
  /*
2230
   *  No connections are using this client.  If
2231
   *  we've passed the idle timeout, then just
2232
   *  delete it.  Otherwise, set an idle timeout (as
2233
   *  above);
2234
   */
2235
0
  if (!connections) {
2236
0
idle_timeout:
2237
    /*
2238
     *  We didn't receive any packets during the
2239
     *  idle_timeout, just delete it.
2240
     */
2241
0
    if (client->ready_to_delete) {
2242
0
      if (connection) {
2243
0
        DEBUG("proto_%s - idle timeout for connection %s", inst->app_io->common.name, connection->name);
2244
0
      } else {
2245
0
        DEBUG("proto_%s - idle timeout for client %s", inst->app_io->common.name, client->radclient->shortname);
2246
0
      }
2247
0
      goto delete_client;
2248
0
    }
2249
2250
    /*
2251
     *  No packets and no idle timeout set, go set
2252
     *  idle timeut.
2253
     */
2254
0
    client->ready_to_delete = true;
2255
0
    delay = client->state == PR_CLIENT_DYNAMIC ? inst->dynamic_timeout : inst->idle_timeout;
2256
0
    goto reset_timer;
2257
0
  }
2258
2259
  /*
2260
   *  There are live sub-connections.  Poll again after a
2261
   *  long period of time.  Once all of the connections are
2262
   *  closed, we can then delete this client.
2263
   *
2264
   *  @todo - maybe just leave it?  we want to be able to
2265
   *  clean up this client after a while tho... especially
2266
   *  if the total number of clients is limited.
2267
   */
2268
0
  client->ready_to_delete = false;
2269
0
  delay = inst->check_interval;
2270
2271
0
reset_timer:
2272
0
  if (fr_timer_in(client, tl, &client->ev,
2273
0
      delay, false, client_expiry_timer, client) < 0) {
2274
0
    ERROR("proto_%s - Failed adding timeout for dynamic client %s.  It will be permanent!",
2275
0
          inst->app_io->common.name, client->radclient->shortname);
2276
0
    return;
2277
0
  }
2278
2279
0
  return;
2280
0
}
2281
2282
2283
/*
2284
 *  Expire cached packets after cleanup_delay time
2285
 */
2286
static void packet_expiry_timer(fr_timer_list_t *tl, fr_time_t now, void *uctx)
2287
0
{
2288
0
  fr_io_track_t *track = talloc_get_type_abort(uctx, fr_io_track_t);
2289
0
  fr_io_client_t *client = track->client;
2290
0
  fr_io_instance_t const *inst = client->inst;
2291
2292
  /*
2293
   *  Insert the timer if requested.
2294
   *
2295
   *  On duplicates this also extends the expiry timer.
2296
   */
2297
0
  if (fr_time_eq(now, fr_time_wrap(0)) && !track->discard && inst->app_io->track_duplicates) {
2298
0
    fr_assert(fr_time_delta_ispos(inst->cleanup_delay));
2299
0
    fr_assert(track->do_not_respond || track->reply_len);
2300
2301
0
    track->expires = fr_time_add(fr_time(), inst->cleanup_delay);
2302
2303
    /*
2304
     *  if the timer succeeds, then "track"
2305
     *  will be cleaned up when the timer
2306
     *  fires.
2307
     */
2308
0
    if (fr_timer_at(track, tl, &track->ev,
2309
0
        track->expires,
2310
0
        false, packet_expiry_timer, track) == 0) {
2311
0
      DEBUG("proto_%s - cleaning up request in %.6fs", inst->app_io->common.name,
2312
0
            fr_time_delta_unwrap(inst->cleanup_delay) / (double)NSEC);
2313
0
      return;
2314
0
    }
2315
2316
0
    DEBUG("proto_%s - Failed adding cleanup_delay for packet.  Discarding packet immediately",
2317
0
          inst->app_io->common.name);
2318
0
  }
2319
2320
  /*
2321
   *  So that all cleanup paths can come here, not just the
2322
   *  timeout ones.
2323
   */
2324
0
  if (fr_time_neq(now, fr_time_wrap(0))) {
2325
0
    DEBUG2("TIMER - proto_%s - cleanup delay", inst->app_io->common.name);
2326
0
  } else {
2327
0
    DEBUG2("proto_%s - cleaning up", inst->app_io->common.name);
2328
0
  }
2329
2330
  /*
2331
   *  Delete the tracking entry.
2332
   */
2333
0
  talloc_free(track);
2334
2335
  /*
2336
   *  The client isn't dynamic, stop here.
2337
   */
2338
0
  if (client->state == PR_CLIENT_STATIC) return;
2339
2340
0
  fr_assert(client->state != PR_CLIENT_NAK);
2341
0
  fr_assert(client->state != PR_CLIENT_PENDING);
2342
2343
  /*
2344
   *  If necessary, call the client expiry timer to clean up
2345
   *  the client.
2346
   */
2347
0
  if (client->packets == 0) {
2348
0
    client_expiry_timer(tl, now, client);
2349
0
  }
2350
0
}
2351
2352
static void update_client(fr_io_client_t *client, fr_client_t *radclient)
2353
0
{
2354
2355
  /*
2356
   *  The new client is mostly OK.  Copy the various fields
2357
   *  over.
2358
   */
2359
0
#define COPY_FIELD(_dest, _x) _dest->radclient->_x = radclient->_x
2360
0
#define DUP_FIELD(_dest, _x) _dest->radclient->_x = talloc_strdup(_dest->radclient, radclient->_x)
2361
2362
  /*
2363
   *  Only these two fields are set.  Other strings in
2364
   *  radclient are copies of these ones.
2365
   */
2366
0
  talloc_const_free(client->radclient->shortname);
2367
0
  talloc_const_free(client->radclient->secret);
2368
2369
0
  DUP_FIELD(client, longname);
2370
0
  DUP_FIELD(client, shortname);
2371
0
  DUP_FIELD(client, secret);
2372
0
  DUP_FIELD(client, nas_type);
2373
2374
0
  COPY_FIELD(client, ipaddr);
2375
0
  COPY_FIELD(client, src_ipaddr);
2376
0
  COPY_FIELD(client, require_message_authenticator);
2377
0
  COPY_FIELD(client, require_message_authenticator_is_set);
2378
#ifdef NAS_VIOLATES_RFC
2379
  COPY_FIELD(client, allow_vulnerable_clients);
2380
#endif
2381
0
  COPY_FIELD(client, limit_proxy_state);
2382
0
  COPY_FIELD(client, limit_proxy_state_is_set);
2383
0
  COPY_FIELD(client, use_connected);
2384
0
  COPY_FIELD(client, cs);
2385
0
}
2386
2387
static ssize_t mod_write(fr_listen_t *li, void *packet_ctx, fr_time_t request_time,
2388
       uint8_t *buffer, size_t buffer_len, size_t written)
2389
0
{
2390
0
  fr_io_instance_t const *inst;
2391
0
  fr_io_thread_t *thread;
2392
0
  fr_io_connection_t *connection;
2393
0
  fr_io_track_t *track = talloc_get_type_abort(packet_ctx, fr_io_track_t);
2394
0
  fr_io_client_t *client;
2395
0
  fr_client_t *radclient;
2396
0
  fr_listen_t *child;
2397
0
  fr_event_list_t *el;
2398
0
  char const *name;
2399
2400
0
  get_inst(li, &inst, &thread, &connection, &child);
2401
2402
0
  client = track->client;
2403
0
  if (connection) {
2404
0
    el = connection->el;
2405
0
    name = connection->name;
2406
0
  } else {
2407
0
    el = thread->el;
2408
0
    name = li->name;
2409
0
  }
2410
2411
0
  DEBUG3("Processing reply for %s", name);
2412
2413
  /*
2414
   *  A fully defined client means that we just send the reply.
2415
   */
2416
0
  if (client->state != PR_CLIENT_PENDING) {
2417
0
    ssize_t packet_len;
2418
2419
0
    track->finished = true;
2420
2421
    /*
2422
     *  The request received a conflicting packet, so we
2423
     *  discard this one.
2424
     */
2425
0
    if (fr_time_neq(track->timestamp, request_time) || track->discard) {
2426
0
      fr_assert(track->packets > 0);
2427
0
      track->packets--;
2428
0
      DEBUG3("Suppressing reply as we have a newer / conflicing packet from the same source");
2429
0
      track->discard = true;
2430
0
      goto setup_timer;
2431
0
    }
2432
2433
    /*
2434
     *  We have a NAK packet, or the request has timed
2435
     *  out, or it was discarded due to a conflicting
2436
     *  packet.  We don't respond, but we do cache the
2437
     *  "do not respond" reply for a period of time.
2438
     */
2439
0
    if ((buffer_len == 1) || track->do_not_respond) {
2440
0
      DEBUG3("Not sending response to request - it is marked as 'do not respond'");
2441
0
      track->do_not_respond = true;
2442
0
      goto setup_timer;
2443
0
    }
2444
2445
    /*
2446
     *  We have a real packet, write it to the network
2447
     *  via the underlying transport write.
2448
     */
2449
0
    packet_len = inst->app_io->write(child, track, request_time,
2450
0
             buffer, buffer_len, written);
2451
0
    if (packet_len <= 0) {
2452
0
      ERROR("Failed writing the reply - not sending any response on %s", name);
2453
0
      track->discard = true;
2454
0
      packet_expiry_timer(el->tl, fr_time_wrap(0), track);
2455
0
      return packet_len;
2456
0
    }
2457
2458
    /*
2459
     *  Only a partial write.  The network code will
2460
     *  take care of calling us again, and we will set
2461
     *  the expiry timer at that point.
2462
     */
2463
0
    if ((size_t) packet_len < buffer_len) {
2464
0
      DEBUG3("Partial write (%zd < %zu)", packet_len, buffer_len);
2465
0
      return packet_len;
2466
0
    }
2467
2468
    /*
2469
     *  We're not tracking duplicates, so just expire
2470
     *  the packet now.
2471
     */
2472
0
    if (!inst->app_io->track_duplicates) {
2473
0
      DEBUG3("Not tracking duplicates - expiring the request");
2474
0
      goto setup_timer;
2475
0
    }
2476
2477
    /*
2478
     *  Cache the reply packet if we're doing dedup.
2479
     *
2480
     *  On resend duplicate reply, the reply is
2481
     *  already filled out.  So we don't do that twice.
2482
     */
2483
0
    if (!track->reply) {
2484
0
      DEBUG3("Caching reply");
2485
0
      MEM(track->reply = talloc_memdup(track, buffer, buffer_len));
2486
0
      track->reply_len = buffer_len;
2487
0
    }
2488
2489
    /*
2490
     *  Set the timer to expire the packet.
2491
     *
2492
     *  On dedup this also extends the timer.
2493
     */
2494
0
  setup_timer:
2495
0
    packet_expiry_timer(el->tl, fr_time_wrap(0), track);
2496
0
    return buffer_len;
2497
0
  }
2498
2499
  /*
2500
   *  The client is pending, so we MUST have dynamic clients.
2501
   *
2502
   *  If there's a connected socket and no dynamic clients, then the
2503
   *  client state is set to CONNECTED when the client is created.
2504
   */
2505
0
  fr_assert(inst->dynamic_clients);
2506
0
  fr_assert(client->pending != NULL);
2507
2508
  /*
2509
   *  The request failed trying to define the dynamic
2510
   *  client.  Discard the client and all pending packets.
2511
   */
2512
0
  if ((buffer_len == 1) && (*buffer == true)) {
2513
0
    DEBUG("Request failed trying to define a new client.  Discarding client and pending packets.");
2514
2515
0
    if (!connection) {
2516
0
      talloc_free(client);
2517
0
      return buffer_len;
2518
0
    }
2519
2520
    /*
2521
     *  Free pending packets and tracking table.
2522
     *  The table is parented by connection->parent, so won't
2523
     *  be auto-freed when connection->client is freed.
2524
     */
2525
0
    TALLOC_FREE(client->pending);
2526
0
    if (client->table) TALLOC_FREE(client->table);
2527
2528
    /*
2529
     *  Remove from parent's hash table so new packets won't
2530
     *  be routed to this connection.
2531
     */
2532
0
    pthread_mutex_lock(&connection->parent->mutex);
2533
0
    if (connection->in_parent_hash) {
2534
0
      connection->in_parent_hash = false;
2535
0
      (void) fr_hash_table_delete(connection->parent->ht, connection);
2536
0
    }
2537
0
    pthread_mutex_unlock(&connection->parent->mutex);
2538
2539
    /*
2540
     *  Mark the connection as dead, then trigger the
2541
     *  standard cleanup path via fr_network_listen_read().
2542
     *  This calls mod_read(), which sees connection->dead,
2543
     *  returns -1, and the network layer closes the
2544
     *  connection through its normal error handling.
2545
     */
2546
0
    connection->dead = true;
2547
0
    fr_network_listen_read(connection->nr, connection->listen);
2548
2549
0
    return buffer_len;
2550
0
  }
2551
2552
  /*
2553
   *  The dynamic client was NOT defined.  Set it's state to
2554
   *  NAK, delete all pending packets, and close the
2555
   *  tracking table.
2556
   */
2557
0
  if (buffer_len == 1) {
2558
0
    INFO("proto_%s - Verification failed for packet from dynamic client %pV - adding IP address to the NAK cache",
2559
0
         inst->app_io->common.name,  fr_box_ipaddr(client->src_ipaddr));
2560
2561
0
    client->state = PR_CLIENT_NAK;
2562
0
    if (!connection) {
2563
0
      client_pending_free(client);
2564
0
    } else {
2565
0
      TALLOC_FREE(client->pending);
2566
0
    }
2567
0
    if (client->table) TALLOC_FREE(client->table);
2568
0
    fr_assert(client->packets == 0);
2569
2570
    /*
2571
     *  If we're a connected UDP socket, allocate a
2572
     *  new connection which is the place-holder for
2573
     *  the NAK.  We will reject packets from from the
2574
     *  src/dst IP/port.
2575
     *
2576
     *  The timer will take care of deleting the NAK
2577
     *  connection (which doesn't have any FDs
2578
     *  associated with it).  The network side will
2579
     *  call mod_close() when the original connection
2580
     *  is done, which will then free that connection,
2581
     *  too.
2582
     */
2583
0
    if (connection && (inst->ipproto == IPPROTO_UDP)) {
2584
0
      MEM(connection = fr_io_connection_alloc(inst, thread, client, -1, connection->address, connection));
2585
0
      client_expiry_timer(el->tl, fr_time_wrap(0), connection->client);
2586
2587
0
      errno = ECONNREFUSED;
2588
0
      return -1;
2589
0
    }
2590
2591
    /*
2592
     *  For connected TCP sockets, we just call the
2593
     *  expiry timer, which will close and free the
2594
     *  connection.
2595
     */
2596
0
    client_expiry_timer(el->tl, fr_time_wrap(0), client);
2597
0
    return buffer_len;
2598
0
  }
2599
2600
0
  fr_assert(buffer_len == sizeof(radclient));
2601
2602
0
  memcpy(&radclient, buffer, sizeof(radclient));
2603
2604
0
  if (!connection) {
2605
0
    fr_ipaddr_t ipaddr;
2606
2607
    /*
2608
     *  Check the encapsulating network against the
2609
     *  address that the user wants to use, but only
2610
     *  for unconnected sockets.
2611
     */
2612
0
    if (client->network.af != radclient->ipaddr.af) {
2613
0
      DEBUG("Client IP address %pV IP family does not match the source network %pV of the packet.",
2614
0
            fr_box_ipaddr(radclient->ipaddr), fr_box_ipaddr(client->network));
2615
0
      goto error;
2616
0
    }
2617
2618
    /*
2619
     *  Network prefix is more restrictive than the one given
2620
     *  by the client... that's bad.
2621
     */
2622
0
    if (client->network.prefix > radclient->ipaddr.prefix) {
2623
0
      DEBUG("Client IP address %pV is not within the prefix with the defined network %pV",
2624
0
            fr_box_ipaddr(radclient->ipaddr), fr_box_ipaddr(client->network));
2625
0
      goto error;
2626
0
    }
2627
2628
0
    ipaddr = radclient->ipaddr;
2629
0
    fr_ipaddr_mask(&ipaddr, client->network.prefix);
2630
0
    if (fr_ipaddr_cmp(&ipaddr, &client->network) != 0) {
2631
0
      DEBUG("Client IP address %pV is not within the defined network %pV.",
2632
0
            fr_box_ipaddr(radclient->ipaddr), fr_box_ipaddr(client->network));
2633
0
      goto error;
2634
0
    }
2635
2636
    /*
2637
     *  We can't define dynamic clients as networks (for now).
2638
     *
2639
     *  @todo - If we did allow it, we would have to remove
2640
     *  this client from the trie, update it's IP address, and
2641
     *  re-add it.  We can PROBABLY do this if this client
2642
     *  isn't already connected, AND radclient->use_connected
2643
     *  is true.  But that's for later...
2644
     */
2645
0
    if (((radclient->ipaddr.af == AF_INET) &&
2646
0
         (radclient->ipaddr.prefix != 32)) ||
2647
0
        ((radclient->ipaddr.af == AF_INET6) &&
2648
0
         (radclient->ipaddr.prefix != 128))) {
2649
0
      ERROR("Cannot define a dynamic client as a network");
2650
2651
0
    error:
2652
0
      talloc_free(radclient);
2653
2654
      /*
2655
       *  Remove the pending client from the trie.
2656
       */
2657
0
      fr_assert(!connection);
2658
0
      talloc_free(client);
2659
0
      return buffer_len;
2660
0
    }
2661
0
  }
2662
2663
0
  update_client(client, radclient);
2664
2665
  // @todo - fill in other fields?
2666
2667
0
  talloc_free(radclient);
2668
2669
0
  radclient = client->radclient; /* laziness */
2670
0
  radclient->server_cs = inst->server_cs;
2671
0
  radclient->server = cf_section_name2(inst->server_cs);
2672
2673
  /*
2674
   *  This is a connected socket, and it's just been
2675
   *  allowed.  Go poke the network side to read from the
2676
   *  socket.
2677
   */
2678
0
  if (connection) {
2679
0
    fr_assert(connection != NULL);
2680
0
    fr_assert(connection->client == client);
2681
0
    fr_assert(client->connection != NULL);
2682
2683
0
    client->state = PR_CLIENT_CONNECTED;
2684
2685
    /*
2686
     *  Connections can't spawn new connections.
2687
     */
2688
0
    client->use_connected = radclient->use_connected = false;
2689
2690
    /*
2691
     *  If we were paused. resume reading from the
2692
     *  connection.
2693
     *
2694
     *  Note that the event list doesn't like resuming
2695
     *  a connection that isn't paused.  It just sets
2696
     *  the read function to NULL.
2697
     */
2698
0
    if (connection->paused) {
2699
0
      (void) fr_event_filter_update(el, child->fd,
2700
0
                  FR_EVENT_FILTER_IO, resume_read);
2701
0
    }
2702
2703
0
    connection->parent->radclient->active = true;
2704
0
    fr_assert(connection->parent->state == PR_CLIENT_PENDING);
2705
0
    connection->parent->state = PR_CLIENT_DYNAMIC;
2706
2707
0
    update_client(connection->parent, radclient);
2708
2709
    /*
2710
     *  Re-parent the conf section used to build this client
2711
     *  so its lifetime is linked to parent client
2712
     */
2713
0
    talloc_steal(connection->parent->radclient, connection->parent->radclient->cs);
2714
2715
    /*
2716
     *  The client has been allowed.
2717
     */
2718
0
    client->state = PR_CLIENT_DYNAMIC;
2719
0
    client->radclient->active = true;
2720
2721
0
    INFO("proto_%s - Verification succeeded for packet from dynamic client %pV - processing queued packets",
2722
0
         inst->app_io->common.name,  fr_box_ipaddr(client->src_ipaddr));
2723
0
    goto finish;
2724
0
  } else {
2725
    /*
2726
     *  Re-parent the conf section used to build this client
2727
     *  so its lifetime is linked to the client
2728
     */
2729
0
    talloc_steal(radclient, radclient->cs);
2730
0
  }
2731
2732
0
  fr_assert(connection == NULL);
2733
0
  fr_assert(client->use_connected == false); /* we weren't sure until now */
2734
2735
  /*
2736
   *  Disallow unsupported configurations.
2737
   */
2738
0
  if (radclient->use_connected && !inst->app_io->connection_set) {
2739
0
    DEBUG("proto_%s - cannot use connected sockets as underlying 'transport = %s' does not support it.",
2740
0
          inst->app_io->common.name, inst->submodule->module->exported->name);
2741
0
    goto error;
2742
0
  }
2743
2744
2745
  /*
2746
   *  Dynamic clients can spawn new connections.
2747
   */
2748
0
  client->use_connected = radclient->use_connected;
2749
2750
  /*
2751
   *  The admin has defined a client which uses connected
2752
   *  sockets.  Go spawn it
2753
   */
2754
0
  if (client->use_connected) {
2755
0
    fr_assert(connection == NULL);
2756
2757
2758
    /*
2759
     *  Leave the state as PENDING.  Each connection
2760
     *  will then cause a dynamic client to be
2761
     *  defined.
2762
     */
2763
0
    (void) pthread_mutex_init(&client->mutex, NULL);
2764
0
    MEM(client->ht = fr_hash_table_alloc(client, connection_hash, connection_cmp, NULL));
2765
2766
0
  } else {
2767
    /*
2768
     *  The client has been allowed.
2769
     */
2770
0
    client->state = PR_CLIENT_DYNAMIC;
2771
0
    client->radclient->active = true;
2772
2773
0
    INFO("proto_%s - Verification succeeded for packet from dynamic client %pV - processing %d queued packets",
2774
0
         inst->app_io->common.name,  fr_box_ipaddr(client->src_ipaddr),
2775
0
         fr_heap_num_elements(client->pending));
2776
0
  }
2777
2778
  /*
2779
   *  Add this client to the master socket, so that
2780
   *  mod_read() will see the pending client, pop the
2781
   *  pending packet, and process it.
2782
   *
2783
   */
2784
0
  if (!thread->pending_clients) {
2785
0
    MEM(thread->pending_clients = fr_heap_alloc(thread, pending_client_cmp,
2786
0
                 fr_io_client_t, pending_id, 0));
2787
0
  }
2788
2789
0
  fr_assert(!fr_heap_entry_inserted((client->pending_id)));
2790
0
  (void) fr_heap_insert(&thread->pending_clients, client);
2791
2792
0
finish:
2793
  /*
2794
   *  Maybe we defined the client, but the original packet
2795
   *  timed out, so there's nothing more to do.  In that case, set up the expiry timers.
2796
   */
2797
0
  if (client->packets == 0) {
2798
0
    client_expiry_timer(el->tl, fr_time_wrap(0), client);
2799
0
  }
2800
2801
  /*
2802
   *  If there are pending packets (and there should be at
2803
   *  least one), tell the network socket to call our read()
2804
   *  function again.
2805
   */
2806
0
  if (fr_heap_num_elements(client->pending) > 0) {
2807
0
    if (connection) {
2808
0
      fr_network_listen_read(connection->nr, connection->listen);
2809
0
    } else {
2810
0
      fr_network_listen_read(thread->nr, thread->listen);
2811
0
    }
2812
0
  }
2813
2814
0
  return buffer_len;
2815
0
}
2816
2817
/** Close the socket.
2818
 *
2819
 */
2820
static int mod_close(fr_listen_t *li)
2821
0
{
2822
0
  fr_io_instance_t const *inst;
2823
0
  fr_io_connection_t *connection;
2824
0
  fr_listen_t *child;
2825
2826
0
  get_inst(li, &inst, NULL, &connection, &child);
2827
2828
0
  if (inst->app_io->close) {
2829
0
    int ret;
2830
2831
0
    ret = inst->app_io->close(child);
2832
0
    if (ret < 0) return ret;
2833
0
  } else {
2834
0
    close(child->fd);
2835
//    child->fd = -1;
2836
0
  }
2837
2838
0
  if (!connection) return 0;
2839
2840
  /*
2841
   *  We allocated this, so we're responsible for closing
2842
   *  it.
2843
   */
2844
0
  DEBUG("Closing connection %s", connection->name);
2845
0
  if (connection->client->pending) {
2846
0
    TALLOC_FREE(connection->client->pending); /* for any pending packets */
2847
0
  }
2848
2849
  /*
2850
   *  Remove connection from parent hash table
2851
   */
2852
0
  pthread_mutex_lock(&connection->parent->mutex);
2853
0
  if (connection->in_parent_hash) {
2854
0
    connection->in_parent_hash = false;
2855
0
    (void) fr_hash_table_delete(connection->parent->ht, connection);
2856
0
  }
2857
2858
  /*
2859
   *  If this is a dynamic client, and the parent has no more connections
2860
   *  set up the timer to expire the dynamic client.
2861
   */
2862
0
  if ((connection->parent->state == PR_CLIENT_DYNAMIC) &&
2863
0
      ((!connection->parent->ht) || (fr_hash_table_num_elements(connection->parent->ht) == 0))) {
2864
0
    client_expiry_timer(connection->el->tl, fr_time_wrap(0), connection->parent);
2865
0
  }
2866
0
  pthread_mutex_unlock(&connection->parent->mutex);
2867
2868
0
  talloc_free(connection->mi);
2869
2870
0
  return 0;
2871
0
}
2872
2873
static int mod_instantiate(module_inst_ctx_t const *mctx)
2874
0
{
2875
0
  fr_io_instance_t *inst = mctx->mi->data;
2876
0
  CONF_SECTION *conf = mctx->mi->conf;
2877
2878
0
  inst->mi = mctx->mi;
2879
0
  inst->app_io = (fr_app_io_t const *) inst->submodule->exported;
2880
0
  inst->app_io_conf = inst->submodule->conf;
2881
0
  inst->app_io_instance = inst->submodule->data;
2882
2883
  /*
2884
   *  If we're not tracking duplicates then we don't need a
2885
   *  cleanup delay.
2886
   *
2887
   *  If we are tracking duplicates, then we must have a non-zero cleanup delay.
2888
   */
2889
0
  if (!inst->app_io->track_duplicates) {
2890
0
    inst->cleanup_delay = fr_time_delta_wrap(0);
2891
2892
0
  } else {
2893
0
    FR_TIME_DELTA_BOUND_CHECK("cleanup_delay", inst->cleanup_delay, >=, fr_time_delta_from_sec(1));
2894
2895
0
    if (!inst->app_io->track_create) {
2896
0
      cf_log_err(inst->app_io_conf, "Internal error: 'track_duplicates' is set, but there is no 'track create' function");
2897
0
      return -1;
2898
0
    }
2899
0
  }
2900
2901
  /*
2902
   *  Get various information after bootstrapping the
2903
   *  application IO module.
2904
   */
2905
0
  if (inst->app_io->network_get) {
2906
0
    inst->app_io->network_get(&inst->ipproto, &inst->dynamic_clients, &inst->networks, inst->app_io_instance);
2907
0
  }
2908
2909
0
  if ((inst->ipproto == IPPROTO_TCP) && !inst->app_io->connection_set) {
2910
0
    cf_log_err(inst->app_io_conf, "Missing 'connection set' API for proto_%s", inst->app_io->common.name);
2911
0
    return -1;
2912
0
  }
2913
2914
  /*
2915
   *  Ensure that the dynamic client sections exist
2916
   */
2917
0
  if (inst->dynamic_clients) {
2918
0
    CONF_SECTION *server = cf_item_to_section(cf_parent(conf));
2919
2920
0
    if (!cf_section_find(server, "new", "client")) {
2921
0
      cf_log_err(conf, "Cannot use 'dynamic_clients = yes' as the virtual server has no 'new client { ... }' section defined.");
2922
0
      return -1;
2923
0
    }
2924
2925
0
    if (!cf_section_find(server, "add", "client")) {
2926
0
      cf_log_warn(conf, "No 'add client { ... }' section was defined.");
2927
0
    }
2928
2929
0
    if (!cf_section_find(server, "deny", "client")) {
2930
0
      cf_log_warn(conf, "No 'deny client { ... }' section was defined.");
2931
0
    }
2932
0
  }
2933
2934
  /*
2935
   *  Create a list of client modules.
2936
   *
2937
   *  FIXME - Probably only want to do this for connected sockets?
2938
   *
2939
   *  FIXME - We probably want write protect enabled?
2940
   */
2941
0
  inst->clients = module_list_alloc(inst, &module_list_type_thread_local, "clients", false);
2942
0
  module_list_mask_set(inst->clients, MODULE_INSTANCE_BOOTSTRAPPED);
2943
2944
0
  return 0;
2945
0
}
2946
2947
2948
static char const *mod_name(fr_listen_t *li)
2949
0
{
2950
0
  fr_io_thread_t *thread;
2951
0
  fr_io_connection_t *connection;
2952
0
  fr_listen_t *child;
2953
0
  fr_io_instance_t const *inst;
2954
2955
0
  get_inst(li, &inst, &thread, &connection, &child);
2956
2957
0
  fr_assert(child != NULL);
2958
0
  return child->app_io->get_name(child);
2959
0
}
2960
2961
/** Create a trie from arrays of allow / deny IP addresses
2962
 *
2963
 * @param ctx the talloc ctx
2964
 * @param af  the address family to allow
2965
 * @param allow the array of IPs / networks to allow.  MUST be talloc'd
2966
 * @param deny  the array of IPs / networks to deny.  MAY be NULL, MUST be talloc'd
2967
 * @return
2968
 *  - fr_trie_t on success
2969
 *  - NULL on error
2970
 */
2971
fr_trie_t *fr_master_io_network(TALLOC_CTX *ctx, int af, fr_ipaddr_t *allow, fr_ipaddr_t *deny)
2972
0
{
2973
0
  fr_trie_t *trie;
2974
0
  size_t i, num;
2975
2976
0
  MEM(trie = fr_trie_alloc(ctx, NULL, NULL));
2977
2978
0
  num = talloc_array_length(allow);
2979
0
  fr_assert(num > 0);
2980
2981
0
  for (i = 0; i < num; i++) {
2982
0
    fr_ipaddr_t *network;
2983
2984
    /*
2985
     *  Can't add v4 networks to a v6 socket, or vice versa.
2986
     */
2987
0
    if (allow[i].af != af) {
2988
0
      fr_strerror_printf("Address family in entry %zd - 'allow = %pV' "
2989
0
             "does not match 'ipaddr'", i + 1, fr_box_ipaddr(allow[i]));
2990
0
      talloc_free(trie);
2991
0
      return NULL;
2992
0
    }
2993
2994
    /*
2995
     *  Duplicates are bad.
2996
     */
2997
0
    network = fr_trie_match_by_key(trie,
2998
0
          &allow[i].addr, allow[i].prefix);
2999
0
    if (network) {
3000
0
      fr_strerror_printf("Cannot add duplicate entry 'allow = %pV'",
3001
0
             fr_box_ipaddr(allow[i]));
3002
0
      talloc_free(trie);
3003
0
      return NULL;
3004
0
    }
3005
3006
    /*
3007
     *  Look for overlapping entries.
3008
     *  i.e. the networks MUST be disjoint.
3009
     *
3010
     *  Note that this catches 192.168.1/24
3011
     *  followed by 192.168/16, but NOT the
3012
     *  other way around.  The best fix is
3013
     *  likely to add a flag to
3014
     *  fr_trie_alloc() saying "we can only
3015
     *  have terminal fr_trie_user_t nodes"
3016
     */
3017
0
    network = fr_trie_lookup_by_key(trie,
3018
0
           &allow[i].addr, allow[i].prefix);
3019
0
    if (network && (network->prefix <= allow[i].prefix)) {
3020
0
      fr_strerror_printf("Cannot add overlapping entry 'allow = %pV'", fr_box_ipaddr(allow[i]));
3021
0
      fr_strerror_const("Entry is completely enclosed inside of a previously defined network.");
3022
0
      talloc_free(trie);
3023
0
      return NULL;
3024
0
    }
3025
3026
    /*
3027
     *  Insert the network into the trie.
3028
     *  Lookups will return the fr_ipaddr_t of
3029
     *  the network.
3030
     */
3031
0
    if (fr_trie_insert_by_key(trie,
3032
0
           &allow[i].addr, allow[i].prefix,
3033
0
           &allow[i]) < 0) {
3034
0
      fr_strerror_printf("Failed adding 'allow = %pV' to tracking table", fr_box_ipaddr(allow[i]));
3035
0
      talloc_free(trie);
3036
0
      return NULL;
3037
0
    }
3038
0
  }
3039
3040
  /*
3041
   *  And now check denied networks.
3042
   */
3043
0
  num = talloc_array_length(deny);
3044
0
  if (!num) return trie;
3045
3046
  /*
3047
   *  Since the default is to deny, you can only add
3048
   *  a "deny" inside of a previous "allow".
3049
   */
3050
0
  for (i = 0; i < num; i++) {
3051
0
    fr_ipaddr_t *network;
3052
3053
    /*
3054
     *  Can't add v4 networks to a v6 socket, or vice versa.
3055
     */
3056
0
    if (deny[i].af != af) {
3057
0
      fr_strerror_printf("Address family in entry %zd - 'deny = %pV' "
3058
0
             "does not match 'ipaddr'", i + 1, fr_box_ipaddr(deny[i]));
3059
0
      talloc_free(trie);
3060
0
      return NULL;
3061
0
    }
3062
3063
    /*
3064
     *  Duplicates are bad.
3065
     */
3066
0
    network = fr_trie_match_by_key(trie,
3067
0
          &deny[i].addr, deny[i].prefix);
3068
0
    if (network) {
3069
0
      fr_strerror_printf("Cannot add duplicate entry 'deny = %pV'", fr_box_ipaddr(deny[i]));
3070
0
      talloc_free(trie);
3071
0
      return NULL;
3072
0
    }
3073
3074
    /*
3075
     *  A "deny" can only be within a previous "allow".
3076
     */
3077
0
    network = fr_trie_lookup_by_key(trie,
3078
0
           &deny[i].addr, deny[i].prefix);
3079
0
    if (!network) {
3080
0
      fr_strerror_printf("The network in entry %zd - 'deny = %pV' is not "
3081
0
             "contained within a previous 'allow'", i + 1, fr_box_ipaddr(deny[i]));
3082
0
      talloc_free(trie);
3083
0
      return NULL;
3084
0
    }
3085
3086
    /*
3087
     *  We hack the AF in "deny" rules.  If
3088
     *  the lookup gets AF_UNSPEC, then we're
3089
     *  adding a "deny" inside of a "deny".
3090
     */
3091
0
    if (network->af != af) {
3092
0
      fr_strerror_printf("The network in entry %zd - 'deny = %pV' is overlaps "
3093
0
             "with another 'deny' rule", i + 1, fr_box_ipaddr(deny[i]));
3094
0
      talloc_free(trie);
3095
0
      return NULL;
3096
0
    }
3097
3098
    /*
3099
     *  Insert the network into the trie.
3100
     *  Lookups will return the fr_ipaddr_t of
3101
     *  the network.
3102
     */
3103
0
    if (fr_trie_insert_by_key(trie,
3104
0
           &deny[i].addr, deny[i].prefix,
3105
0
           &deny[i]) < 0) {
3106
0
      fr_strerror_printf("Failed adding 'deny = %pV' to tracking table", fr_box_ipaddr(deny[i]));
3107
0
      talloc_free(trie);
3108
0
      return NULL;
3109
0
    }
3110
3111
    /*
3112
     *  Hack it to make it a deny rule.
3113
     */
3114
0
    deny[i].af = AF_UNSPEC;
3115
0
  }
3116
3117
0
  return trie;
3118
0
}
3119
3120
3121
int fr_io_listen_free(fr_listen_t *li)
3122
0
{
3123
0
  if (!li->thread_instance) return 0;
3124
3125
0
  talloc_free(li->thread_instance);
3126
0
  return 0;
3127
0
}
3128
3129
int fr_master_io_listen(fr_io_instance_t *inst, fr_schedule_t *sc,
3130
      size_t default_message_size, size_t num_messages)
3131
0
{
3132
0
  fr_listen_t *li, *child;
3133
0
  fr_io_thread_t  *thread;
3134
3135
  /*
3136
   *  No IO paths, so we don't initialize them.
3137
   */
3138
0
  if (!inst->app_io) {
3139
0
    fr_assert(!inst->dynamic_clients);
3140
0
    return 0;
3141
0
  }
3142
3143
0
  if (!inst->app_io->common.thread_inst_size) {
3144
0
    fr_strerror_const("IO modules MUST set 'thread_inst_size' when using the master IO handler.");
3145
0
    return -1;
3146
0
  }
3147
3148
  /*
3149
   *  Build the #fr_listen_t.  This describes the complete
3150
   *  path data takes from the socket to the decoder and
3151
   *  back again.
3152
   */
3153
0
  MEM(li = talloc_zero(NULL, fr_listen_t));
3154
0
  talloc_set_destructor(li, fr_io_listen_free);
3155
3156
  /*
3157
   *  The first listener is the one for the application
3158
   *  (e.g. RADIUS).  However, we mangle the IO path to
3159
   *  point to the master IO handler.  That allows all of
3160
   *  the high-level work (dynamic client checking,
3161
   *  connected sockets, etc.) to be handled by the master
3162
   *  IO handler.
3163
   *
3164
   *  This listener is then passed to the network code,
3165
   *  which calls our trampoline functions to do the actual
3166
   *  work.
3167
   */
3168
0
  li->app = inst->app;
3169
0
  li->app_instance = inst->app_instance;
3170
0
  li->server_cs = inst->server_cs;
3171
3172
  /*
3173
   *  Set configurable parameters for message ring buffer.
3174
   */
3175
0
  li->default_message_size = default_message_size;
3176
0
  li->num_messages = num_messages;
3177
3178
  /*
3179
   *  Per-socket data lives here.
3180
   */
3181
0
  thread = talloc_zero(NULL, fr_io_thread_t);
3182
0
  thread->listen = li;
3183
0
  thread->sc = sc;
3184
3185
  /*
3186
   *  Create the trie of clients for this socket.
3187
   */
3188
0
  MEM(thread->trie = fr_trie_alloc(thread, NULL, NULL));
3189
3190
0
  if (inst->dynamic_clients) {
3191
0
    MEM(thread->alive_clients = fr_heap_alloc(thread, alive_client_cmp,
3192
0
                fr_io_client_t, alive_id, 0));
3193
0
  }
3194
3195
  /*
3196
   *  Set the listener to call our master trampoline function.
3197
   */
3198
0
  li->cs = inst->app_io_conf;
3199
0
  li->app_io = &fr_master_app_io;
3200
0
  li->thread_instance = thread;
3201
0
  li->app_io_instance = inst;
3202
0
  li->track_duplicates = inst->app_io->track_duplicates;
3203
0
  if (inst->app_io->hexdump_set) inst->app_io->hexdump_set(li, inst->app_io_instance);
3204
3205
  /*
3206
   *  The child listener points to the *actual* IO path.
3207
   *
3208
   *  We need to create a complete listener here (e.g.
3209
   *  RADIUS + RADIUS_UDP), because the underlying IO
3210
   *  functions expect to get passed a full listener.
3211
   *
3212
   *  Once the network side calls us, we will call the child
3213
   *  listener to do the actual IO.
3214
   */
3215
0
  child = thread->child = talloc_zero(li, fr_listen_t);
3216
0
  memcpy(child, li, sizeof(*child));
3217
3218
  /*
3219
   *  Reset these fields to point to the IO instance data.
3220
   */
3221
0
  child->app_io = inst->app_io;
3222
0
  child->track_duplicates = inst->app_io->track_duplicates;
3223
3224
0
  if (child->app_io->common.thread_inst_size > 0) {
3225
0
    child->thread_instance = talloc_zero_array(NULL, uint8_t,
3226
0
                 inst->app_io->common.thread_inst_size);
3227
0
    talloc_set_destructor(child, fr_io_listen_free);
3228
3229
0
    talloc_set_name(child->thread_instance, "proto_%s_thread_t",
3230
0
        inst->app_io->common.name);
3231
3232
    /*
3233
     *  This is "const", and the user can't
3234
     *  touch it.  So we just reuse the same
3235
     *  configuration everywhere.
3236
     */
3237
0
    child->app_io_instance = inst->app_io_instance;
3238
3239
0
  } else {
3240
0
    child->thread_instance = inst->app_io_instance;
3241
0
    child->app_io_instance = child->thread_instance;
3242
0
  }
3243
3244
  /*
3245
   *  Don't call connection_set() for the main socket.  It's
3246
   *  not connected.  Instead, tell the IO path to open the
3247
   *  socket for us.
3248
   */
3249
0
  if (inst->app_io->open(child) < 0) {
3250
0
    talloc_free(li);
3251
0
    return -1;
3252
0
  }
3253
3254
0
  li->fd = child->fd; /* copy this back up */
3255
3256
0
  if (!child->app_io->get_name) {
3257
0
    child->name = child->app_io->common.name;
3258
0
  } else {
3259
0
    child->name = child->app_io->get_name(child);
3260
0
  }
3261
0
  li->name = child->name;
3262
3263
  /*
3264
   *  Record which socket we opened.
3265
   */
3266
0
  if (child->app_io_addr) {
3267
0
    fr_listen_t *other;
3268
3269
0
    other = listen_find_any(thread->child);
3270
0
    if (other) {
3271
0
      cf_log_err(other->cs, "Already opened socket %s", other->name);
3272
0
      cf_log_err(li->cs, "Failed opening duplicate socket - cannot use the same configuration for two different listen sections");
3273
3274
0
      talloc_free(li);
3275
0
      return -1;
3276
0
    }
3277
3278
0
    (void) listen_record(child);
3279
0
  }
3280
3281
  /*
3282
   *  Add the socket to the scheduler, where it might end up
3283
   *  in a different thread.
3284
   */
3285
0
  if (!fr_schedule_listen_add(sc, li)) {
3286
0
    talloc_free(li);
3287
0
    return -1;
3288
0
  }
3289
3290
0
  return 0;
3291
0
}
3292
3293
/*
3294
 *  Used to create a tracking structure for fr_network_sendto_worker()
3295
 */
3296
fr_io_track_t *fr_master_io_track_alloc(fr_listen_t *li, fr_client_t *radclient, fr_ipaddr_t const *src_ipaddr, int src_port,
3297
          fr_ipaddr_t const *dst_ipaddr, int dst_port)
3298
{
3299
  fr_io_instance_t const  *inst;
3300
  fr_io_thread_t    *thread;
3301
  fr_io_connection_t  *connection;
3302
  fr_listen_t   *child;
3303
  fr_io_track_t   *track;
3304
  fr_io_client_t    *client;
3305
  fr_io_address_t   *address;
3306
  fr_listen_t   *parent = talloc_parent(li);
3307
3308
  (void) talloc_get_type_abort(parent, fr_listen_t);
3309
3310
  get_inst(parent, &inst, &thread, &connection, &child);
3311
3312
  fr_assert(child == li);
3313
3314
  if (unlikely(!thread)) return NULL;
3315
  fr_assert(thread->trie != NULL);
3316
3317
  client = fr_trie_lookup_by_key(thread->trie, &src_ipaddr->addr, src_ipaddr->prefix);
3318
  if (!client) {
3319
    MEM(client = client_alloc(thread, PR_CLIENT_STATIC, inst, thread, radclient, NULL));
3320
  }
3321
3322
  MEM(track = talloc_zero_pooled_object(client, fr_io_track_t, 1, sizeof(*track) + sizeof(*track->address) + 64));
3323
  MEM(track->address = address = talloc_zero(track, fr_io_address_t));
3324
3325
  track->li = li;
3326
  track->client = client;
3327
3328
  address->socket.inet.src_port = src_port;
3329
  address->socket.inet.dst_port = dst_port;
3330
3331
  address->socket.inet.src_ipaddr = *src_ipaddr;
3332
  address->socket.inet.dst_ipaddr = *dst_ipaddr;
3333
  address->radclient = radclient;
3334
3335
  return track;
3336
}
3337
3338
3339
fr_app_io_t fr_master_app_io = {
3340
  .common = {
3341
    .magic      = MODULE_MAGIC_INIT,
3342
    .name     = "radius_master_io",
3343
3344
    .instantiate    = mod_instantiate,
3345
  },
3346
  .default_message_size = 4096,
3347
  .track_duplicates = true,
3348
3349
  .read     = mod_read,
3350
  .write      = mod_write,
3351
  .inject     = mod_inject,
3352
3353
  .open     = mod_open,
3354
  .close      = mod_close,
3355
  .event_list_set   = mod_event_list_set,
3356
  .get_name   = mod_name,
3357
};