From 316befb960fea2009ed1b8bed26b4060f04673ba Mon Sep 17 00:00:00 2001 From: Marvin Sielenkemper Date: Fri, 16 Sep 2016 21:35:36 +0200 Subject: Add IPv6 support and a new '-A' option to specify an IPv6 adress to bind --- src/c/http.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/c/http.c b/src/c/http.c index 9059746f..5752fc6f 100644 --- a/src/c/http.c +++ b/src/c/http.c @@ -325,8 +325,8 @@ static void sigint(int signum) { int main(int argc, char *argv[]) { // The skeleton for this function comes from Beej's sockets tutorial. int sockfd; // listen on sock_fd - struct sockaddr_in my_addr; - struct sockaddr_in their_addr; // connector's address information + struct sockaddr_in6 my_addr; + struct sockaddr_in6 their_addr; // connector's address information socklen_t sin_size; int yes = 1, uw_port = 8080, nthreads = 1, i, *names, opt; int recv_timeout_sec = 5; @@ -334,10 +334,9 @@ int main(int argc, char *argv[]) { signal(SIGINT, sigint); signal(SIGPIPE, SIG_IGN); - my_addr.sin_addr.s_addr = INADDR_ANY; // auto-fill with my IP - memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero); + my_addr.sin6_addr = in6addr_any; // auto-fill with my IP - while ((opt = getopt(argc, argv, "hp:a:t:kqT:")) != -1) { + while ((opt = getopt(argc, argv, "hp:a:A:t:kqT:")) != -1) { switch (opt) { case '?': fprintf(stderr, "Unknown command-line option\n"); @@ -358,8 +357,21 @@ int main(int argc, char *argv[]) { break; case 'a': - if (!inet_pton(AF_INET, optarg, &my_addr.sin_addr)) { - fprintf(stderr, "Invalid IP address\n"); + { + char *buf = alloca(strlen(optarg) + 8); + strcpy(buf, "::FFFF:"); + strcpy(buf + 7, optarg); + if (!inet_pton(AF_INET6, buf, &my_addr.sin6_addr)) { + fprintf(stderr, "Invalid IPv4 address\n"); + help(argv[0]); + return 1; + } + } + break; + + case 'A': + if (!inet_pton(AF_INET6, optarg, &my_addr.sin6_addr)) { + fprintf(stderr, "Invalid IPv6 address\n"); help(argv[0]); return 1; } @@ -401,7 +413,7 @@ int main(int argc, char *argv[]) { names = calloc(nthreads, sizeof(int)); - sockfd = socket(PF_INET, SOCK_STREAM, 0); // do some error checking! + sockfd = socket(AF_INET6, SOCK_STREAM, 0); // do some error checking! if (sockfd < 0) { fprintf(stderr, "Listener socket creation failed\n"); @@ -413,8 +425,8 @@ int main(int argc, char *argv[]) { return 1; } - my_addr.sin_family = AF_INET; // host byte order - my_addr.sin_port = htons(uw_port); // short, network byte order + my_addr.sin6_family = AF_INET6; // host byte order + my_addr.sin6_port = htons(uw_port); // short, network byte order if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) < 0) { fprintf(stderr, "Listener socket bind failed\n"); -- cgit v1.2.3 From c70444b4dd41960554f5f283d22e911df6447737 Mon Sep 17 00:00:00 2001 From: Marvin Sielenkemper Date: Fri, 16 Sep 2016 22:19:07 +0200 Subject: Add tests for IPv6 --- Makefile.am | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile.am b/Makefile.am index 9ab31acd..8e945a47 100644 --- a/Makefile.am +++ b/Makefile.am @@ -121,4 +121,11 @@ test: (curl -s 'http://localhost:8080/Demo/Hello/main' | diff tests/hello.html -) || (kill `cat $(TESTPID)`; echo "Test 'Hello' failed"; /bin/false) (curl -s 'http://localhost:8080/Demo/Crud1/create?A=1&B=2&C=3&D=4' | diff tests/crud1.html -) || (kill `cat $(TESTPID)`; echo "Test 'Crud1' failed"; /bin/false) kill `cat $(TESTPID)` + rm -f $(TESTDB) + sqlite3 $(TESTDB) < demo/demo.sql + demo/demo.exe & echo $$! > $(TESTPID) + sleep 1 + (curl -s 'http://[::1]:8080/Demo/Hello/main' | diff tests/hello.html -) || (kill `cat $(TESTPID)`; echo "Test 'Hello' failed"; /bin/false) + (curl -s 'http://[::1]:8080/Demo/Crud1/create?A=1&B=2&C=3&D=4' | diff tests/crud1.html -) || (kill `cat $(TESTPID)`; echo "Test 'Crud1' failed"; /bin/false) + kill `cat $(TESTPID)` echo Tests succeeded. -- cgit v1.2.3 From 13a90684dc583427ad1d59a10d8bb00928fb6687 Mon Sep 17 00:00:00 2001 From: Marvin Sielenkemper Date: Fri, 16 Sep 2016 22:38:08 +0200 Subject: Amend the tests to check if the new option works --- Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 8e945a47..3eb0a377 100644 --- a/Makefile.am +++ b/Makefile.am @@ -116,14 +116,14 @@ test: bin/urweb -boot -noEmacs -dbms sqlite -db $(TESTDB) -demo /Demo demo rm -f $(TESTDB) sqlite3 $(TESTDB) < demo/demo.sql - demo/demo.exe & echo $$! > $(TESTPID) + demo/demo.exe -a 127.0.0.1 & echo $$! > $(TESTPID) sleep 1 (curl -s 'http://localhost:8080/Demo/Hello/main' | diff tests/hello.html -) || (kill `cat $(TESTPID)`; echo "Test 'Hello' failed"; /bin/false) (curl -s 'http://localhost:8080/Demo/Crud1/create?A=1&B=2&C=3&D=4' | diff tests/crud1.html -) || (kill `cat $(TESTPID)`; echo "Test 'Crud1' failed"; /bin/false) kill `cat $(TESTPID)` rm -f $(TESTDB) sqlite3 $(TESTDB) < demo/demo.sql - demo/demo.exe & echo $$! > $(TESTPID) + demo/demo.exe -A ::1 & echo $$! > $(TESTPID) sleep 1 (curl -s 'http://[::1]:8080/Demo/Hello/main' | diff tests/hello.html -) || (kill `cat $(TESTPID)`; echo "Test 'Hello' failed"; /bin/false) (curl -s 'http://[::1]:8080/Demo/Crud1/create?A=1&B=2&C=3&D=4' | diff tests/crud1.html -) || (kill `cat $(TESTPID)`; echo "Test 'Crud1' failed"; /bin/false) -- cgit v1.2.3 From 10baddb6ee0fcd645ef0da096ef1dd5b6d4e09a4 Mon Sep 17 00:00:00 2001 From: Marvin Sielenkemper Date: Sat, 17 Sep 2016 08:22:12 +0200 Subject: Explicitly cleares IPV6_V6ONLY to ensure IPv4 availability --- src/c/http.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/c/http.c b/src/c/http.c index 5752fc6f..b3ada18a 100644 --- a/src/c/http.c +++ b/src/c/http.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include @@ -328,7 +330,7 @@ int main(int argc, char *argv[]) { struct sockaddr_in6 my_addr; struct sockaddr_in6 their_addr; // connector's address information socklen_t sin_size; - int yes = 1, uw_port = 8080, nthreads = 1, i, *names, opt; + int yes = 1, no = 0, uw_port = 8080, nthreads = 1, i, *names, opt; int recv_timeout_sec = 5; signal(SIGINT, sigint); @@ -425,6 +427,11 @@ int main(int argc, char *argv[]) { return 1; } + if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &no, sizeof(int)) < 0) { + fprintf(stderr, "Listener IPV6_V6ONLY option resetting failed\n"); + return 1; + } + my_addr.sin6_family = AF_INET6; // host byte order my_addr.sin6_port = htons(uw_port); // short, network byte order -- cgit v1.2.3 From 6bd95b0236f8142181aae369c93e00d15bb3c83f Mon Sep 17 00:00:00 2001 From: Marvin Sielenkemper Date: Sat, 17 Sep 2016 09:33:39 +0200 Subject: Check if the loopback interface has an IPv6 address and only run IPv6 test tests if this is the case --- Makefile.am | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Makefile.am b/Makefile.am index 3eb0a377..0b9a5957 100644 --- a/Makefile.am +++ b/Makefile.am @@ -121,11 +121,17 @@ test: (curl -s 'http://localhost:8080/Demo/Hello/main' | diff tests/hello.html -) || (kill `cat $(TESTPID)`; echo "Test 'Hello' failed"; /bin/false) (curl -s 'http://localhost:8080/Demo/Crud1/create?A=1&B=2&C=3&D=4' | diff tests/crud1.html -) || (kill `cat $(TESTPID)`; echo "Test 'Crud1' failed"; /bin/false) kill `cat $(TESTPID)` - rm -f $(TESTDB) - sqlite3 $(TESTDB) < demo/demo.sql - demo/demo.exe -A ::1 & echo $$! > $(TESTPID) - sleep 1 - (curl -s 'http://[::1]:8080/Demo/Hello/main' | diff tests/hello.html -) || (kill `cat $(TESTPID)`; echo "Test 'Hello' failed"; /bin/false) - (curl -s 'http://[::1]:8080/Demo/Crud1/create?A=1&B=2&C=3&D=4' | diff tests/crud1.html -) || (kill `cat $(TESTPID)`; echo "Test 'Crud1' failed"; /bin/false) - kill `cat $(TESTPID)` + if (ifconfig lo | grep -q inet6); \ + then \ + echo "Running IPv6 tests."; \ + rm -f $(TESTDB); \ + sqlite3 $(TESTDB) < demo/demo.sql; \ + demo/demo.exe -A ::1 & echo $$! > $(TESTPID); \ + sleep 1; \ + (curl -s 'http://[::1]:8080/Demo/Hello/main' | diff tests/hello.html -) || (kill `cat $(TESTPID)`; echo "Test 'Hello' failed"; /bin/false); \ + (curl -s 'http://[::1]:8080/Demo/Crud1/create?A=1&B=2&C=3&D=4' | diff tests/crud1.html -) || (kill `cat $(TESTPID)`; echo "Test 'Crud1' failed"; /bin/false); \ + kill `cat $(TESTPID)`; \ + else \ + echo "Skipped IPv6 tests."; \ + fi echo Tests succeeded. -- cgit v1.2.3 From 8c7115af98f01fc6bc3683f20be252412cb75d1c Mon Sep 17 00:00:00 2001 From: Marvin Sielenkemper Date: Sat, 17 Sep 2016 09:40:56 +0200 Subject: Remove accidentally commited unused includes which do not exist on MacOS --- src/c/http.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/c/http.c b/src/c/http.c index b3ada18a..2c409c04 100644 --- a/src/c/http.c +++ b/src/c/http.c @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include -- cgit v1.2.3 From 62ac943afa64fd4fc16f47c2f23fd90f7c5fff81 Mon Sep 17 00:00:00 2001 From: Marvin Sielenkemper Date: Sat, 17 Sep 2016 12:42:00 +0200 Subject: Try adding an IPv6 address to interface lo --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index df4e4abc..32f1e3ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,5 +24,6 @@ before_install: - if command -v brew &>/dev/null; then brew install libtool; fi - if command -v brew &>/dev/null; then brew install openssl mlton; fi - if command -v brew &>/dev/null; then export CONFIGURE_ARGS="--with-openssl=/usr/local/opt/openssl"; fi + - if command -v ifconfig &>/dev/null; then sudo ifconfig lo add ::1; fi script: ./autogen.sh && ./configure $CONFIGURE_ARGS && make && make test -- cgit v1.2.3 From 0d9b72d8806df969a7a4f3dbf0813eb68c52fae0 Mon Sep 17 00:00:00 2001 From: Marvin Sielenkemper Date: Sat, 17 Sep 2016 12:44:57 +0200 Subject: Revert "Try adding an IPv6 address to interface lo" This reverts commit 62ac943afa64fd4fc16f47c2f23fd90f7c5fff81. --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 32f1e3ee..df4e4abc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,5 @@ before_install: - if command -v brew &>/dev/null; then brew install libtool; fi - if command -v brew &>/dev/null; then brew install openssl mlton; fi - if command -v brew &>/dev/null; then export CONFIGURE_ARGS="--with-openssl=/usr/local/opt/openssl"; fi - - if command -v ifconfig &>/dev/null; then sudo ifconfig lo add ::1; fi script: ./autogen.sh && ./configure $CONFIGURE_ARGS && make && make test -- cgit v1.2.3