cleaner socket protocol parser support

git-svn-id: http://repo.ham.fi/svn/aprsc/trunk@37 3ce903b1-3385-4e86-93cd-f9a4a239f7ac
This commit is contained in:
Matti Aarnio 2008-03-02 01:15:09 +00:00
parent 852a827208
commit c57fc77169
2 changed files with 159 additions and 30 deletions

View File

@ -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] <hostname> <portnum> [<filter> [..<more_filters>]]
*
*/
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 <label> <typelabel> tcp <hostname> <portnum> [<filter> [..<more_filters>]]
* listen <label> <?> [tcp|udp|sctp] <hostname> <portnum> [<filter> [..<more_filters>]]
*
*/
@ -193,11 +291,26 @@ int do_listen(struct listen_config_t **lq, int argc, char **argv)
struct listen_config_t *l;
struct addrinfo req, *ai;
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 (argc < 6)
return -1;
if (strcasecmp(argv[3], "tcp") == 0) {
// well, do nothing for now.
/* 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, "Listen: Unsupported protocol '%s'\n", argv[3]);
return -2;
@ -209,13 +322,6 @@ int do_listen(struct listen_config_t **lq, int argc, char **argv)
return -2;
}
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;
i = getaddrinfo(argv[4], argv[5], &req, &ai);
if (i != 0) {
fprintf(stderr,"Listen: address parse failure of '%s' '%s'",argv[4],argv[5]);
@ -363,6 +469,14 @@ int read_config(void)
if (listen_config)
listen_config->prevp = &listen_config;
listen_config_new = NULL;
/* put in the new aprsis-uplink config */
free_peerip_config(&aprsis_uplink_config);
aprsis_uplink_config = new_aprsis_uplink_config;
if (aprsis_uplink_config)
aprsis_uplink_config->prevp = &aprsis_uplink_config;
new_aprsis_uplink_config = NULL;
if (failed)
return -1;

View File

@ -66,6 +66,7 @@ extern char *rundir;
extern char *logdir;
extern char *logname;
struct listen_config_t {
struct listen_config_t *next;
struct listen_config_t **prevp; /* pointer to the *next pointer in the previous node */
@ -78,8 +79,22 @@ struct listen_config_t {
char *filters[10]; /* up to 10 filters, NULL when not defined */
};
struct peerip_config_t {
struct peerip_config_t *next;
struct peerip_config_t **prevp; /* pointer to the *next pointer in the previous node */
char *name; /* name of socket */
char *host; /* hostname or dotted-quad IP to bind the UDP socket to, default INADDR_ANY */
struct addrinfo *ai;
char *filters[10]; /* up to 10 filters, NULL when not defined */
};
extern struct listen_config_t *listen_config;
extern struct peerip_config_t *aprsis_uplink_ai;
extern int read_config(void);
extern void free_config(void);