From 479471c409a61d01290ac9444042357b03f8d0b0 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 23 Jan 2014 20:42:06 -0800 Subject: [PATCH] server: make the connect code fully IPv6 Signed-off-by: Jens Axboe --- server.c | 51 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/server.c b/server.c index 6e96b77a..9b13df8b 100644 --- a/server.c +++ b/server.c @@ -840,7 +840,8 @@ static int handle_connection(int sk) static int accept_loop(int listen_sk) { struct sockaddr_in addr; - socklen_t len = sizeof(addr); + struct sockaddr_in6 addr6; + socklen_t len = use_ipv6 ? sizeof(addr6) : sizeof(addr); struct pollfd pfd; int ret = 0, sk, flags, exitval = 0; FLIST_HEAD(conn_list); @@ -852,6 +853,8 @@ static int accept_loop(int listen_sk) fcntl(listen_sk, F_SETFL, flags); while (!exit_backend) { + const char *from; + char buf[64]; pid_t pid; pfd.fd = listen_sk; @@ -882,13 +885,22 @@ static int accept_loop(int listen_sk) if (exit_backend || ret < 0) break; - sk = accept(listen_sk, (struct sockaddr *) &addr, &len); + if (use_ipv6) + sk = accept(listen_sk, (struct sockaddr *) &addr6, &len); + else + sk = accept(listen_sk, (struct sockaddr *) &addr, &len); + if (sk < 0) { log_err("fio: accept: %s\n", strerror(errno)); return -1; } - dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr)); + if (use_ipv6) + from = inet_ntop(AF_INET6, (struct sockaddr *) &addr6.sin6_addr, buf, sizeof(buf)); + else + from = inet_ntop(AF_INET, (struct sockaddr *) &addr.sin_addr, buf, sizeof(buf)); + + dprint(FD_NET, "server: connect from %s\n", from); pid = fork(); if (pid) { @@ -1392,29 +1404,26 @@ int fio_server_parse_host(const char *host, int *ipv6, struct in_addr *inp, ret = inet_pton(AF_INET, host, inp); if (ret != 1) { - struct hostent *hent; + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = *ipv6 ? AF_INET6 : AF_INET; + hints.ai_socktype = SOCK_STREAM; - hent = gethostbyname(host); - if (!hent) { - log_err("fio: failed to resolve <%s>\n", host); + ret = getaddrinfo(host, NULL, &hints, &res); + if (ret) { + log_err("fio: failed to resolve <%s> (%s)\n", host, + gai_strerror(ret)); return 0; } - if (*ipv6) { - if (hent->h_addrtype != AF_INET6) { - log_info("fio: falling back to IPv4\n"); - *ipv6 = 0; - } else - memcpy(inp6, hent->h_addr_list[0], 16); - } - if (!*ipv6) { - if (hent->h_addrtype != AF_INET) { - log_err("fio: lookup type mismatch\n"); - return 0; - } - memcpy(inp, hent->h_addr_list[0], 4); - } + if (*ipv6) + memcpy(inp6, &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr, sizeof(*inp6)); + else + memcpy(inp, &((struct sockaddr_in *) res->ai_addr)->sin_addr, sizeof(*inp)); + ret = 1; + freeaddrinfo(res); } return !(ret == 1); -- 2.25.1