From f08a7c77c19f3825307a946c8a4a8720975300e0 Mon Sep 17 00:00:00 2001 From: Matti Aarnio Date: Sat, 1 Mar 2008 03:20:05 +0000 Subject: [PATCH] switch entirely to getnameinfo()/getaddrinfo() resolver APIs git-svn-id: http://repo.ham.fi/svn/aprsc/trunk@31 3ce903b1-3385-4e86-93cd-f9a4a239f7ac --- src/accept.c | 58 +++++++++++++++++++++++--------------------------- src/aprsc.conf | 14 ++++++------ src/config.c | 55 ++++++++++++++++++++++++++++++++--------------- src/config.h | 8 ++++++- src/netlib.c | 3 ++- src/netlib.h | 4 ++-- 6 files changed, 83 insertions(+), 59 deletions(-) diff --git a/src/accept.c b/src/accept.c index fa9327e..95ac4cf 100644 --- a/src/accept.c +++ b/src/accept.c @@ -51,8 +51,7 @@ struct listen_t { struct listen_t *next; struct listen_t **prevp; - union sockaddr_u sa; - socklen_t addr_len; + struct addrinfo *ai; int fd; char *addr_s; @@ -119,7 +118,7 @@ int open_tcp_listener(struct listen_t *l) hlog(LOG_INFO, "Binding listening TCP socket: %s", l->addr_s); - if ((f = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + if ((f = socket(l->ai->ai_family, l->ai->ai_socktype, l->ai->ai_protocol)) < 0) { hlog(LOG_CRIT, "socket(): %s\n", strerror(errno)); return -1; } @@ -127,7 +126,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->sa, l->addr_len)) { + if (bind(f, l->ai->ai_addr, l->ai->ai_addrlen)) { hlog(LOG_CRIT, "bind(%s): %s", l->addr_s, strerror(errno)); close(f); return -1; @@ -148,33 +147,25 @@ int open_listeners(void) { struct listen_config_t *lc; struct listen_t *l; - struct hostent *he; - char eb[80], *s; + char eb[120], *s; + char sbuf[20]; int opened = 0, i; for (lc = listen_config; (lc); lc = lc->next) { l = listener_alloc(); - 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)); - hlog(LOG_CRIT, "Listen: Could not resolve \"%s\": %s - not listening on port %d\n", lc->host, eb, lc->port); - listener_free(l); - continue; - } - memcpy(&l->sa.si.sin_addr.s_addr, he->h_addr_list[0], he->h_length); - } else { - l->sa.si.sin_addr.s_addr = INADDR_ANY; - } + /* Pick first of the AIs for this listen definition */ eb[0] = '['; - inet_ntop(l->sa.sa.sa_family, &l->sa.si.sin_addr, eb+1, sizeof(eb)-1); + eb[1] = 0; + *sbuf = 0; + + l->ai = lc->ai; + + getnameinfo(l->ai->ai_addr, l->ai->ai_addrlen, + eb+1, sizeof(eb)-1, sbuf, sizeof(sbuf), NI_NUMERICHOST|NI_NUMERICSERV); 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))); + sprintf(s, "]:%s", sbuf); l->addr_s = hstrdup(eb); @@ -195,7 +186,7 @@ int open_listeners(void) l->filters[i] = NULL; } - hlog(LOG_DEBUG, "... adding to listened sockets"); + hlog(LOG_DEBUG, "... adding %s to listened sockets", eb); // put (first) in the list of listening sockets l->next = listen_list; l->prevp = &listen_list; @@ -231,9 +222,10 @@ struct client_t *do_accept(struct listen_t *l) { int fd, i; struct client_t *c; - union sockaddr_u sa; + union sockaddr_u sa; /* large enough for also IPv6 address */ socklen_t addr_len = sizeof(sa); char eb[200]; + char sbuf[20]; char *s; if ((fd = accept(l->fd, (struct sockaddr*)&sa, &addr_len)) < 0) { @@ -267,17 +259,21 @@ struct client_t *do_accept(struct listen_t *l) } } + eb[0] = '['; + eb[1] = 0; + *sbuf = 0; + + getnameinfo((struct sockaddr *)&sa, addr_len, + eb+1, sizeof(eb)-1, sbuf, sizeof(sbuf), NI_NUMERICHOST|NI_NUMERICSERV); + s = eb + strlen(eb); + sprintf(s, "]:%s", sbuf); + c = client_alloc(); 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)); - c->addr_s = hstrdup(eb); + hlog(LOG_DEBUG, "%s - Accepted connection on fd %d from %s", l->addr_s, c->fd, eb); for (i = 0; i < (sizeof(l->filters)/sizeof(l->filters[0])); ++i) { diff --git a/src/aprsc.conf b/src/aprsc.conf index 188f429..b650f70 100644 --- a/src/aprsc.conf +++ b/src/aprsc.conf @@ -5,9 +5,9 @@ # Configuration for aprsc, an APRS-IS server for core servers -MyCall N0CALL -MyEmail email@example.com -MyAdmin "My Name, MYCALL" +MyCall N0CALL +MyEmail email@example.com +MyAdmin "My Name, MYCALL" MyHostname aprsc-1.example.com ### Directories ######### @@ -49,10 +49,10 @@ ClientTimeout 48h # msgonly - messages only # userfilter - user-specified filters # -Listen "userfilter" userfilter tcp 0.0.0.0 14580 -Listen "fullfeed" fullfeed tcp 83.145.252.162 10152 -Listen "dupefeed" dupefeed tcp 127.0.0.1 10159 -Listen "msgonly" messageonly tcp 10.5.12.5 1314 +Listen "userfilter" userfilter tcp :: 14580 +Listen "fullfeed" fullfeed tcp 83.145.252.162 10152 +Listen "dupefeed" dupefeed tcp ::1 10159 +Listen "msgonly" messageonly tcp 10.5.12.5 1314 ### Internals ############ # The number of worker threads to run - set this to the number of diff --git a/src/config.c b/src/config.c index 2e19d5f..edef439 100644 --- a/src/config.c +++ b/src/config.c @@ -40,26 +40,26 @@ char def_cfgfile[] = "aprsc.conf"; char *cfgfile = def_cfgfile; -char *pidfile = NULL; -char *new_rundir = NULL; -char *rundir = NULL; -char *new_logdir = NULL; -char *logdir = NULL; /* access logs go here */ +char *pidfile; +char *new_rundir; +char *rundir; +char *new_logdir; +char *logdir; /* access logs go here */ char def_logname[] = "aprsc"; 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; +char *mycall; +char *myemail; +char *myadmin; +char *myhostname; +char *new_mycall; +char *new_myemail; +char *new_myadmin; -int fork_a_daemon = 0; /* fork a daemon */ +int fork_a_daemon; /* fork a daemon */ -int dump_splay = 0; /* print splay tree information */ +int dump_splay; /* print splay tree information */ int workers_configured = 2; /* number of workers to run */ @@ -75,7 +75,7 @@ int client_timeout = 60*60; /* after N seconds of no input from a client, disco int ibuf_size = 1500; /* size of input buffer for clients */ int obuf_size = 32*1024; /* size of output buffer for clients */ -int verbose = 0; +int verbose; /* address:port pairs being listened */ struct listen_config_t *listen_config = NULL, *listen_config_new = NULL; @@ -124,6 +124,7 @@ void free_listen_config(struct listen_config_t **lc) 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); } } @@ -190,6 +191,7 @@ int do_listen(struct listen_config_t **lq, int argc, char **argv) { int i, port; struct listen_config_t *l; + struct addrinfo req, *ai; if (argc < 6) return -1; @@ -206,11 +208,25 @@ int do_listen(struct listen_config_t **lq, int argc, char **argv) fprintf(stderr, "Listen: unsupported port number '%s'\n", argv[5]); 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]); + return i; + } + + l = hmalloc(sizeof(*l)); l->name = hstrdup(argv[1]); l->host = hstrdup(argv[4]); - l->port = port; + l->ai = ai; for (i = 0; i < (sizeof(l->filters)/sizeof(l->filters[0])); ++i) { l->filters[i] = NULL; if (argc - 6 > i) { @@ -264,6 +280,10 @@ int read_config(void) { int failed = 0; char *s; + + myhostname = hstrdup("undefined-hostname"); + myadmin = hstrdup("undefined-myadmin"); + myemail = hstrdup("undefined-myemail"); if (read_cfgfile(cfgfile, cfg_cmds)) return -1; @@ -382,5 +402,6 @@ void free_config(void) hfree(myadmin); mycall = myemail = myadmin = NULL; logname = NULL; + free_listen_config(&listen_config); } diff --git a/src/config.h b/src/config.h index 80ca4fd..49549ea 100644 --- a/src/config.h +++ b/src/config.h @@ -34,6 +34,11 @@ #include #include #include +#include + +#ifndef AI_PASSIVE +#include "netdb6.h" +#endif extern int fork_a_daemon; /* fork a daemon */ @@ -67,7 +72,8 @@ struct listen_config_t { char *name; /* name of socket */ char *host; /* hostname or dotted-quad IP to bind the UDP socket to, default INADDR_ANY */ - int port; /* port to bind */ + + struct addrinfo *ai; char *filters[10]; /* up to 10 filters, NULL when not defined */ }; diff --git a/src/netlib.c b/src/netlib.c index 4efc00c..8358ab0 100644 --- a/src/netlib.c +++ b/src/netlib.c @@ -27,6 +27,7 @@ #include "netlib.h" +#if 0 /* * Convert address & port to string */ @@ -47,7 +48,6 @@ int aptoa(struct in_addr sin_addr, int sin_port, char *s, int len) } } - /* * Convert return values of gethostbyname() to a string */ @@ -67,4 +67,5 @@ int h_strerror(int i, char *s, int len) return snprintf(s, len, "%d", i); } } +#endif diff --git a/src/netlib.h b/src/netlib.h index a35d2ff..221d0ea 100644 --- a/src/netlib.h +++ b/src/netlib.h @@ -22,7 +22,7 @@ #ifndef NETLIB_H #define NETLIB_H -extern int aptoa(struct in_addr sin_addr, int sin_port, char *s, int len); -extern int h_strerror(int i, char *s, int len); +// extern int aptoa(struct in_addr sin_addr, int sin_port, char *s, int len); +// extern int h_strerror(int i, char *s, int len); #endif