char const *name2 = NULL;
CONF_SECTION *subcs;
+ /*
+ * Optional MUST be listed before required ones
+ */
+ if ((rule->flags & CONF_FLAG_OPTIONAL) != 0) {
+ return 0;
+ }
+
subcs = cf_section_find(cs, rule->name1, rule->name2);
/*
return -1;
}
+ /*
+ * The old rules were delayed until we pushed a matching subsection which is actually used.
+ */
+ if ((old->flags & CONF_FLAG_OPTIONAL) != 0) {
+ if (cf_section_rules_push(subcs, old->subcs) < 0) return -1;
+ }
+
return cf_section_rules_push(subcs, rule->subcs);
}
CONF_FLAG_HIDDEN = (1 << 23), //!< Used by scripts to omit items from the
///< generated documentation.
CONF_FLAG_REF = (1 << 24), //!< reference another conf_parser_t inline in this one
+ CONF_FLAG_OPTIONAL = (1 << 25), //!< subsection is pushed only if a non-optional matching one is pushed
} conf_parser_flags_t;
DIAG_ON(attributes)
CONF_PARSER_TERMINATOR
};
+static conf_parser_t const transport_config[] = {
+ { FR_CONF_OFFSET_FLAGS("secret", CONF_FLAG_REQUIRED, rlm_radius_t, secret) },
+
+ CONF_PARSER_TERMINATOR
+};
+
/*
* A mapping of configuration file names to internal variables.
{ FR_CONF_OFFSET_FLAGS("type", CONF_FLAG_NOT_EMPTY | CONF_FLAG_MULTI | CONF_FLAG_REQUIRED, rlm_radius_t, types),
.func = type_parse },
- { FR_CONF_OFFSET_FLAGS("secret", CONF_FLAG_REQUIRED, rlm_radius_t, secret) },
-
{ FR_CONF_OFFSET("max_packet_size", rlm_radius_t, max_packet_size), .dflt = "4096" },
{ FR_CONF_OFFSET("max_send_coalesce", rlm_radius_t, max_send_coalesce), .dflt = "1024" },
{ FR_CONF_OFFSET_SUBSECTION("pool", 0, rlm_radius_t, trunk_conf, trunk_config ) },
+ { FR_CONF_POINTER("udp", 0, CONF_FLAG_SUBSECTION | CONF_FLAG_OPTIONAL, NULL), .subcs = (void const *) transport_config },
+
+ { FR_CONF_POINTER("tcp", 0, CONF_FLAG_SUBSECTION | CONF_FLAG_OPTIONAL, NULL), .subcs = (void const *) transport_config }
+,
CONF_PARSER_TERMINATOR
};