fr_radius_client_fd_bio_t *fr_radius_client_fd_bio_alloc(TALLOC_CTX *ctx, size_t read_size, fr_radius_client_config_t *cfg, fr_bio_fd_config_t const *fd_cfg)
{
+ int i;
fr_radius_client_fd_bio_t *my;
fr_bio_t *fd, *mem;
my = talloc_zero(ctx, fr_radius_client_fd_bio_t);
if (!my) return NULL;
+ /*
+ * Allocate tracking for all of the packets.
+ */
+ for (i = 1; i < FR_RADIUS_CODE_MAX; i++) {
+ if (!cfg->allowed[i]) continue;
+
+ my->codes[i] = fr_radius_id_alloc(my);
+ if (!my->codes[i]) goto fail;
+ }
+
my->fd = fd = fr_bio_fd_alloc(my, NULL, fd_cfg, 0);
if (!fd) {
fail:
}
my->fd = fd;
- my->mem = mem = fr_bio_mem_alloc(ctx, read_size, 2 * 4096, fd);
+ my->mem = mem = fr_bio_mem_alloc(my, read_size, 2 * 4096, fd);
if (!mem) goto fail;
my->cfg = *cfg;
fr_assert(packet->code > 0);
fr_assert(packet->code < FR_RADIUS_CODE_MAX);
- /*
- * @todo - Allocate when the socket is opened, so we don't check it for every packet.
- */
- if (!my->codes[packet->code] && !(my->codes[packet->code] = fr_radius_id_alloc(my))) return -1;
+ if (!my->codes[packet->code]) {
+ fr_strerror_printf("Outgoing packet code %s is disallowed by the configuration",
+ fr_radius_packet_names[packet->code]);
+ return -1;
+ }
- if (fr_radius_code_id_pop(my->codes, packet) < 0) return -1;
+ if (fr_radius_code_id_pop(my->codes, packet) < 0) {
+ fr_strerror_const("All IDs are in use");
+ return -1;
+ }
/*
* Encode the packet.
if (slen < 0) {
fr_assert(slen != fr_bio_error(IO_WOULD_BLOCK));
-
return slen;
}
}
/*
- * @todo - if we already have a reply then don't decode
- * it. Just return "whoops, no packet".
- *
- * @todo - provide an API to expire the outgoing packet.
- *
- * @todo - provide an API to run timers for a particular packet.
- *
- * Any retries, etc. are part of packet->uctx
+ * Return the code to the free list.
*/
if (fr_radius_code_id_push(my->codes, packet) < 0) {
fr_assert(0);
typedef struct {
fr_radius_bio_verify_t verify;
- fr_retry_config_t retry[FR_RADIUS_CODE_MAX];
+ bool allowed[FR_RADIUS_CODE_MAX]; //!< allowed outgoing packet types
+
+ fr_retry_config_t retry[FR_RADIUS_CODE_MAX]; //!< default retry configuration for each packet type
} fr_radius_client_config_t;
fr_bio_packet_t *fr_radius_client_bio_alloc(TALLOC_CTX *ctx, fr_radius_client_config_t *cfg, fr_bio_fd_config_t const *fd_cfg) CC_HINT(nonnull);