From 37882cee889d556a932d26084119f516d6639b13 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Fri, 1 Jan 2010 22:01:57 +0100 Subject: ipv6: reuse the existing socket for further lookups This reduces network overhead if you do not run a local caching nameserver. --- src/print_ipv6_addr.c | 58 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/print_ipv6_addr.c b/src/print_ipv6_addr.c index fcb2df8..fd02dba 100644 --- a/src/print_ipv6_addr.c +++ b/src/print_ipv6_addr.c @@ -8,15 +8,46 @@ #include #include +static void print_sockname(int fd) { + static char buf[INET6_ADDRSTRLEN+1]; + struct sockaddr_storage local; + int ret; + + socklen_t local_len = sizeof(struct sockaddr_storage); + if (getsockname(fd, (struct sockaddr*)&local, &local_len) == -1) { + perror("getsockname()"); + (void)close(fd); + printf("no IPv6"); + return; + } + + memset(buf, 0, INET6_ADDRSTRLEN + 1); + if ((ret = getnameinfo((struct sockaddr*)&local, local_len, + buf, sizeof(buf), NULL, 0, + NI_NUMERICHOST)) != 0) { + fprintf(stderr, "getnameinfo(): %s\n", gai_strerror(ret)); + printf("no IPv6"); + return; + } + + printf("%s", buf); +} + /* * Returns the IPv6 address with which you have connectivity at the moment. * */ static void print_ipv6_addr() { - static char buf[INET6_ADDRSTRLEN+1]; struct addrinfo hints; struct addrinfo *result, *resp; - int fd; + static int fd = -1; + + /* To save dns lookups (if they are not cached locally) and creating + * sockets, we save the fd and keep it open. */ + if (fd > -1) { + print_sockname(fd); + return; + } memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET6; @@ -52,29 +83,10 @@ static void print_ipv6_addr() { continue; } - struct sockaddr_storage local; - socklen_t local_len = sizeof(struct sockaddr_storage); - if (getsockname(fd, (struct sockaddr*)&local, &local_len) == -1) { - perror("getsockname()"); - (void)close(fd); - printf("no IPv6"); - return; - } - - (void)close(fd); + free(result); - memset(buf, 0, INET6_ADDRSTRLEN + 1); - int ret; - if ((ret = getnameinfo((struct sockaddr*)&local, local_len, - buf, sizeof(buf), NULL, 0, - NI_NUMERICHOST)) != 0) { - fprintf(stderr, "getnameinfo(): %s\n", gai_strerror(ret)); - printf("no IPv6"); - return; - } + print_sockname(fd); - free(result); - printf("%s", buf); return; } -- cgit v1.2.3