summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stapelberg <michael@stapelberg.de>2010-01-01 22:01:57 +0100
committerMichael Stapelberg <michael@stapelberg.de>2010-01-01 22:01:57 +0100
commit37882cee889d556a932d26084119f516d6639b13 (patch)
tree3e99fd872819c16491c1b2089da784b1d8cb82a0
parent998109a6537c4534652673ff25d72a502cb15605 (diff)
ipv6: reuse the existing socket for further lookups
This reduces network overhead if you do not run a local caching nameserver.
-rw-r--r--src/print_ipv6_addr.c58
1 files 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 <string.h>
#include <arpa/inet.h>
+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;
}