mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-29 15:43:56 +00:00
Legacy 'interfaces' config option improvements
Legacy form is now incompatible with modern form. Test case to check legacy parsing.
This commit is contained in:
parent
93c38a764d
commit
c53789d764
1
conf.h
1
conf.h
@ -544,6 +544,7 @@ int cf_opt_sid(sid_t *sidp, const char *text);
|
||||
int cf_opt_rhizome_bk(rhizome_bk_t *bkp, const char *text);
|
||||
int cf_opt_interface_type(short *typep, const char *text);
|
||||
int cf_opt_pattern_list(struct pattern_list *listp, const char *text);
|
||||
int cf_opt_network_interface(struct config_network_interface *nifp, const struct cf_om_node *node);
|
||||
int cf_opt_interface_list(struct config_interface_list *listp, const struct cf_om_node *node);
|
||||
|
||||
extern int cf_limbo;
|
||||
|
@ -394,7 +394,7 @@ int cf_opt_pattern_list(struct pattern_list *listp, const char *text)
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int cf_opt_network_interface(struct config_network_interface *nifp, const char *text)
|
||||
static int cf_opt_network_interface_legacy(struct config_network_interface *nifp, const char *text)
|
||||
{
|
||||
//DEBUGF("%s text=%s", __FUNCTION__, alloca_str_toprint(text));
|
||||
struct config_network_interface nif;
|
||||
@ -472,63 +472,67 @@ int cf_opt_network_interface(struct config_network_interface *nifp, const char *
|
||||
return CFOK;
|
||||
}
|
||||
|
||||
int cf_opt_network_interface(struct config_network_interface *nifp, const struct cf_om_node *node)
|
||||
{
|
||||
if (!node->text)
|
||||
return cf_opt_config_network_interface(nifp, node);
|
||||
cf_warn_spurious_children(node);
|
||||
return cf_opt_network_interface_legacy(nifp, node->text);
|
||||
}
|
||||
|
||||
/* Config parse function. Implements the original form of the 'interfaces' config option. Parses a
|
||||
* comma-separated list of interface rules (see cf_opt_network_interface() for the format of each
|
||||
* rule), then parses the regular config array-of-struct style interface option settings so that
|
||||
* both forms are supported.
|
||||
* comma-separated list of interface rules (see cf_opt_network_interface_legacy() for the format of
|
||||
* each rule), then parses the regular config array-of-struct style interface option settings so
|
||||
* that both forms are supported.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int cf_opt_interface_list(struct config_interface_list *listp, const struct cf_om_node *node)
|
||||
{
|
||||
int result = cf_opt_config_interface_list(listp, node);
|
||||
if (result == CFERROR)
|
||||
return CFERROR;
|
||||
if (node->text) {
|
||||
const char *p;
|
||||
const char *arg = NULL;
|
||||
unsigned n = listp->ac;
|
||||
for (p = node->text; n < NELS(listp->av); ++p) {
|
||||
if (*p == '\0' || *p == ',' || isspace(*p)) {
|
||||
if (arg) {
|
||||
int len = p - arg;
|
||||
if (len > 80) {
|
||||
result |= CFSTRINGOVERFLOW;
|
||||
goto bye;
|
||||
}
|
||||
char buf[len + 1];
|
||||
strncpy(buf, arg, len)[len] = '\0';
|
||||
int ret = cf_opt_network_interface(&listp->av[n].value, buf);
|
||||
switch (ret) {
|
||||
case CFERROR: return CFERROR;
|
||||
case CFOK:
|
||||
len = snprintf(listp->av[n].key, sizeof listp->av[n].key - 1, "%u", n);
|
||||
listp->av[n].key[len] = '\0';
|
||||
++n;
|
||||
break;
|
||||
default:
|
||||
cf_warn_node(node, NULL, "invalid interface rule %s", alloca_str_toprint(buf)); \
|
||||
result |= CFSUB(ret);
|
||||
break;
|
||||
}
|
||||
arg = NULL;
|
||||
if (!node->text)
|
||||
return cf_opt_config_interface_list(listp, node);
|
||||
const char *p;
|
||||
const char *arg = NULL;
|
||||
unsigned n = listp->ac;
|
||||
int result = CFOK;
|
||||
for (p = node->text; n < NELS(listp->av); ++p) {
|
||||
if (*p == '\0' || *p == ',' || isspace(*p)) {
|
||||
if (arg) {
|
||||
int len = p - arg;
|
||||
if (len > 80) {
|
||||
result |= CFSTRINGOVERFLOW;
|
||||
goto bye;
|
||||
}
|
||||
if (!*p)
|
||||
char buf[len + 1];
|
||||
strncpy(buf, arg, len)[len] = '\0';
|
||||
int ret = cf_opt_network_interface_legacy(&listp->av[n].value, buf);
|
||||
switch (ret) {
|
||||
case CFERROR: return CFERROR;
|
||||
case CFOK:
|
||||
len = snprintf(listp->av[n].key, sizeof listp->av[n].key - 1, "%u", n);
|
||||
listp->av[n].key[len] = '\0';
|
||||
++n;
|
||||
break;
|
||||
} else if (!arg)
|
||||
arg = p;
|
||||
}
|
||||
if (*p) {
|
||||
result |= CFARRAYOVERFLOW;
|
||||
goto bye;
|
||||
}
|
||||
assert(n <= NELS(listp->av));
|
||||
listp->ac = n;
|
||||
default:
|
||||
cf_warn_node(node, NULL, "invalid interface rule %s", alloca_str_toprint(buf)); \
|
||||
result |= CFSUB(ret);
|
||||
break;
|
||||
}
|
||||
arg = NULL;
|
||||
}
|
||||
if (!*p)
|
||||
break;
|
||||
} else if (!arg)
|
||||
arg = p;
|
||||
}
|
||||
if (*p) {
|
||||
result |= CFARRAYOVERFLOW;
|
||||
goto bye;
|
||||
}
|
||||
assert(n <= NELS(listp->av));
|
||||
listp->ac = n;
|
||||
bye:
|
||||
if (listp->ac == 0)
|
||||
result |= CFEMPTY;
|
||||
else
|
||||
result &= ~CFEMPTY;
|
||||
return result;
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ END_STRUCT
|
||||
|
||||
ARRAY(interface_list,)
|
||||
KEY_STRING(15, cf_opt_str)
|
||||
VALUE_SUB_STRUCT(network_interface)
|
||||
VALUE_NODE_STRUCT(network_interface, cf_opt_network_interface)
|
||||
END_ARRAY(10)
|
||||
|
||||
// The top level.
|
||||
|
16
tests/config
16
tests/config
@ -25,6 +25,12 @@ setup() {
|
||||
setup_servald
|
||||
}
|
||||
|
||||
execute_servald_config_error() {
|
||||
execute --stderr --exit-status=2 --core-backtrace --executable=$servald "$@"
|
||||
assertStderrGrep --matches=1 --message="stderr of ($executed) contains exactly one error message" '^ERROR:'
|
||||
assertStderrGrep --matches=1 --message="stderr of ($executed) contains one config error message" '^ERROR:.*config file'
|
||||
}
|
||||
|
||||
doc_GetCreateInstanceDir="Get creates instance directory"
|
||||
setup_GetCreateInstanceDir() {
|
||||
setup
|
||||
@ -148,4 +154,14 @@ test_DebugFlagAll() {
|
||||
assertStderrGrep --matches=3 '\<echo:argv\['
|
||||
}
|
||||
|
||||
doc_InterfacesLegacy="Legacy interfaces config option is supported"
|
||||
test_InterfacesLegacy() {
|
||||
executeOk_servald config set interfaces '+eth,-wifi,+'
|
||||
executeOk_servald config set interfaces '+'
|
||||
executeOk_servald config set interfaces '-'
|
||||
executeOk_servald config set interfaces '+eth=ethernet:4111:9M, +wifi=wifi:4112:900K, -'
|
||||
execute_servald_config_error config set interfaces '+eth=foo:4111:9M'
|
||||
assertExitStatus --stderr '!=' 0
|
||||
}
|
||||
|
||||
runTests "$@"
|
||||
|
@ -61,14 +61,14 @@ test_StartLogfile() {
|
||||
tfw_cat log
|
||||
}
|
||||
|
||||
doc_StartNoInterfaces="Starting server with no configured interfaces gives error"
|
||||
doc_StartNoInterfaces="Starting server with no configured interfaces gives warning"
|
||||
setup_StartNoInterfaces() {
|
||||
setup
|
||||
}
|
||||
test_StartNoInterfaces() {
|
||||
start_servald_server
|
||||
sleep 0.1
|
||||
assertGrep --message="log contains 'no interfaces' error message" "$instance_servald_log" '^ERROR:.*interfaces'
|
||||
assertGrep --message="log contains 'no interfaces' warning" "$instance_servald_log" '^WARN:.*interfaces'
|
||||
tfw_cat "$instance_servald_log"
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user