PERFORCE change 196633 for review
Catalin Nicutar
cnicutar at FreeBSD.org
Sun Jul 24 14:17:53 UTC 2011
http://p4web.freebsd.org/@@196633?ac=10
Change 196633 by cnicutar at 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
More information about the p4-projects
mailing list