From c1eb1c8fd2c7fb8d9e7c7e54abca684149f11a5d Mon Sep 17 00:00:00 2001 From: Matti Aarnio Date: Sat, 1 Mar 2008 01:45:12 +0000 Subject: [PATCH] socket interface modernisation, client keepalives git-svn-id: http://repo.ham.fi/svn/aprsc/trunk@30 3ce903b1-3385-4e86-93cd-f9a4a239f7ac --- src/accept.c | 47 ++++++++++++-------- src/aprsc.c | 5 ++- src/aprsc.conf | 1 + src/config.c | 5 ++- src/config.h | 1 + src/login.c | 28 ++++++------ src/splay.h | 3 +- src/worker.c | 116 ++++++++++++++++++++++++++++++++++++++++--------- src/worker.h | 25 ++++++++--- 9 files changed, 169 insertions(+), 62 deletions(-) diff --git a/src/accept.c b/src/accept.c index b89a88b..fa9327e 100644 --- a/src/accept.c +++ b/src/accept.c @@ -51,7 +51,7 @@ struct listen_t { struct listen_t *next; struct listen_t **prevp; - struct sockaddr_in sin; + union sockaddr_u sa; socklen_t addr_len; int fd; @@ -127,7 +127,7 @@ int open_tcp_listener(struct listen_t *l) arg = 1; setsockopt(f, SOL_SOCKET, SO_REUSEADDR, (char *)&arg, sizeof(arg)); - if (bind(f, (struct sockaddr *)&l->sin, sizeof(l->sin))) { + if (bind(f, (struct sockaddr *)&l->sa, l->addr_len)) { hlog(LOG_CRIT, "bind(%s): %s", l->addr_s, strerror(errno)); close(f); return -1; @@ -149,15 +149,16 @@ int open_listeners(void) struct listen_config_t *lc; struct listen_t *l; struct hostent *he; - char eb[80]; + char eb[80], *s; int opened = 0, i; for (lc = listen_config; (lc); lc = lc->next) { l = listener_alloc(); - l->sin.sin_family = AF_INET; - l->sin.sin_port = htons(lc->port); - + l->sa.si.sin_family = AF_INET; + l->sa.si.sin_port = htons(lc->port); + l->addr_len = sizeof(l->sa.si); + if (lc->host) { if (!(he = gethostbyname(lc->host))) { h_strerror(h_errno, eb, sizeof(eb)); @@ -165,12 +166,16 @@ int open_listeners(void) listener_free(l); continue; } - memcpy(&l->sin.sin_addr.s_addr, he->h_addr_list[0], he->h_length); + memcpy(&l->sa.si.sin_addr.s_addr, he->h_addr_list[0], he->h_length); } else { - l->sin.sin_addr.s_addr = INADDR_ANY; + l->sa.si.sin_addr.s_addr = INADDR_ANY; } - aptoa(l->sin.sin_addr, ntohs(l->sin.sin_port), eb, sizeof(eb)); + eb[0] = '['; + inet_ntop(l->sa.sa.sa_family, &l->sa.si.sin_addr, eb+1, sizeof(eb)-1); + s = eb + strlen(eb); + sprintf(s, "]:%d", ntohs(((l->sa.sa.sa_family == AF_INET) ? l->sa.si.sin_port : l->sa.si6.sin6_port))); + l->addr_s = hstrdup(eb); if (open_tcp_listener(l) >= 0) { @@ -185,7 +190,7 @@ int open_listeners(void) /* Copy filter definitions */ for (i = 0; i < (sizeof(l->filters)/sizeof(l->filters[0])); ++i) { if (i < (sizeof(lc->filters)/sizeof(lc->filters[0]))) - l->filters[i] = lc->filters[i]; + l->filters[i] = (lc->filters[i]) ? hstrdup(lc->filters[i]) : NULL; else l->filters[i] = NULL; } @@ -224,14 +229,14 @@ void close_listeners(void) struct client_t *do_accept(struct listen_t *l) { - char eb[80]; int fd, i; struct client_t *c; - struct sockaddr_in *sin; - struct sockaddr sa; + union sockaddr_u sa; socklen_t addr_len = sizeof(sa); + char eb[200]; + char *s; - if ((fd = accept(l->fd, &sa, &addr_len)) < 0) { + if ((fd = accept(l->fd, (struct sockaddr*)&sa, &addr_len)) < 0) { int e = errno; switch (e) { /* Errors reporting really bad internal (programming) bugs */ @@ -263,9 +268,15 @@ struct client_t *do_accept(struct listen_t *l) } c = client_alloc(); - sin = (struct sockaddr_in *)&c->addr; + c->fd = fd; + c->addr = sa; + c->state = CSTATE_LOGIN; + + eb[0] = '['; + inet_ntop(sa.sa.sa_family, &sa.si.sin_addr, eb+1, sizeof(eb)-1); + s = eb + strlen(eb); + sprintf(s, "]:%d", ntohs((sa.sa.sa_family == AF_INET) ? sa.si.sin_port : sa.si6.sin6_port)); - aptoa(sin->sin_addr, ntohs(sin->sin_port), eb, sizeof(eb)); c->addr_s = hstrdup(eb); hlog(LOG_DEBUG, "%s - Accepted connection on fd %d from %s", l->addr_s, c->fd, eb); @@ -353,8 +364,10 @@ void accept_thread(void *asdf) close_listeners(); /* start listening on the sockets */ - if ((listen_n = open_listeners()) <= 0) + if ((listen_n = open_listeners()) <= 0) { hlog(LOG_CRIT, "Failed to listen on any ports."); + exit(2); + } hlog(LOG_DEBUG, "Generating polling list..."); acceptpfd = hmalloc(listen_n * sizeof(*acceptpfd)); diff --git a/src/aprsc.c b/src/aprsc.c index 91779e4..f3df981 100644 --- a/src/aprsc.c +++ b/src/aprsc.c @@ -234,16 +234,19 @@ int main(int argc, char **argv) accept_reconfiguring = 1; } } - /* + + /* if (now >= next_expiry) { next_expiry = now + expiry_interval; // expire + // pbuf_expire(); } if (now >= next_stats) { next_stats = now + stats_interval; // log stats } */ + } hlog(LOG_INFO, "Signalling accept_thread to shut down..."); diff --git a/src/aprsc.conf b/src/aprsc.conf index a03b887..188f429 100644 --- a/src/aprsc.conf +++ b/src/aprsc.conf @@ -8,6 +8,7 @@ MyCall N0CALL MyEmail email@example.com MyAdmin "My Name, MYCALL" +MyHostname aprsc-1.example.com ### Directories ######### # Data directory (for database files) diff --git a/src/config.c b/src/config.c index f6e544b..2e19d5f 100644 --- a/src/config.c +++ b/src/config.c @@ -52,6 +52,7 @@ char *logname = def_logname; /* syslog entries use this program name */ char *mycall = NULL; char *myemail = NULL; char *myadmin = NULL; +char *myhostname = "undefined-hostname"; char *new_mycall = NULL; char *new_myemail = NULL; char *new_myadmin = NULL; @@ -93,6 +94,7 @@ static struct cfgcmd cfg_cmds[] = { { "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 }, @@ -180,7 +182,7 @@ int do_interval(time_t *dest, int argc, char **argv) /* * Parse a Listen directive * - * listen