Commit a1a93f90 authored by Rusty Russell's avatar Rusty Russell

net: make tests more robust.

Andreas Schlick reports failure on systems without IPv6 support (in particular
ones with no IPv6 addresses for localhost).  We should be more robust in
these cases, and also where IPv4 support is missing.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 42b45378
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <stdio.h> #include <stdio.h>
#include <err.h> #include <err.h>
static unsigned int server(int protocol, int type) static int server(int protocol, int type)
{ {
int sock; int sock;
union { union {
...@@ -17,9 +17,12 @@ static unsigned int server(int protocol, int type) ...@@ -17,9 +17,12 @@ static unsigned int server(int protocol, int type)
socklen_t addlen = sizeof(addr); socklen_t addlen = sizeof(addr);
sock = socket(protocol, type, 0); sock = socket(protocol, type, 0);
if (sock < 0)
return -1;
/* Bind to free port. */ /* Bind to free port. */
listen(sock, 0); if (listen(sock, 0) != 0)
return -1;
/* Figure out what port it gave us. */ /* Figure out what port it gave us. */
getsockname(sock, &addr.addr, &addlen); getsockname(sock, &addr.addr, &addlen);
...@@ -43,10 +46,8 @@ static unsigned int server(int protocol, int type) ...@@ -43,10 +46,8 @@ static unsigned int server(int protocol, int type)
? addr.ipv4.sin_port : addr.ipv6.sin6_port); ? addr.ipv4.sin_port : addr.ipv6.sin6_port);
} }
static bool we_faked_double = false; /* Get a localhost on ipv4 and IPv6. Fake it if we can. */
static struct addrinfo* double_addr_lookup(char* buf, bool *fake_double)
/* Get a localhost on ipv4 and IPv6. Fake it if we have to. */
static struct addrinfo* double_addr_lookup(char* buf)
{ {
struct addrinfo *addr, *addr2; struct addrinfo *addr, *addr2;
...@@ -57,9 +58,8 @@ static struct addrinfo* double_addr_lookup(char* buf) ...@@ -57,9 +58,8 @@ static struct addrinfo* double_addr_lookup(char* buf)
/* If we only got one, we need to fake up the other one. */ /* If we only got one, we need to fake up the other one. */
if (addr->ai_next) { if (addr->ai_next) {
addr2 = addr->ai_next; addr2 = addr->ai_next;
*fake_double = false;
} else { } else {
we_faked_double = true;
/* OK, IPv4 only? */ /* OK, IPv4 only? */
if (addr->ai_family == AF_INET) { if (addr->ai_family == AF_INET) {
/* These are the names I found on my Ubuntu system. */ /* These are the names I found on my Ubuntu system. */
...@@ -77,8 +77,14 @@ static struct addrinfo* double_addr_lookup(char* buf) ...@@ -77,8 +77,14 @@ static struct addrinfo* double_addr_lookup(char* buf)
/* IPv6 only? This is a guess... */ /* IPv6 only? This is a guess... */
addr2 = net_client_lookup("ip4-localhost", buf, addr2 = net_client_lookup("ip4-localhost", buf,
AF_UNSPEC, SOCK_STREAM); AF_UNSPEC, SOCK_STREAM);
if (!addr2)
return NULL; /* Perhaps no support on this system? Go ahead with one. */
if (!addr2) {
*fake_double = false;
return addr;
}
*fake_double = true;
addr->ai_next = addr2; addr->ai_next = addr2;
} }
...@@ -93,16 +99,13 @@ static struct addrinfo* double_addr_lookup(char* buf) ...@@ -93,16 +99,13 @@ static struct addrinfo* double_addr_lookup(char* buf)
return NULL; return NULL;
} }
static void double_addr_free(struct addrinfo* addr) static void double_addr_free(struct addrinfo* addr, bool fake_double)
{ {
struct addrinfo *addr2; if (fake_double) {
if (we_faked_double) { freeaddrinfo(addr->ai_next);
addr2 = addr->ai_next;
addr->ai_next = NULL; addr->ai_next = NULL;
} }
freeaddrinfo(addr); freeaddrinfo(addr);
if (we_faked_double)
freeaddrinfo(addr2);
} }
int main(void) int main(void)
...@@ -112,13 +115,23 @@ int main(void) ...@@ -112,13 +115,23 @@ int main(void)
struct sockaddr saddr; struct sockaddr saddr;
socklen_t slen; socklen_t slen;
char buf[20]; char buf[20];
unsigned int port; int port;
bool fake_double;
plan_tests(14); plan_tests(14);
port = server(AF_INET, SOCK_STREAM); port = server(AF_INET, SOCK_STREAM);
if (port == -1) {
/* No IPv4 support? Maybe one day this will happen! */
if (errno == EAFNOSUPPORT)
skip(6, "No IPv4 socket support");
else
fail("Could not create IPv4 listening socket: %s",
strerror(errno));
} else {
sprintf(buf, "%u", port); sprintf(buf, "%u", port);
addr = double_addr_lookup(buf); addr = double_addr_lookup(buf, &fake_double);
ok1(addr); ok1(addr);
fd = net_connect(addr); fd = net_connect(addr);
ok1(fd >= 0); ok1(fd >= 0);
...@@ -132,12 +145,21 @@ int main(void) ...@@ -132,12 +145,21 @@ int main(void)
"Read returned %i (%s)", status, strerror(errno)); "Read returned %i (%s)", status, strerror(errno));
ok1(strncmp(buf, "Yay!", strlen("Yay!")) == 0); ok1(strncmp(buf, "Yay!", strlen("Yay!")) == 0);
close(fd); close(fd);
double_addr_free(addr); double_addr_free(addr, fake_double);
}
port = server(AF_INET6, SOCK_STREAM); port = server(AF_INET6, SOCK_STREAM);
if (port == -1) {
/* No IPv6 support? */
if (errno == EAFNOSUPPORT)
skip(6, "No IPv6 socket support");
else
fail("Could not create IPv6 listening socket: %s",
strerror(errno));
} else {
sprintf(buf, "%u", port); sprintf(buf, "%u", port);
addr = double_addr_lookup(buf); addr = double_addr_lookup(buf, &fake_double);
ok1(addr); ok1(addr);
fd = net_connect(addr); fd = net_connect(addr);
ok1(fd >= 0); ok1(fd >= 0);
...@@ -150,7 +172,8 @@ int main(void) ...@@ -150,7 +172,8 @@ int main(void)
"Read returned %i (%s)", status, strerror(errno)); "Read returned %i (%s)", status, strerror(errno));
ok1(strncmp(buf, "Yay!", strlen("Yay!")) == 0); ok1(strncmp(buf, "Yay!", strlen("Yay!")) == 0);
close(fd); close(fd);
double_addr_free(addr); double_addr_free(addr, fake_double);
}
wait(&status); wait(&status);
ok1(WIFEXITED(status)); ok1(WIFEXITED(status));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment