Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Jul 2011 14:17:52 GMT
From:      Catalin Nicutar <cnicutar@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 196633 for review
Message-ID:  <201107241417.p6OEHqPO056697@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@196633?ac=10

Change 196633 by cnicutar@cnicutar_cronos on 2011/07/24 14:17:31

	Add IPv6 support to UTO tests and cleanup.

Affected files ...

.. //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/long_uto.c#2 edit
.. //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/runtest.sh#2 edit
.. //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/send_uto.c#2 edit
.. //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/short_uto.c#2 edit
.. //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/test_utils.c#2 edit
.. //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/test_utils.h#2 edit

Differences ...

==== //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/long_uto.c#2 (text+ko) ====

@@ -1,7 +1,6 @@
 #include <sys/wait.h>
 
 #include <err.h>
-#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sysexits.h>
@@ -9,10 +8,6 @@
 
 #include "test_utils.h"
 
-#define CLIENT_ADDR	"192.0.2.2"
-#define SERVER_ADDR	"192.0.2.3"
-#define PORT		1296
-
 #define UTO		20*60		/* 20 minutes UTO. */
 #define DOWNTIME	5*60		/* 5 minutes of network downtime. */
 #define WAITTIME	7*60		/* Waiting 7 minutes. */
@@ -26,12 +21,21 @@
  * The test passes if the server exits normally (the second write succeeds).
  */
 int
-main(void)
+main(int argc, char *argv[])
 {
 	int status;
+	char *caddr, *saddr, *port;
 	pid_t server;
 	pid_t client;
 
+	if (argc != 4)
+		errx(EX_USAGE, "Usage: %s client_addr server_addr port",
+		    argv[0]);
+
+	caddr = argv[1];
+	saddr = argv[2];
+	port = argv[3];
+
 	if(getuid())
 		errx(EX_USAGE, "Only root may run this test");
 
@@ -41,8 +45,7 @@
 		err(EX_OSERR, "fork");
 		break;
 	case 0:
-		server_disconnect(SERVER_ADDR, PORT, CLIENT_ADDR, DOWNTIME,
-		    UTO, 1);
+		server_disconnect(saddr, port, caddr, DOWNTIME, UTO, 1);
 		exit(EX_OK);
 		break;
 	}
@@ -56,14 +59,14 @@
 		err(EX_OSERR, "fork");
 		break;
 	case 0:
-		client_generic(CLIENT_ADDR, SERVER_ADDR, PORT, 0, 1);
+		client_generic(caddr, saddr, port, 0, 1);
 		exit(EX_OK);
 		break;
 	}
 
 	sleep(WAITTIME);
 
-	/* Wait server. The test passes if the server exits normlly (which
+	/* Wait server. The test passes if the server exits normally (which
 	 * means the second write completed successfully).
 	 */
 	if (waitpid(server, &status, WNOHANG) <= 0)

==== //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/runtest.sh#2 (text+ko) ====

@@ -10,41 +10,46 @@
 # Create two loopback interfaces and assign example addresses
 lo_up()
 {
+	# Just in case they are still around
 	lo_down
 
         ifconfig lo2 create
         ifconfig lo3 create
-
-        ifconfig lo2 192.0.2.2 netmask 255.255.255.255 mtu 1500 up
-        ifconfig lo3 192.0.2.3 netmask 255.255.255.255 mtu 1500 up
+	
+	if [ -n "$ipv6" ]
+	then
+		ifconfig lo2 inet6 "$1/128" mtu 1500 up
+		ifconfig lo3 inet6 "$2/128" mtu 1500 up
+	else
+        	ifconfig lo2 "$1/32" mtu 1500 up
+        	ifconfig lo3 "$2/32" mtu 1500 up
+	fi
 }
 
-# Run a test and display results
-runtest()
+needroot()
 {
-	no=$1			# Test number
-	name=$2			# Test name
-	needroot=$3		# Does the test need root ?
-
-	killall "$name" > /dev/null 2>&1
-
-	if [ -n "$needroot" ] && [ $(id -u) -ne 0 ]
+	if [ $(id -u) -ne 0 ]
 	then
 		echo "not ok $no - $name # Only root may run this test"
 		exit 1
 	fi
+}
+
+# Run a test and display results
+runtest()
+{
+	args=$1			# Test arguments
 
-	# Create loopback interfaces
-	lo_up > /dev/null 2>&1
+	killall "$bin" > /dev/null 2>&1
 
-	if ! make -f "Makefile.${name}" > /dev/null 2>&1
+	if ! make -f "Makefile.${bin}" > /dev/null 2>&1
 	then
 		echo "not ok $no - $name # make failed"
 		exit 1
 	fi
 	
 	# Finally run the test
-	if ./$name > /dev/null 2>&1
+	if ./$bin  > /dev/null 2>&1 $args
 	then
 		echo "ok $no - $name"
 	else
@@ -53,12 +58,58 @@
 	lo_down > /dev/null 2>&1
 }
 
+test_with_loopback()
+{
+	lo1=$1
+	lo2=$2
 
+	# Make sure we run as root
+	needroot 
 
-case "$1" in
-	"1") runtest "$1" send_uto 	;;
-	"2") runtest "$1" short_uto 1 	;;
-	"3") runtest "$1" long_uto 1 	;;	
+	# Create loopback interfaces
+	lo_up $lo1 $lo2 > /dev/null 2>&1
+	
+	# Run the atual test
+	runtest "$lo1 $lo2 $PORT"
+
+	# Destroy loopback interfaces
+	lo_down > /dev/null 2>&1
+}
+
+PORT="1296"
+
+no=$1
+case "$no" in
+	"1")
+		name="Send UTO"
+		bin="send_uto"
+		addr="127.0.0.1"
+
+		runtest "$addr $PORT"
+	;;
+	"2")
+		name="short_uto"
+		bin="short_uto"
+		client="192.0.2.2"
+		server="192.0.2.3"
+
+		test_with_loopback $client $server
+	;;
+	"3")
+		name="long_uto"
+		bin="long_uto"
+		client="192.0.2.2"
+		server="192.0.2.3"
+
+		test_with_loopback $client $server
+	;;
+	"4")
+		name="send_uto_ipv6"
+		bin="send_uto"
+		addr="127.0.0.1"
+
+		runtest "$addr $PORT"
+	;;
 esac
 
 

==== //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/send_uto.c#2 (text+ko) ====

@@ -3,7 +3,6 @@
 #include <sys/wait.h>
 
 #include <err.h>
-#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sysexits.h>
@@ -12,9 +11,6 @@
 #include "test_utils.h"
 
 
-#define ADDR		"127.0.0.1"
-#define PORT		1296
-
 #define SERVER_UTO	1600
 #define CLIENT_UTO	1200
 #define WAITTIME	5
@@ -25,7 +21,7 @@
  * Send new UTO and tests again the received UTO.
  */
 static void
-server()
+server(char *addr, char *port)
 {
 	int listen_sock;
 	int sock;
@@ -35,7 +31,7 @@
 	int send_uto, recv_uto;
 
 	/* Bind and start listening. */
-	listen_sock = listen_socket(ADDR, PORT, SERVER_UTO, 1);
+	listen_sock = listen_uto(addr, port, SERVER_UTO, 1);
 
 	sock = accept(listen_sock, NULL, NULL);
 	if (sock < 0)
@@ -70,7 +66,7 @@
  * Exchanges data and tests the received value again.
  */
 static void
-client()
+client(char *addr, char *port)
 {
 	int sock;
 	static char buf[6000];
@@ -78,7 +74,7 @@
 	int send_uto, recv_uto;
 
 	/* Connect to the server, with the specified UTO values. */
-	sock = connect_socket(ADDR, ADDR, PORT, CLIENT_UTO, 1);
+	sock = connect_uto(addr, addr, port, CLIENT_UTO, 1);
 
 	/* See what the server sent. */
 	uto_get(sock, &send_uto, &recv_uto);
@@ -112,16 +108,23 @@
  */
 
 int
-main(void)
+main(int argc, char *argv[])
 {
 	int status;
+	char *addr, *port;
+
+	if (argc != 3)
+		errx(EX_USAGE, "Usage: %s address port", argv[0]);
+
+	addr = argv[1];
+	port = argv[2];
 
 	switch(fork()) {
 	case -1:
 		err(EX_OSERR, "fork");
 		break;
 	case 0:
-		server();
+		server(addr, port);
 		exit(EX_OK);
 		break;
 	}
@@ -134,7 +137,7 @@
 		err(EX_OSERR, "fork");
 		break;
 	case 0:
-		client();
+		client(addr, port);
 		exit(EX_OK);
 		break;
 	}

==== //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/short_uto.c#2 (text+ko) ====

@@ -1,7 +1,6 @@
 #include <sys/wait.h>
 
 #include <err.h>
-#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sysexits.h>
@@ -9,10 +8,6 @@
 
 #include "test_utils.h"
 
-#define CLIENT_ADDR	"192.0.2.2"
-#define SERVER_ADDR	"192.0.2.3"
-#define PORT		1296
-
 #define UTO		10		/* 10 seconds UTO. */
 #define DOWNTIME	20		/* 20 seconds of network downtime. */
 #define WAITTIME	40		/* Waiting 40 seconds. */
@@ -29,12 +24,21 @@
  * The test passes if the server exits abnormally with EX_IOERR.
  */
 int
-main(void)
+main(int argc, char *argv[])
 {
 	int status;
+	char *caddr, *saddr, *port;
 	pid_t server;
 	pid_t client;
 
+	if (argc != 4)
+		errx(EX_USAGE, "Usage: %s client_addr server_addr port",
+		    argv[0]);
+
+	caddr = argv[1];
+	saddr = argv[2];
+	port = argv[3];
+
 	/* Changing a network flag requires root. */
 	if(getuid())
 		errx(EX_USAGE, "Only root may run this test");
@@ -45,8 +49,7 @@
 		err(EX_OSERR, "fork");
 		break;
 	case 0:
-		server_disconnect(SERVER_ADDR, PORT, CLIENT_ADDR, DOWNTIME,
-		    UTO, 1);
+		server_disconnect(saddr, port, caddr, DOWNTIME, UTO, 1);
 		exit(EX_OK);
 		break;
 	}
@@ -60,12 +63,11 @@
 		err(EX_OSERR, "fork");
 		break;
 	case 0:
-		client_generic(CLIENT_ADDR, SERVER_ADDR, PORT, 0, 1);
+		client_generic(caddr, saddr, port, 0, 1);
 		exit(EX_OK);
 		break;
 	}
 
-	/* Allow connection to run. */
 	sleep(WAITTIME);
 
 	/*
@@ -77,6 +79,7 @@
 		exit(-1);
 	if (WIFEXITED(status) && WEXITSTATUS(status) == EX_IOERR)
 		exit(EX_OK);
-
+	
+	printf("Here\n");
 	return -1;
 }

==== //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/test_utils.c#2 (text+ko) ====

@@ -3,12 +3,10 @@
 
 #include <netinet/in.h>
 #include <netinet/tcp.h>
-#include <arpa/inet.h>
 
 #include <err.h>
 #include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
+#include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -21,33 +19,86 @@
 /*
  * Bind a socket to an address, using the SO_REUSEADDR socket option.
  */
-void
-tcp_bind(int s, char *addr, int port)
+int tcp_bind(char *addr, char *port)
 {
-	struct sockaddr_in sin;
-	int optval;
+	int s, rc, yes = 1;
+	struct addrinfo hints;
+	struct addrinfo *result, *rp;
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_canonname = NULL;
+	hints.ai_addr = NULL;
+	hints.ai_next = NULL;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_family = AF_UNSPEC;		/* Both v4 and v6.*/
+	hints.ai_flags = AI_PASSIVE;
+
+	/* Address lookup. */
+	rc = getaddrinfo(addr, port, &hints, &result);
+	if (rc)
+		return -1;
+
+	/* Loop until we can bind to something. */
+	for (rp = result; rp != NULL; rp = rp->ai_next) {
+		s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+		if (s == -1)
+			/* Try another result. */
+			continue;
 
-	sin.sin_port = htons(port);
-	sin.sin_family = AF_INET;
+		if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes,
+		    sizeof(yes))) {
+			close(s);
+			freeaddrinfo(result);
+			return -1;
+		}
 
-	if (NULL != addr && strlen(addr)) {
-		int rc;
-		rc = inet_pton(AF_INET, addr, &sin.sin_addr);
-		if (rc < 0)
-			err(EX_DATAERR, "inet_pton");
-		if (rc == 0)
-			errx(EX_DATAERR, "inet_pton can't parse `%s'", addr);
+		if (bind(s, rp->ai_addr, rp->ai_addrlen) == 0)
+			/* Return bound socket. */
+			break;
+		
+		/* Couldn't bind; try another result. */
+		close(s);
 	}
+	freeaddrinfo(result);
 
-	optval = 1;
-	if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)))
-		err(EX_UNAVAILABLE, "setsockopt");
+	return (rp == NULL) ? -1 : s;
+}
+
+
+int tcp_connect(int s, char *addr, char *port)
+{
+	int rc;
+	struct addrinfo hints;
+	struct addrinfo *result, *rp;
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_canonname = NULL;
+	hints.ai_addr = NULL;
+	hints.ai_next = NULL;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_family = AF_UNSPEC;		/* Both v4 and v6.*/
+
+	/* Look up address. */
+	rc = getaddrinfo(addr, port, &hints, &result);
+	if (rc)
+		return -1;
+
+	/* Search for a suitable combination. */
+	for (rp = result; rp != NULL; rp = rp->ai_next) {
+		if (connect(s, rp->ai_addr, rp->ai_addrlen) == 0)
+			/* Done connect, break. */
+			break;
+
+		/* Connect failed; trying next entry. */
+	}
+	freeaddrinfo(result);
 
-	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)))
-		err(EX_UNAVAILABLE, "bind");
+	return (rp == NULL) ? -1 : s;
 }
 
 
+
+
 /*
  * Set UTO values on a socket.
  */
@@ -84,16 +135,14 @@
  * Create a socket, set UTO values, bind it locally, start listening.
  */
 int
-listen_socket(char *listen_addr, int port, int send_uto, int recv_uto)
+listen_uto(char *laddr, char *port, int send_uto, int recv_uto)
 {
 	int s;
-
-	s = socket(AF_INET, SOCK_STREAM, 0);
-	if (s <= 0)
-		err(EX_OSERR, "socket");
-
+	
+	s = tcp_bind(laddr, port);
+	if (s < 0)
+		err(EX_UNAVAILABLE, "tcp_bind");
 	uto_set(s, send_uto, recv_uto);
-	tcp_bind(s, listen_addr, port);
 
 	if(listen(s, -1))
 		err(EX_UNAVAILABLE, "listen");
@@ -104,31 +153,26 @@
  * Create a socket, set UTO values, bind it locally and attempt to connect.
  */
 int
-connect_socket(char *local_addr, char *remote_addr, int remote_port,
-    int send_uto, int recv_uto)
+connect_uto(char *laddr, char *raddr, char *rport, int send_uto, int recv_uto)
 {
 	int s;
-	struct sockaddr_in sin;
-
-	s = socket(AF_INET, SOCK_STREAM, 0);
-	if (s <= 0)
-		err(EX_OSERR, "socket");
+	
+	s = tcp_bind(laddr, NULL);
+	if (s < 0)
+		err(EX_UNAVAILABLE, "tcp_bind");
 
 	uto_set(s, send_uto, recv_uto);
-	tcp_bind(s, local_addr, 0);
-
-	sin.sin_family = AF_INET;
-	sin.sin_port = htons(remote_port);
+	if (s != tcp_connect(s, raddr, rport))
+		err(EX_UNAVAILABLE, "tcp_connect");
 
-	if (inet_pton(AF_INET, remote_addr, &sin.sin_addr) <= 0)
-		err(EX_DATAERR, "inet_pton");
-
-	if (connect(s, (struct sockaddr *)&sin, sizeof(sin)))
-		err(EX_UNAVAILABLE, "connect");
-
 	return s;
 }
 
+int
+is_v6(char *addr)
+{
+	return strchr(addr, ':') != NULL;
+}
 
 /*
  * Simulate broken connectivity by setting the "blackhole" flag on a route;
@@ -139,7 +183,13 @@
 route_down(char *addr)
 {
 	static char cmd[256];
-	snprintf(cmd, sizeof(cmd), "route change %s -blackhole", addr);
+	
+	if (is_v6(addr))
+		snprintf(cmd, sizeof(cmd), "route change -inet6 %s -blackhole",
+		    addr);
+	else
+		snprintf(cmd, sizeof(cmd), "route change -inet %s -blackhole",
+		    addr);
 	system(cmd);
 }
 
@@ -150,7 +200,10 @@
 route_up(char *addr)
 {
 	static char cmd[256];
-	snprintf(cmd, sizeof(cmd), "route change %s", addr);
+	if (is_v6(addr))
+		snprintf(cmd, sizeof(cmd), "route change -inet6 %s", addr);
+	else
+		snprintf(cmd, sizeof(cmd), "route change %s", addr);
 	system(cmd);
 }
 
@@ -163,7 +216,7 @@
  * If the connection is dead, write(2) should trigger an EPIPE.
  */
 void
-server_disconnect(char *laddr, int lport, char *downaddr, int downtime,
+server_disconnect(char *laddr, char *lport, char *downaddr, int downtime,
     int send_uto, int recv_uto)
 {
 	int listen_sock;
@@ -172,7 +225,7 @@
 	ssize_t bytes;
 
 	/* Bind and start listening. */
-	listen_sock = listen_socket(laddr, lport, send_uto, recv_uto);
+	listen_sock = listen_uto(laddr, lport, send_uto, recv_uto);
 
 	sock = accept(listen_sock, NULL, NULL);
 	if (sock < 0)
@@ -202,14 +255,14 @@
  * Generic client that simply connects and tries to receive data.
  */
 void
-client_generic(char *laddr, char *raddr, int rport, int send_uto, int recv_uto)
+client_generic(char *laddr, char *raddr, char *rport, int send_uto, int recv_uto)
 {
 	int sock;
 	static char buf[6000];
 	ssize_t bytes;
 
 	/* Connect to the server, with the specified UTO values. */
-	sock = connect_socket(laddr, raddr, rport, send_uto, recv_uto);
+	sock = connect_uto(laddr, raddr, rport, send_uto, recv_uto);
 
 	bytes = recv(sock, &buf, sizeof(buf), MSG_WAITALL);
 	if (bytes < 0 || (unsigned) bytes < sizeof(buf))

==== //depot/projects/soc2011/cnicutar_tcputo_8/src/tools/regression/netinet/tcputo/test_utils.h#2 (text+ko) ====

@@ -5,17 +5,16 @@
 #define TCP_RCVUTO_TIMEOUT	0x100
 
 
-void tcp_bind(int s, char *addr, int port);
+int tcp_bind(char *addr, char *port);
 void uto_set(int s, int send_uto, int recv_uto);
 void uto_get(int s, int *send_uto, int *recv_uto);
-int listen_socket(char *listen_addr, int port, int send_uto, int recv_uto);
-int connect_socket(char *local_addr, char *remote_addr, int remote_port,
-    int send_uto, int recv_uto);
+int listen_uto(char *laddr, char *port, int send_uto, int recv_uto);
+int connect_uto(char *laddr, char *raddr, char *rport, int send_uto, int recv_uto);
 void route_down(char *addr);
 void route_up(char *addr);
-void server_disconnect(char *laddr, int lport, char *downaddr, int downtime,
+void server_disconnect(char *laddr, char *lport, char *downaddr, int downtime,
     int send_uto, int recv_uto);
-void client_generic(char *laddr, char *raddr, int rport,
+void client_generic(char *laddr, char *raddr, char *rport,
     int send_uto, int recv_uto);
 
 #endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107241417.p6OEHqPO056697>