simplified conf file parsing (#582)

This commit is contained in:
Logan oos Even 2021-01-13 00:45:48 +05:45 committed by GitHub
parent 22c7145375
commit 4e2548a98c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 130 additions and 115 deletions

View File

@ -1,6 +1,10 @@
# Advanced Configuration
## Configuration Files
Read about [Configuration Files](ConfigurationFiles.md) as they might come in handy especially, but not limited to, if edges or supernodes shall be run as a service (see below) or in case of bulk automated parameter generation for mass deployment.
## Running edge as a Service
edge can also be run as a service instead of cli:

73
doc/ConfigurationFiles.md Normal file
View File

@ -0,0 +1,73 @@
# Configuration Files
To help deployment of locally different configurations, n2n supports the use of configuration files for `edge` and `supernode`.
They are plain text files and contain the desired command line options, **one per line**.
The exemplary command line
```bash
sudo edge -c mynetwork -k mysecretpass -a 192.168.100.1 -f -l supernode.ntop.org:7777
```
translates into the following `edge.conf` file:
```
-c mynetwork
-k mysecretpass
-a 192.168.100.1
-f
-l supernode.ntop.org:7777
```
which can be loaded by
```
sudo ./edge edge.conf
```
The `.conf` file syntax also allows `=` between parameter and its option:
```
-c=mynetwork
-k=mysecretpass
-a=192.168.100.1
-f
-l=supernode.ntop.org:7777
```
When used with `=`, there is no whitespace allowed between parameter, delimter (`=`), and option. So, do **not** put `-c = mynetwork` it is required to be `-c=mynetwork`.
Comment lines starting with a hash '#' are ignored.
```
# automated edge configuration
# created by bot7
# on April 31, 2038 1800Z
-c mynetwork
-k mysecretpass
-a 192.168.100.1
-f
# --- supernode section ---
-l supernode.ntop.org:7777
```
Long options can be used as well. Please note the double minus/dash character `--`, just like on command line:
```
# automated edge configuration
# created by bot7
# on April 31, 2038 1800Z
--community mynetwork
-k mysecretpass
-a 192.168.100.1
-f
# --- supernode section ---
-l supernode.ntop.org:7777
```
If using a configuration file, its filename needs to be supplied as first parameter to `edge` or `supernode`. If required, additional command line parameters can be supplied afterwards:
```
sudo edge edge.conf -A5
```

View File

@ -1,5 +1,5 @@
/**
* (C) 2007-20 - ntop.org and contributors
* (C) 2007-21 - ntop.org and contributors
*
* 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
@ -525,14 +525,14 @@ static int setOption (int optkey, char *optargument, n2n_tuntap_priv_config_t *e
static const struct option long_options[] =
{
{ "community", required_argument, NULL, 'c' },
{ "community", required_argument, NULL, 'c' },
{ "supernode-list", required_argument, NULL, 'l' },
{ "tap-device", required_argument, NULL, 'd' },
{ "euid", required_argument, NULL, 'u' },
{ "egid", required_argument, NULL, 'g' },
{ "help" , no_argument, NULL, 'h' },
{ "verbose", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 }
{ "tap-device", required_argument, NULL, 'd' },
{ "euid", required_argument, NULL, 'u' },
{ "egid", required_argument, NULL, 'g' },
{ "help" , no_argument, NULL, 'h' },
{ "verbose", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 }
};
/* *************************************************** */
@ -549,8 +549,10 @@ static int loadFromCLI (int argc, char *argv[], n2n_edge_conf_t *conf, n2n_tunta
#endif
,
long_options, NULL)) != '?') {
if(c == 255) break;
setOption(c, optarg, ec, conf);
}
return 0;
@ -579,10 +581,11 @@ static char *trim (char *s) {
/* parse the configuration file */
static int loadFromFile (const char *path, n2n_edge_conf_t *conf, n2n_tuntap_priv_config_t *ec) {
char buffer[4096], *line, *key, *value;
u_int line_len, opt_name_len;
char buffer[4096], *line;
char *line_vec[3];
int tmp;
FILE *fd;
const struct option *opt;
fd = fopen(path, "r");
@ -591,71 +594,29 @@ static int loadFromFile (const char *path, n2n_edge_conf_t *conf, n2n_tuntap_pri
return -1;
}
// we mess around with optind, better save it
tmp = optind;
while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) {
line = trim(line);
value = NULL;
if((line_len = strlen(line)) < 2 || line[0] == '#')
if(strlen(line) < 2 || line[0] == '#')
continue;
if(!strncmp(line, "--", 2)) { /* long opt */
key = &line[2], line_len -= 2;
opt = long_options;
while(opt->name != NULL) {
opt_name_len = strlen(opt->name);
if(!strncmp(key, opt->name, opt_name_len)
&& (line_len <= opt_name_len
|| key[opt_name_len] == '\0'
|| key[opt_name_len] == ' '
|| key[opt_name_len] == '=')) {
if(line_len > opt_name_len) key[opt_name_len] = '\0';
if(line_len > opt_name_len + 1) value = trim(&key[opt_name_len + 1]);
// traceEvent(TRACE_NORMAL, "long key: %s value: %s", key, value);
setOption(opt->val, value, ec, conf);
break;
}
opt++;
}
} else if(line[0] == '-') { /* short opt */
char *equal;
key = &line[1], line_len--;
equal = strchr(line, '=');
if(equal) {
equal[0] = '\0';
value = &equal[1];
if((value[0] == '\0') && (key[1] != '\0'))
value = &key[1];
} else {
value = NULL;
/* Adding an exception for -A_ -z_ which can come
without '=' and even without any further data */
if(key[0] == 'z') {
if(key[1]) value = &key[1];
key = "z";
} else if(key[0] == 'A') {
if(key[1]) value = &key[1];
key = "A";
}
}
// traceEvent(TRACE_NORMAL, "key: %c value: %s", key[0], value);
setOption(key[0], value, ec, conf);
} else {
traceEvent(TRACE_WARNING, "Skipping unrecognized line: %s", line);
continue;
}
// executable, cannot be omitted, content can be anything
line_vec[0] = line;
// first token, e.g. `-p` or `-A3', eventually followed by a whitespace or '=' delimiter
line_vec[1] = strtok(line, "\t =");
// separate parameter option, if present
line_vec[2] = strtok(NULL, "\t ");
// not to duplicate the option parser code, call loadFromCLI and pretend we have no option read yet
optind = 1;
// if second token present (optional argument, not part of first), then announce 3 vector members
loadFromCLI(line_vec[2] ? 3 : 2, line_vec, conf, ec);
}
fclose(fd);
optind = tmp;
return 0;
}
@ -783,8 +744,9 @@ int main (int argc, char* argv[]) {
} else if(argc > 1)
rc = loadFromCLI(argc, argv, &conf, &ec);
else
#ifdef WIN32
/* Load from current directory */
// load from current directory
rc = loadFromFile("edge.conf", &conf, &ec);
#else
rc = -1;

View File

@ -1,5 +1,5 @@
/**
* (C) 2007-20 - ntop.org and contributors
* (C) 2007-21 - ntop.org and contributors
*
* 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
@ -455,10 +455,11 @@ static char *trim (char *s) {
/* parse the configuration file */
static int loadFromFile (const char *path, n2n_sn_t *sss) {
char buffer[4096], *line, *key, *value;
u_int line_len, opt_name_len;
char buffer[4096], *line;
char *line_vec[3];
int tmp;
FILE *fd;
const struct option *opt;
fd = fopen(path, "r");
@ -467,55 +468,31 @@ static int loadFromFile (const char *path, n2n_sn_t *sss) {
return -1;
}
// we mess around with optind, better save it
tmp = optind;
while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) {
line = trim(line);
value = NULL;
if((line_len = strlen(line)) < 2 || line[0] == '#') {
if(strlen(line) < 2 || line[0] == '#') {
continue;
}
if(!strncmp(line, "--", 2)) { /* long opt */
key = &line[2], line_len -= 2;
// executable, cannot be omitted, content can be anything
line_vec[0] = line;
// first token, e.g. `-p`, eventually followed by a whitespace or '=' delimiter
line_vec[1] = strtok(line, "\t =");
// separate parameter option, if present
line_vec[2] = strtok(NULL, "\t ");
opt = long_options;
while(opt->name != NULL) {
opt_name_len = strlen(opt->name);
if(!strncmp(key, opt->name, opt_name_len)
&& (line_len <= opt_name_len
|| key[opt_name_len] == '\0'
|| key[opt_name_len] == ' '
|| key[opt_name_len] == '=')) {
if(line_len > opt_name_len) {
key[opt_name_len] = '\0';
}
if(line_len > opt_name_len + 1) {
value = trim(&key[opt_name_len + 1]);
}
// traceEvent(TRACE_NORMAL, "long key: %s value: %s", key, value);
setOption(opt->val, value, sss);
break;
}
opt++;
}
} else if(line[0] == '-') { /* short opt */
key = &line[1], line_len--;
if(line_len > 1) key[1] = '\0';
if(line_len > 2) value = trim(&key[2]);
// traceEvent(TRACE_NORMAL, "key: %c value: %s", key[0], value);
setOption(key[0], value, sss);
} else {
traceEvent(TRACE_WARNING, "Skipping unrecognized line: %s", line);
continue;
}
// not to duplicate the option parser code, call loadFromCLI and pretend we have no option read yet
optind = 1;
// if separate second token present (optional argument, not part of first), then announce 3 vector members
loadFromCLI(line_vec[2] ? 3 : 2, line_vec, sss);
}
fclose(fd);
optind = tmp;
return 0;
}
@ -624,9 +601,9 @@ int main (int argc, char * const argv[]) {
} else if(argc > 1) {
rc = loadFromCLI(argc, argv, &sss_node);
} else
#ifdef WIN32
/* Load from current directory */
// load from current directory
rc = loadFromFile("supernode.conf", &sss_node);
#else
rc = -1;
@ -636,7 +613,6 @@ int main (int argc, char * const argv[]) {
help();
}
#if defined(N2N_HAVE_DAEMON)
if(sss_node.daemon) {
setUseSyslog(1); /* traceEvent output now goes to syslog. */