Skip to content

Commit

Permalink
move to new method of handling listeners
Browse files Browse the repository at this point in the history
still have to re-do raw encode/decode functions, but it's a
good start
  • Loading branch information
alandekok committed May 4, 2018
1 parent 6c5a81f commit 7a73e8d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 105 deletions.
2 changes: 1 addition & 1 deletion src/modules/proto_vmps/all.mk
Original file line number Diff line number Diff line change
@@ -1 +1 @@
SUBMAKEFILES := proto_vmps.mk proto_vmps_udp.mk proto_vmps_all.mk libfreeradius-vqp.mk
SUBMAKEFILES := proto_vmps.mk proto_vmps_udp.mk proto_vmps_all.mk proto_vmps_dynamic_client.mk libfreeradius-vqp.mk
96 changes: 38 additions & 58 deletions src/modules/proto_vmps/proto_vmps.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,33 +66,22 @@ static CONF_PARSER const proto_vmps_config[] = {
};


#if 0
/*
* Allow configurable priorities for each listener.
*/
static uint32_t priorities[FR_MAX_PACKET_CODE] = {
[FR_CODE_ACCESS_REQUEST] = PRIORITY_HIGH,
[FR_CODE_ACCOUNTING_REQUEST] = PRIORITY_LOW,
[FR_CODE_COA_REQUEST] = PRIORITY_NORMAL,
[FR_CODE_DISCONNECT_REQUEST] = PRIORITY_NORMAL,
[FR_CODE_STATUS_SERVER] = PRIORITY_NOW,
static uint32_t priorities[FR_MAX_VMPS_CODE] = {
[FR_VMPS_PACKET_TYPE_VALUE_VMPS_JOIN_REQUEST] = PRIORITY_LOW,
[FR_VMPS_PACKET_TYPE_VALUE_VMPS_RECONFIRM_REQUEST] = PRIORITY_LOW,
};

static const CONF_PARSER priority_config[] = {
{ FR_CONF_OFFSET("Access-Request", FR_TYPE_UINT32, proto_vmps_t, priorities[FR_CODE_ACCESS_REQUEST]),
.dflt = STRINGIFY(PRIORITY_HIGH) },
{ FR_CONF_OFFSET("Accounting-Request", FR_TYPE_UINT32, proto_vmps_t, priorities[FR_CODE_ACCOUNTING_REQUEST]),
{ FR_CONF_OFFSET("VMPS-Join-Request", FR_TYPE_UINT32, proto_vmps_t, priorities[FR_VMPS_PACKET_TYPE_VALUE_VMPS_JOIN_REQUEST]),
.dflt = STRINGIFY(PRIORITY_LOW) },
{ FR_CONF_OFFSET("VMPS-Reconfirm-Request", FR_TYPE_UINT32, proto_vmps_t, priorities[FR_VMPS_PACKET_TYPE_VALUE_VMPS_RECONFIRM_REQUEST]),
.dflt = STRINGIFY(PRIORITY_LOW) },
{ FR_CONF_OFFSET("CoA-Request", FR_TYPE_UINT32, proto_vmps_t, priorities[FR_CODE_COA_REQUEST]),
.dflt = STRINGIFY(PRIORITY_NORMAL) },
{ FR_CONF_OFFSET("Disconnect-Request", FR_TYPE_UINT32, proto_vmps_t, priorities[FR_CODE_DISCONNECT_REQUEST]),
.dflt = STRINGIFY(PRIORITY_NORMAL) },
{ FR_CONF_OFFSET("Status-Server", FR_TYPE_UINT32, proto_vmps_t, priorities[FR_CODE_STATUS_SERVER]),
.dflt = STRINGIFY(PRIORITY_NOW) },

CONF_PARSER_TERMINATOR
};
#endif

/** Wrapper around dl_instance which translates the packet-type into a submodule name
*
Expand Down Expand Up @@ -137,7 +126,11 @@ static int type_parse(TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, UNUSED CONF_PAR

code = type_enum->value->vb_uint32;

// @todo - check code VMPS-Request???
if ((code != FR_VMPS_PACKET_TYPE_VALUE_VMPS_JOIN_REQUEST) &&
(code != FR_VMPS_PACKET_TYPE_VALUE_VMPS_RECONFIRM_REQUEST)) {
cf_log_err(ci, "Unsupported 'type = %s'", type_str);
return -1;
}

/*
* Setting 'type = foo' means you MUST have at least a
Expand All @@ -158,13 +151,14 @@ static int type_parse(TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, UNUSED CONF_PAR
*/
inst = talloc_get_type_abort(parent_inst->data, proto_vmps_t);

// @todo - set allowed for the 2 types we support
// inst->code_allowed[code] = true;
inst->code_allowed[code] = true;

/*
* Parent dl_instance_t added in virtual_servers.c (listen_parse)
*
* We allow "type = foo", but we just load proto_vmps_all.a
*/
return dl_instance(ctx, out, listen_cs, parent_inst, type_enum->alias, DL_TYPE_SUBMODULE);
return dl_instance(ctx, out, listen_cs, parent_inst, "all", DL_TYPE_SUBMODULE);
}

/** Wrapper around dl_instance
Expand Down Expand Up @@ -236,6 +230,7 @@ static int mod_decode(void const *instance, REQUEST *request, uint8_t *const dat
request->packet->data = talloc_memdup(request->packet, data, data_len);
request->packet->data_len = data_len;

#if 0
/*
* Note that we don't set a limit on max_attributes here.
* That MUST be set and checked in the underlying
Expand All @@ -245,6 +240,7 @@ static int mod_decode(void const *instance, REQUEST *request, uint8_t *const dat
RPEDEBUG("Failed decoding packet");
return -1;
}
#endif

/*
* Set the rest of the fields.
Expand Down Expand Up @@ -376,7 +372,6 @@ static ssize_t mod_encode(void const *instance, REQUEST *request, uint8_t *buffe
static void mod_process_set(void const *instance, REQUEST *request)
{
proto_vmps_t const *inst = talloc_get_type_abort_const(instance, proto_vmps_t);
fr_io_process_t process;
fr_io_track_t *track = request->async->packet_ctx;

rad_assert(request->packet->code != 0);
Expand All @@ -397,28 +392,18 @@ static void mod_process_set(void const *instance, REQUEST *request)
return;
}

// process = inst->process_by_code[request->packet->code];
// @todo - set this!
process = NULL;
if (!process) {
REDEBUG("proto_vmps - No module available to handle packet code %i", request->packet->code);
return;
}

request->async->process = process;
request->async->process = inst->process;
}


static int mod_priority(UNUSED void const *instance, UNUSED uint8_t const *buffer, UNUSED size_t buflen)
static int mod_priority(void const *instance, UNUSED uint8_t const *buffer, UNUSED size_t buflen)
{
// proto_vmps_t const *inst = talloc_get_type_abort_const(instance, proto_vmps_t);
proto_vmps_t const *inst = talloc_get_type_abort_const(instance, proto_vmps_t);

/*
* Disallowed packet
*/
// if (!inst->priorities[buffer[0]]) return 0;

// if (!inst->process_by_code[buffer[0]]) return -1;
if (!inst->priorities[buffer[1]]) return 0;

/*
* @todo - if we cared, we could also return -1 for "this
Expand All @@ -430,9 +415,7 @@ static int mod_priority(UNUSED void const *instance, UNUSED uint8_t const *buffe
/*
* Return the configured priority.
*/
// return inst->priorities[buffer[0]];

return PRIORITY_NORMAL;
return inst->priorities[buffer[1]];
}

/** Open listen sockets/connect to external event source
Expand Down Expand Up @@ -543,6 +526,7 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf)
fr_dict_enum_t const *dv;
char const *name, *packet_type;
CONF_SECTION *subcs;
rlm_components_t component = MOD_AUTHORIZE;

if (!cf_item_is_section(ci)) continue;

Expand Down Expand Up @@ -575,31 +559,25 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf)
*/
packet_type = cf_section_name2(subcs);
dv = fr_dict_enum_by_alias(da, packet_type);


// @todo skip anything other than the 2 request packets
if (!dv) {
if (!dv ||
((dv->value->vb_uint32 != FR_VMPS_PACKET_TYPE_VALUE_VMPS_JOIN_REQUEST) &&
(dv->value->vb_uint32 != FR_VMPS_PACKET_TYPE_VALUE_VMPS_JOIN_RESPONSE) &&
(dv->value->vb_uint32 != FR_VMPS_PACKET_TYPE_VALUE_VMPS_RECONFIRM_REQUEST) &&
(dv->value->vb_uint32 != FR_VMPS_PACKET_TYPE_VALUE_VMPS_RECONFIRM_RESPONSE) &&
(dv->value->vb_uint32 != FR_VMPS_PACKET_TYPE_VALUE_DO_NOT_RESPOND))) {
cf_log_err(subcs, "Invalid VMPS packet type in '%s %s {...}'",
name, packet_type);
return -1;
}

/*
* Skip 'recv foo' when it's a request packet
* that isn't used by this instance.
*/
if ((strcmp(name, "recv") == 0) && 0) {
cf_log_warn(subcs, "Skipping %s %s { ...}", name, packet_type);
continue;
}

/*
* Try to compile it, and fail if it doesn't work.
*/
cf_log_debug(subcs, "compiling - %s %s {...}", name, packet_type);

// @todo - set component here? Maybe all post-auth?
if (unlang_compile(subcs, -1) < 0) {
if (strcmp(name, "send") == 0) component = MOD_POST_AUTH;

if (unlang_compile(subcs, component) < 0) {
cf_log_err(subcs, "Failed compiling '%s %s { ... }' section", name, packet_type);
return -1;
}
Expand Down Expand Up @@ -636,9 +614,10 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf)
if (!fr_cond_assert(enumv)) return -1;

code = enumv->value->vb_uint32;
// inst->process_by_code[code] = app_process->process; /* Store the process function */

// rad_assert(inst->code_allowed[code] == true);
inst->process = app_process->process; /* Store the process function */

rad_assert(inst->code_allowed[code] == true);
i++;
}

Expand Down Expand Up @@ -775,10 +754,11 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf)
*/
subcs = cf_section_find(conf, "priority", NULL);
if (subcs) {
// if (cf_section_rules_push(subcs, priority_config) < 0) return -1;
if (cf_section_rules_push(subcs, priority_config) < 0) return -1;
if (cf_section_parse(NULL, NULL, subcs) < 0) return -1;
} else {
// @todo - set the priorities for the packets we care about
rad_assert(sizeof(inst->priorities) == sizeof(priorities));
memcpy(&inst->priorities, &priorities, sizeof(priorities));
}

/*
Expand Down
59 changes: 13 additions & 46 deletions src/modules/proto_vmps/proto_vmps.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,60 +21,27 @@
* @file proto_vmps.h
* @brief Structures for the VMPS protocol
*
* @copyright 2017 Alan DeKok <aland@freeradius.org>
* @copyright 2018 Alan DeKok <aland@freeradius.org>
*/
#include <freeradius-devel/io/master.h>
#include <freeradius-devel/vqp.h>
#include "vqp.h"

/** Return the VMPS client associated with the request
*
* @param[in] instance #fr_app_io_t instance.
* @param[in] packet_ctx as allocated/returned by the #fr_app_io_t.
*/
typedef RADCLIENT *(*proto_vmps_client_get_t)(void const *instance, void const *packet_ctx);

/** Get src/dst address from the #fr_app_io_t module
*
* @param[out] sockaddr structure to populate. If UNIX socket, path will be a shallow copy.
* @param[in] instance #fr_app_io_t instance.
* @param[in] packet_ctx as allocated/returned by the #fr_app_io_t.
* @return
* - 0 on success.
* - -1 on failure.
*/
typedef int (*proto_vmps_addr_get_t)(fr_socket_addr_t *sockaddr,
void const *instance, void const *packet_ctx);

/** Semi-private functions exported by proto_vmps #fr_app_io_t modules
*
* Should only be used by the proto_vmps module, and submodules.
*/
typedef struct {
proto_vmps_addr_get_t src; //!< Retrieve the src address of the packet.
proto_vmps_addr_get_t dst; //!< Retrieve the dst address of the packet.
} proto_vmps_app_io_t;

/** An instance of a proto_vmps listen section
*
*/
typedef struct {
CONF_SECTION *server_cs; //!< server CS for this listener

dl_instance_t *io_submodule; //!< As provided by the transport_parse
///< callback. Broken out into the
///< app_io_* fields below for convenience.

fr_app_io_t const *app_io; //!< Easy access to the app_io handle.
void *app_io_instance; //!< Easy access to the app_io instance.
CONF_SECTION *app_io_conf; //!< Easy access to the app_io's config section.
proto_vmps_app_io_t *app_io_private; //!< Internal interface for proto_vmps.
typedef struct proto_vmps_t {
fr_io_instance_t io; //!< wrapper for IO abstraction

dl_instance_t **process_submodule; //!< Instance of the various types
dl_instance_t **type_submodule; //!< Instance of the various types
dl_instance_t *dynamic_submodule; //!< proto_vmps_dynamic_client
//!< only one instance per type allowed.
fr_io_process_t process; //!< process function

fr_io_process_t process; //!< process entry point
uint32_t max_packet_size; //!< for message ring buffer.
uint32_t num_messages; //!< for message ring buffer.

uint32_t default_message_size; //!< for message ring buffer
uint32_t num_messages; //!< for message ring buffer
bool code_allowed[FR_MAX_VMPS_CODE]; //!< Allowed packet codes.

fr_listen_t const *listen; //!< The listener structure which describes
///< the I/O path.
uint32_t priorities[FR_MAX_VMPS_CODE]; //!< priorities for individual packets
} proto_vmps_t;

0 comments on commit 7a73e8d

Please sign in to comment.