diff --git a/src/config.c b/src/config.c index edef439..4723e35 100644 --- a/src/config.c +++ b/src/config.c @@ -57,20 +57,23 @@ char *new_mycall; char *new_myemail; char *new_myadmin; +struct peerip_config_t *aprsis_uplink_config; +struct peerip_config_t *new_aprsis_uplink_config; + int fork_a_daemon; /* fork a daemon */ int dump_splay; /* print splay tree information */ -int workers_configured = 2; /* number of workers to run */ +int workers_configured = 2; /* number of workers to run */ -int expiry_interval = 10; -int stats_interval = 1 * 60; +int expiry_interval = 10; +int stats_interval = 1 * 60; int lastposition_storetime = 24*60*60; /* how long the last position packet of each station is stored */ -int dupefilter_storetime = 24*60*60; /* how long to store information required for dupe filtering */ +int dupefilter_storetime = 24*60*60; /* how long to store information required for dupe filtering */ -int upstream_timeout = 5*60; /* after N seconds of no input from an upstream, disconnect */ -int client_timeout = 60*60; /* after N seconds of no input from a client, disconnect */ +int upstream_timeout = 5*60; /* after N seconds of no input from an upstream, disconnect */ +int client_timeout = 60*60; /* after N seconds of no input from a client, disconnect */ int ibuf_size = 1500; /* size of input buffer for clients */ int obuf_size = 32*1024; /* size of output buffer for clients */ @@ -82,6 +85,7 @@ struct listen_config_t *listen_config = NULL, *listen_config_new = NULL; int do_listen(struct listen_config_t **lq, int argc, char **argv); int do_interval(time_t *dest, int argc, char **argv); +int do_peerip(struct peerip_config_t **lq, int argc, char **argv); /* * Configuration file commands @@ -90,21 +94,22 @@ int do_interval(time_t *dest, int argc, char **argv); #define _CFUNC_ (int (*)(void *dest, int argc, char **argv)) static struct cfgcmd cfg_cmds[] = { - { "rundir", _CFUNC_ do_string, &new_rundir }, - { "logdir", _CFUNC_ do_string, &new_logdir }, - { "mycall", _CFUNC_ do_string, &new_mycall }, - { "myemail", _CFUNC_ do_string, &new_myemail }, - { "myhostname", _CFUNC_ do_string, &myhostname }, - { "myadmin", _CFUNC_ do_string, &new_myadmin }, - { "workerthreads", _CFUNC_ do_int, &workers_configured }, - { "statsinterval", _CFUNC_ do_interval, &stats_interval }, - { "expiryinterval", _CFUNC_ do_interval, &expiry_interval }, - { "lastpositioncache", _CFUNC_ do_interval, &lastposition_storetime }, - { "dupefiltercache", _CFUNC_ do_interval, &dupefilter_storetime }, - { "upstreamtimeout", _CFUNC_ do_interval, &upstream_timeout }, - { "clienttimeout", _CFUNC_ do_interval, &client_timeout }, - { "listen", _CFUNC_ do_listen, &listen_config_new }, - { NULL, NULL, NULL } + { "rundir", _CFUNC_ do_string, &new_rundir }, + { "logdir", _CFUNC_ do_string, &new_logdir }, + { "mycall", _CFUNC_ do_string, &new_mycall }, + { "myemail", _CFUNC_ do_string, &new_myemail }, + { "myhostname", _CFUNC_ do_string, &myhostname }, + { "myadmin", _CFUNC_ do_string, &new_myadmin }, + { "workerthreads", _CFUNC_ do_int, &workers_configured }, + { "statsinterval", _CFUNC_ do_interval, &stats_interval }, + { "expiryinterval", _CFUNC_ do_interval, &expiry_interval }, + { "lastpositioncache", _CFUNC_ do_interval, &lastposition_storetime }, + { "dupefiltercache", _CFUNC_ do_interval, &dupefilter_storetime }, + { "upstreamtimeout", _CFUNC_ do_interval, &upstream_timeout }, + { "clienttimeout", _CFUNC_ do_interval, &client_timeout }, + { "listen", _CFUNC_ do_listen, &listen_config_new }, + { "aprsis-uplink", _CFUNC_ do_peerip, &new_aprsis_uplink_config }, + { NULL, NULL, NULL } }; /* @@ -129,6 +134,28 @@ void free_listen_config(struct listen_config_t **lc) } } +/* + * Free a peer-ip config tree + */ + +void free_peerip_config(struct peerip_config_t **lc) +{ + struct peerip_config_t *this; + int i; + + while (*lc) { + this = *lc; + *lc = this->next; + hfree(this->name); + hfree(this->host); + for (i = 0; i < (sizeof(this->filters)/sizeof(this->filters[0])); ++i) + if (this->filters[i]) + hfree(this->filters[i]); + freeaddrinfo(this->ai); + hfree(this); + } +} + /* * parse an interval specification */ @@ -180,10 +207,81 @@ int do_interval(time_t *dest, int argc, char **argv) return 0; } +/* + * Parse a peer definition directive + * + * "keyword" [tcp|udp|sctp] [ [..]] + * + */ + +int do_peerip(struct peerip_config_t **lq, int argc, char **argv) +{ + int i, port; + struct peerip_config_t *l; + struct addrinfo req, *ai; + + if (argc < 4) + return -1; + + memset(&req, 0, sizeof(req)); + req.ai_family = 0; + req.ai_socktype = SOCK_STREAM; + req.ai_protocol = IPPROTO_TCP; + req.ai_flags = 0; + ai = NULL; + + if (strcasecmp(argv[1], "tcp") == 0) { + // well, do nothing for now. + } else if (strcasecmp(argv[3], "udp") == 0) { + req.ai_socktype = SOCK_DGRAM; + req.ai_protocol = IPPROTO_UDP; +#if defined(SOCK_SEQPACKET) && defined(IPPROTO_SCTP) + } else if (strcasecmp(argv[3], "sctp") == 0) { + req.ai_socktype = SOCK_SEQPACKET; + req.ai_protocol = IPPROTO_SCTP; +#endif + } else { + fprintf(stderr, "Peer-ip: Unsupported protocol '%s'\n", argv[1]); + return -2; + } + + port = atoi(argv[3]); + if (port < 1 || port > 65535) { + fprintf(stderr, "Listen: unsupported port number '%s'\n", argv[3]); + return -2; + } + + i = getaddrinfo(argv[2], argv[3], &req, &ai); + if (i != 0) { + fprintf(stderr,"Listen: address parse failure of '%s' '%s'",argv[2],argv[3]); + return i; + } + + + l = hmalloc(sizeof(*l)); + l->name = hstrdup(argv[1]); + l->host = hstrdup(argv[4]); + l->ai = ai; + for (i = 0; i < (sizeof(l->filters)/sizeof(l->filters[0])); ++i) { + l->filters[i] = NULL; + if (argc - 4 > i) { + l->filters[i] = hstrdup(argv[i+4]); + } + } + + /* put in the list */ + l->next = *lq; + if (l->next) + l->next->prevp = &l->next; + *lq = l; + + return 0; +} + /* * Parse a Listen directive * - * listen