#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)
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) },
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) },
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;
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;
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" },