int common_socket_print(rad_listen_t const *this, char *buffer, size_t bufsize);
void common_packet_debug(REQUEST *request, RADIUS_PACKET *packet, bool received);
+
+typedef int (*fr_app_bootstrap_t)(CONF_SECTION *);
+
+/*
+ * src/lib/io/transport.h
+ */
+typedef struct fr_transport_t fr_transport_t;
+
+typedef struct fr_app_io_t {
+ int fd;
+ void *ctx;
+ fr_transport_t *transport;
+} fr_app_io_t;
+
+typedef fr_app_io_t *(*fr_app_compile_t)(CONF_SECTION *);
+
+/*
+ * Functions for new virtual servers and listeners
+ */
+typedef struct fr_app_t {
+ RAD_MODULE_COMMON; //!< Common fields to all loadable modules.
+
+ fr_app_bootstrap_t bootstrap;
+ fr_app_compile_t compile;
+} fr_app_t;
+
#ifdef __cplusplus
}
#endif
#include <freeradius-devel/modpriv.h>
#include <freeradius-devel/interpreter.h>
#include <freeradius-devel/parser.h>
+#include <freeradius-devel/protocol.h>
static int default_component_results[MOD_COUNT] = {
RLM_MODULE_REJECT, /* AUTH */
cs = cf_subsection_find_next(config, cs, "server")) {
CONF_ITEM *ci;
CONF_SECTION *subcs;
+ CONF_PAIR *cp;
server_name = cf_section_name2(cs);
if (!server_name) {
return -1;
}
+ /*
+ * New-style virtual servers are special.
+ */
+ cp = cf_pair_find(cs, "namespace");
+ if (cp) {
+ char const *value;
+ dl_t const *module;
+ fr_app_t const *app;
+
+ value = cf_pair_value(cp);
+ if (!value) {
+ cf_log_err_cs(cs, "Cannot have empty namespace");
+ return -1;
+ }
+
+ if (strcmp(value, "radius") != 0) {
+ cf_log_err_cs(cs, "Unknown namespace '%s'", value);
+ return -1;
+ }
+
+ module = dl_module(cs, NULL, value, DL_TYPE_PROTO);
+ if (!module) {
+ cf_log_err_cs(cs, "Failed to find library for 'namespace = %s'", value);
+ return -1;
+ }
+
+ app = (fr_app_t const *) module->common;
+
+ if (app->bootstrap && (app->bootstrap(cs) < 0)) {
+ cf_log_err_cs(cs, "Failed to bootstrap library for 'namespace = %s'", value);
+ return -1;
+ }
+
+ cf_data_add(cs, module, "app", false);
+ continue;
+ }
+
for (ci = cf_item_find_next(cs, NULL);
ci != NULL;
ci = cf_item_find_next(cs, ci)) {
char const *name1;
if (cf_item_is_pair(ci)) {
- CONF_PAIR *cp;
-
- cp = cf_item_to_pair(ci);
- name1 = cf_pair_attr(cp);
- if (strcmp(name1, "namespace") != 0) {
- cf_log_err(ci, "Cannot set variables inside of a virtual server.");
- return -1;
- }
-
- if (!cf_pair_value(cp)) {
- cf_log_err(ci, "'namespace' cannot be empty");
- return -1;
- }
+ cf_log_err(ci, "Cannot set variables inside of a virtual server.");
+ return -1;
}
if (!cf_item_is_section(ci)) continue;
name1 = cf_section_name1(subcs);
if (strcmp(name1, "listen") == 0) {
- if (cf_pair_find(cs, "namespace") != NULL) continue;
-
if (listen_bootstrap(cs, subcs, server_name) < 0) return -1;
continue;
}
for (cs = cf_subsection_find_next(config, NULL, "server");
cs != NULL;
cs = cf_subsection_find_next(config, cs, "server")) {
+ /*
+ * Skip new-style virtual servers.
+ */
+ if (cf_pair_find(cs, "namespace")) {
+ dl_t const *module;
+ fr_app_t const *app;
+ fr_app_io_t *io;
+
+ module = cf_data_find(cs, dl_t, "app");
+ if (!module) continue;
+
+ app = (fr_app_t const *) module->common;
+
+ if (app->compile) {
+ io = app->compile(cs);
+ if (!io) continue;
+
+ DEBUG("Loaded Protocol %s", module->name);
+ }
+
+ continue;
+ }
+
if (virtual_servers_compile(cs) < 0) {
return -1;
}
-SUBMAKEFILES := proto_radius_acct.mk proto_radius_auth.mk proto_radius_coa.mk proto_radius_status.mk
+SUBMAKEFILES := proto_radius.mk proto_radius_acct.mk proto_radius_auth.mk proto_radius_coa.mk proto_radius_status.mk
--- /dev/null
+/*
+ * proto_radius.c RADIUS master protocol handler
+ *
+ * Version: $Id$
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * Copyright 2016 The FreeRADIUS server project
+ * Copyright 2016 Alan DeKok <aland@deployingradius.com>
+ */
+
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/protocol.h>
+#include <freeradius-devel/udp.h>
+#include <freeradius-devel/radius/radius.h>
+#include <freeradius-devel/io/transport.h>
+#include <freeradius-devel/rad_assert.h>
+
+/** Load the RADIUS protocol
+ *
+ * Typically loads dictionaries, etc.
+ */
+static int proto_radius_load(void)
+{
+ /*
+ * @todo - load the RADIUS dictionaries
+ */
+
+ return 0;
+}
+
+/** Bootstrap the RADIUS protocol in a particular virtual server.
+ *
+ */
+static int proto_radius_bootstrap(UNUSED CONF_SECTION *cs)
+{
+ return 0;
+}
+
+
+/** Compile the RADIUS protocol in a particular virtual server.
+ *
+ */
+static fr_app_io_t *proto_radius_compile(UNUSED CONF_SECTION *cs)
+{
+
+ return NULL;
+}
+
+extern fr_app_t proto_radius;
+fr_app_t proto_radius = {
+ .magic = RLM_MODULE_INIT,
+ .name = "radius",
+ .load = proto_radius_load,
+ .bootstrap = proto_radius_bootstrap,
+ .compile = proto_radius_compile,
+};
--- /dev/null
+TARGETNAME := proto_radius
+
+ifneq "$(TARGETNAME)" ""
+TARGET := $(TARGETNAME).a
+endif
+
+SOURCES := proto_radius.c
+
+TGT_PREREQS := libfreeradius-util.a libfreeradius-radius.a