]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
separate client and server BIO config
authorAlan T. DeKok <aland@freeradius.org>
Thu, 5 Dec 2024 14:59:52 +0000 (09:59 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 5 Dec 2024 17:15:55 +0000 (12:15 -0500)
src/lib/bio/fd.h
src/lib/bio/fd_config.c
src/modules/rlm_radius2/rlm_radius.c

index a5c2de1e56675e65d7f1be9bbb43e36cd51511e5..60a4425d9c99652e9886388dbabd06ab0af587bd 100644 (file)
@@ -113,7 +113,8 @@ typedef struct {
        bool            send_buff_is_set;       //!< Whether we were provided with a send_buf
 } fr_bio_fd_config_t;
 
-extern const conf_parser_t fr_bio_fd_config[];
+extern const conf_parser_t fr_bio_fd_client_config[];
+extern const conf_parser_t fr_bio_fd_server_config[];
 
 /** Run-time status of the socket.
  *
index 99d440fdd3d54cc528af49d37ee28d11f1d96830..c7e7e15959aebf0b95881822c8a5501025192bb0 100644 (file)
 
 #include <freeradius-devel/bio/fd_priv.h>
 
-#if 0
-static fr_table_num_sorted_t socket_type_names[] = {
-       { L("udp"),             SOCK_DGRAM                      },
-       { L("datagram"),        SOCK_DGRAM                      },
-       { L("tcp"),             SOCK_STREAM                     },
-       { L("stream"),          SOCK_STREAM                     },
-};
-static size_t socket_type_names_len = NUM_ELEMENTS(socket_type_names);
-
-static int socket_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
-{
-       int type;
-       char const *name = cf_pair_value(cf_item_to_pair(ci));
-
-       type = fr_table_value_by_str(socket_type_names, name, -1);
-       if (type < 0) {
-               cf_log_err(ci, "Invalid protocol name \"%s\"", name);
-               return -1;
-       }
-
-       *(int *) out = type;
-
-       return 0;
-}
-#endif
-
 #define FR_READ  (1)
 #define FR_WRITE (2)
 
@@ -85,14 +59,7 @@ static int mode_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CO
        return 0;
 }
 
-static const conf_parser_t peercred_config[] = {
-       { FR_CONF_OFFSET("uid", fr_bio_fd_config_t, uid), .func = cf_parse_uid },
-       { FR_CONF_OFFSET("gid", fr_bio_fd_config_t, gid), .func = cf_parse_gid },
-
-       CONF_PARSER_TERMINATOR
-};
-
-static const conf_parser_t udp_config[] = {
+static const conf_parser_t client_udp_config[] = {
        { FR_CONF_OFFSET_TYPE_FLAGS("ipaddr", FR_TYPE_COMBO_IP_ADDR, 0, fr_bio_fd_config_t, dst_ipaddr), },
        { FR_CONF_OFFSET_TYPE_FLAGS("ipv4addr", FR_TYPE_IPV4_ADDR, 0, fr_bio_fd_config_t, dst_ipaddr) },
        { FR_CONF_OFFSET_TYPE_FLAGS("ipv6addr", FR_TYPE_IPV6_ADDR, 0, fr_bio_fd_config_t, dst_ipaddr) },
@@ -113,7 +80,7 @@ static const conf_parser_t udp_config[] = {
        CONF_PARSER_TERMINATOR
 };
 
-static const conf_parser_t tcp_config[] = {
+static const conf_parser_t client_tcp_config[] = {
        { FR_CONF_OFFSET_TYPE_FLAGS("ipaddr", FR_TYPE_COMBO_IP_ADDR, 0, fr_bio_fd_config_t, dst_ipaddr), },
        { FR_CONF_OFFSET_TYPE_FLAGS("ipv4addr", FR_TYPE_IPV4_ADDR, 0, fr_bio_fd_config_t, dst_ipaddr) },
        { FR_CONF_OFFSET_TYPE_FLAGS("ipv6addr", FR_TYPE_IPV6_ADDR, 0, fr_bio_fd_config_t, dst_ipaddr) },
@@ -136,42 +103,169 @@ static const conf_parser_t tcp_config[] = {
        CONF_PARSER_TERMINATOR
 };
 
-static const conf_parser_t unix_config[] = {
+static const conf_parser_t client_file_config[] = {
        { FR_CONF_OFFSET_FLAGS("filename", CONF_FLAG_REQUIRED, fr_bio_fd_config_t, filename), },
 
-       { FR_CONF_OFFSET("permissions", fr_bio_fd_config_t, perm), .dflt = "0600", .func = cf_parse_permissions },
+       CONF_PARSER_TERMINATOR
+};
 
-       { FR_CONF_OFFSET("mode", fr_bio_fd_config_t, flags), .dflt = "read-only", .func = mode_parse },
+static const conf_parser_t client_unix_config[] = {
+       { FR_CONF_OFFSET_FLAGS("filename", CONF_FLAG_REQUIRED, fr_bio_fd_config_t, filename), },
+
+       CONF_PARSER_TERMINATOR
+};
+
+static fr_table_ptr_sorted_t client_transport_names[] = {
+       { L("file"),            client_file_config },
+       { L("tcp"),             client_tcp_config },
+       { L("udp"),             client_udp_config },
+       { L("unix"),            client_unix_config },
+};
+static size_t client_transport_names_len = NUM_ELEMENTS(client_transport_names);
+
+/** Parse "transport" and then set the subconfig
+ *
+ */
+static int client_transport_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
+{
+       int socket_type = SOCK_STREAM;
+       conf_parser_t const *rules;
+       char const *name = cf_pair_value(cf_item_to_pair(ci));
+       fr_bio_fd_config_t *fd_config = parent;
+       CONF_SECTION *subcs;
+
+       rules = fr_table_value_by_str(client_transport_names, name, NULL);
+       if (!rules) {
+               cf_log_err(ci, "Invalid transport name \"%s\"", name);
+               return -1;
+       }
+
+       /*
+        *      Find the relevant subsection.
+        */
+       subcs = cf_section_find(cf_item_to_section(cf_parent(ci)), name, NULL);
+       if (!subcs) {
+               cf_log_perr(ci, "Failed finding transport configuration section %s { ... }", name);
+               return -1;
+       }
+
+       /*
+        *      Note that these offsets will get interpreted as being
+        *      offsets from base of the subsection.  i.e. the parent
+        *      section and the subsection have to be parsed with the
+        *      same base pointer.
+        */
+       if (cf_section_rules_push(subcs, rules) < 0) {
+               cf_log_perr(ci, "Failed updating parse rules");
+               return -1;
+       }
+
+       if (strcmp(name, "udp") == 0) socket_type = SOCK_DGRAM;
+
+       fd_config->socket_type = socket_type;
+       *(char const **) out = name;
+
+       return 0;
+}
+
+/*
+ *     Client uses src_ipaddr for our address, and ipaddr for their address.
+ */
+const conf_parser_t fr_bio_fd_client_config[] = {
+       { FR_CONF_OFFSET("transport", fr_bio_fd_config_t, transport), .func = client_transport_parse },
+
+       { FR_CONF_OFFSET("async", fr_bio_fd_config_t, async), .dflt = "true" },
+
+       CONF_PARSER_TERMINATOR
+};
+
+/*
+ *     Server configuration
+ *
+ *     "ipaddr" is src_ipaddr
+ *     There's no "dst_ipaddr" or "src_ipaddr" in the config.
+ *
+ *     Files have permissions which can be set.
+ */
+
+static const conf_parser_t server_udp_config[] = {
+       { FR_CONF_OFFSET_TYPE_FLAGS("ipaddr", FR_TYPE_COMBO_IP_ADDR, 0, fr_bio_fd_config_t, src_ipaddr), },
+       { FR_CONF_OFFSET_TYPE_FLAGS("ipv4addr", FR_TYPE_IPV4_ADDR, 0, fr_bio_fd_config_t, src_ipaddr) },
+       { FR_CONF_OFFSET_TYPE_FLAGS("ipv6addr", FR_TYPE_IPV6_ADDR, 0, fr_bio_fd_config_t, src_ipaddr) },
+
+       { FR_CONF_OFFSET("port", fr_bio_fd_config_t, src_port) },
+
+       { FR_CONF_OFFSET("interface", fr_bio_fd_config_t, interface) },
+
+       { FR_CONF_OFFSET_IS_SET("recv_buff", FR_TYPE_UINT32, 0, fr_bio_fd_config_t, recv_buff) },
+       { FR_CONF_OFFSET_IS_SET("send_buff", FR_TYPE_UINT32, 0, fr_bio_fd_config_t, send_buff) },
+
+       CONF_PARSER_TERMINATOR
+};
+
+static const conf_parser_t server_tcp_config[] = {
+       { FR_CONF_OFFSET_TYPE_FLAGS("ipaddr", FR_TYPE_COMBO_IP_ADDR, 0, fr_bio_fd_config_t, src_ipaddr), },
+       { FR_CONF_OFFSET_TYPE_FLAGS("ipv4addr", FR_TYPE_IPV4_ADDR, 0, fr_bio_fd_config_t, src_ipaddr) },
+       { FR_CONF_OFFSET_TYPE_FLAGS("ipv6addr", FR_TYPE_IPV6_ADDR, 0, fr_bio_fd_config_t, src_ipaddr) },
+
+       { FR_CONF_OFFSET("port", fr_bio_fd_config_t, src_port) },
+
+       { FR_CONF_OFFSET("interface", fr_bio_fd_config_t, interface) },
+
+       { FR_CONF_OFFSET_IS_SET("recv_buff", FR_TYPE_UINT32, 0, fr_bio_fd_config_t, recv_buff) },
+       { FR_CONF_OFFSET_IS_SET("send_buff", FR_TYPE_UINT32, 0, fr_bio_fd_config_t, send_buff) },
+
+       { FR_CONF_OFFSET("delay_tcp_writes", fr_bio_fd_config_t, tcp_delay) },
+
+       CONF_PARSER_TERMINATOR
+};
+
+static const conf_parser_t server_file_config[] = {
+       { FR_CONF_OFFSET_FLAGS("filename", CONF_FLAG_REQUIRED, fr_bio_fd_config_t, filename), },
+
+       { FR_CONF_OFFSET("permissions", fr_bio_fd_config_t, perm), .dflt = "0600", .func = cf_parse_permissions },
 
        { FR_CONF_OFFSET("mkdir", fr_bio_fd_config_t, mkdir) },
 
-       { FR_CONF_POINTER("peercred", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) peercred_config },
+       CONF_PARSER_TERMINATOR
+};
+
+static const conf_parser_t server_peercred_config[] = {
+       { FR_CONF_OFFSET("uid", fr_bio_fd_config_t, uid), .func = cf_parse_uid },
+       { FR_CONF_OFFSET("gid", fr_bio_fd_config_t, gid), .func = cf_parse_gid },
 
        CONF_PARSER_TERMINATOR
 };
 
-static const conf_parser_t file_config[] = {
+static const conf_parser_t server_unix_config[] = {
        { FR_CONF_OFFSET_FLAGS("filename", CONF_FLAG_REQUIRED, fr_bio_fd_config_t, filename), },
 
        { FR_CONF_OFFSET("permissions", fr_bio_fd_config_t, perm), .dflt = "0600", .func = cf_parse_permissions },
 
+       { FR_CONF_OFFSET("mode", fr_bio_fd_config_t, flags), .dflt = "read-only", .func = mode_parse },
+
        { FR_CONF_OFFSET("mkdir", fr_bio_fd_config_t, mkdir) },
 
+       { FR_CONF_POINTER("peercred", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) server_peercred_config },
+
        CONF_PARSER_TERMINATOR
 };
 
-static fr_table_ptr_sorted_t transport_names[] = {
-       { L("file"),            file_config },
-       { L("tcp"),             tcp_config },
-       { L("udp"),             udp_config },
-       { L("unix"),            unix_config },
+/*
+ *     @todo - move this to client/server config in the same struct?
+ */
+static fr_table_ptr_sorted_t server_transport_names[] = {
+       { L("file"),            server_file_config },
+       { L("tcp"),             server_tcp_config },
+       { L("udp"),             server_udp_config },
+       { L("unix"),            server_unix_config },
 };
-static size_t transport_names_len = NUM_ELEMENTS(transport_names);
+static size_t server_transport_names_len = NUM_ELEMENTS(server_transport_names);
 
 /** Parse "transport" and then set the subconfig
  *
  */
-static int transport_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
+static int server_transport_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
 {
        int socket_type = SOCK_STREAM;
        conf_parser_t const *rules;
@@ -179,7 +273,7 @@ static int transport_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, CONF
        fr_bio_fd_config_t *fd_config = parent;
        CONF_SECTION *subcs;
 
-       rules = fr_table_value_by_str(transport_names, name, NULL);
+       rules = fr_table_value_by_str(server_transport_names, name, NULL);
        if (!rules) {
                cf_log_err(ci, "Invalid transport name \"%s\"", name);
                return -1;
@@ -213,8 +307,11 @@ static int transport_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, CONF
        return 0;
 }
 
-const conf_parser_t fr_bio_fd_config[] = {
-       { FR_CONF_OFFSET("transport", fr_bio_fd_config_t, transport), .func = transport_parse },
+/*
+ *     Server uses ipaddr for our address, and doesn't use src_ipaddr.
+ */
+const conf_parser_t fr_bio_fd_server_config[] = {
+       { FR_CONF_OFFSET("transport", fr_bio_fd_config_t, transport), .func = server_transport_parse },
 
        { FR_CONF_OFFSET("async", fr_bio_fd_config_t, async), .dflt = "true" },
 
index dd9a0f62d60521898d44323ade9cd4210eeea5d9..4c042a714213ca8b1eb64e28efc9c46d26a14cfd 100644 (file)
@@ -104,7 +104,7 @@ static conf_parser_t const module_config[] = {
         *      transport, and push the transport-specific rules to
         *      the submodule CONF_SECTION.
         */
-       { FR_CONF_OFFSET_REF(rlm_radius_t, fd_config, fr_bio_fd_config) },
+       { FR_CONF_OFFSET_REF(rlm_radius_t, fd_config, fr_bio_fd_client_config) },
 
        { FR_CONF_OFFSET_TYPE_FLAGS("submodule", FR_TYPE_VOID, 0, rlm_radius_t, io_submodule),
          .func = module_rlm_submodule_parse },