[PATCH 2/2] netrate - network rate/rtt measurement utility

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


- From 1ecdeb7f48302a2ea8a37fd8aecd90081637e0dc Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@xxxxxxxxxx>
Date: Thu, 2 Oct 2008 17:26:05 -0500
Subject: [PATCH] consolidate into common

consolidated both rtt and transmit to use same socket setup function; added exchange code and daemon mode; removed --server and --receive; added versioning

Signed-off-by: Clark Williams <williams@xxxxxxxxxx>
- ---
 common.c   |   82 +++++++++++++++++++++++++++++++++
 main.c     |  146 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 netrate.h  |   28 +++++++++---
 receive.c  |   71 +-----------------------------
 rtt.c      |   51 +--------------------
 server.c   |   74 +------------------------------
 transmit.c |   50 +--------------------
 7 files changed, 237 insertions(+), 265 deletions(-)

diff --git a/common.c b/common.c
index 48cd4e9..8ed0590 100644
- --- a/common.c
+++ b/common.c
@@ -433,3 +433,85 @@ free_histogram(struct histogram *h)
 	free(h);
 }
 
+/*
+ ***********************************************************************
+ * socket stuff
+ ***********************************************************************
+ */
+
+int
+netrate_tx_socket(int protocol, int port, int request)
+{
+	int ret;
+	int sock;
+	int val;
+	char portstring[10];
+	struct addrinfo *ai, hints;
+	struct netrate_exchange ex;
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_flags = AI_CANONNAME;
+	hints.ai_family = AF_INET;
+	hints.ai_socktype = type;
+	hints.ai_protocol = protocol;
+	sprintf(portstring, "%d", port);
+
+	ret = getaddrinfo(hostname, portstring, &hints, &ai);
+	if (ret) {
+		fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
+		return -ret;
+	}
+
+	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+	if (sock < 0) {
+		perror("transmit socket()");
+		return -(errno);
+	}
+
+	dprintf("calling connect\n");
+	if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
+		perror("connect");
+		close(sock);
+		return -(errno);
+	}
+
+	freeaddrinfo(ai);
+
+	if (protocol == IPPROTO_TCP && nodelay == TRUE) {
+		/* set TCP_NODELAY */
+		dprintf("setting TCP_NODELAY\n");
+		val = 1;
+		if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &val, sizeof(val)) < 0) {
+			perror("setsockopt");
+			ret = -errno;
+			close(sock);
+			return ret;
+		}
+	}
+	memset(&ex, 0, sizeof(ex));
+	ex.major = MAJOR;
+	ex.minor = MINOR;
+	ex.request = request;
+	ex.size = size;
+	ret = write(sock, (void *) &ex, sizeof(ex));
+	if (ret < 0) {
+		fprintf(stderr, "Error sending exchange request: %s\n", strerror(errno));
+		ret = -errno;
+		close(sock);
+		return ret;
+	}
+	ret = read(sock, (void *) &ex, sizeof(ex));
+	if (ret < 0) {
+		fprintf(stderr, "Error reading exchange ack: %s\n", strerror(errno));
+		ret = -errno;
+		close(sock);
+		return ret;
+	}
+	if (ex.request != REQUEST_ACK) {
+		fprintf(stderr, "Exchange ack not valid: %x\n", ex.request);
+		ret = -errno;
+		close(sock);
+		return ret;
+	}
+	return sock;
+}
diff --git a/main.c b/main.c
index 838642c..a13f7f6 100644
- --- a/main.c
+++ b/main.c
@@ -54,10 +54,9 @@ char hostname[1024];		/* host to connect to */
 static void interrupt(int sig);
 
 static struct option long_options[] = {
- -	{"receive", 0, 0, RX},
 	{"transmit", 0, 0, TX},
- -	{"server", 0, 0, SERVER},
 	{"rtt", 0, 0, RTT},
+	{"daemon", 0, 0, DAEMON},
 	{"rate", 1, 0, RATE},
 	{"size", 1, 0, SIZE},
 	{"tcp", 0, 0, TCP},
@@ -75,7 +74,7 @@ static struct option long_options[] = {
 
 void usage(void)
 {
- -	fprintf(stderr, "usage: netrate {--transmit|--receive|--server|--rtt} [options]\n");
+	fprintf(stderr, "usage: netrate {--transmit|--rtt|--daemon} [options]\n");
 	fprintf(stderr, "   where options are:\n");
 	fprintf(stderr, "        --rate=<Inter-Packet Interval>\n");
 	fprintf(stderr, "        --size=<packet size>\n");
@@ -92,6 +91,126 @@ void usage(void)
 }
 
 
+int
+netrate_rx_socket(int protocol, int type)
+{
+	int ret;
+	int sock;
+	char portstring[10];
+	struct addrinfo hints, *ai;
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_flags = AI_PASSIVE;
+	hints.ai_family = AF_INET;
+	hints.ai_socktype = type;
+	hints.ai_protocol = protocol;
+	sprintf(portstring, "%d", port);
+
+	dprintf("calling getaddrinfo\n");
+	ret = getaddrinfo(NULL, portstring, &hints, &ai);
+	if (ret) {
+		fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
+		return -ret;
+	}
+
+	dprintf("calling socket\n");
+	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+	if (sock < 0) {
+		perror ("receive socket()");
+		return -(errno);
+	}
+
+	dprintf("calling accept\n");
+	ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
+	if (ret < 0) {
+		perror("bind");
+		return -(errno);
+	}
+
+	if (protocol == IPPROTO_TCP) {
+		dprintf("calling listen\n");
+		ret = listen(sock, SOMAXCONN);
+		if (ret < 0) {
+			perror("listen()");
+			return -(errno);
+		}
+	}
+	return sock;
+}
+
+int
+netrate_daemon(void)
+{
+	int ret;
+	int servsock, sock;
+	socklen_t clientlen;
+	struct sockaddr_in client;
+	struct netrate_exchange ex, ack;
+
+	dprintf("netrate_daemon: starting\n");
+	servsock = netrate_rx_socket(protocol, type);
+	
+	if (protocol == IPPROTO_TCP) {
+		dprintf("calling accept\n");
+		sock = accept(servsock, (struct sockaddr *)&client, &clientlen);
+		if (sock < 0) {
+			fprintf(stderr, "error from accept: %s\n", strerror(errno));
+			close(servsock);
+			exit(-1);
+		}
+		close(servsock);
+		dprintf("out of accept\n");
+	}
+	else
+		sock = servsock;
+
+	dprintf("calling read for exchange\n");
+	ret = read(sock, &ex, sizeof(ex));
+	if (ret < 0) {
+		fprintf(stderr, "error reading exchange message: %s\n", strerror(errno));
+		close(sock);
+		exit(-2);
+	}
+	dprintf("got exchange: major: %d, minor: %d, request: %d, size: %d\n",
+		ex.major, ex.minor, ex.request, ex.size);
+
+	if (ex.major != MAJOR || ex.minor != MINOR) {
+		fprintf(stderr, "protocol mismatch us: (%d, %d), them:(%d, %d)\n",
+			MAJOR, MINOR, ex.major, ex.minor);
+		close(sock);
+		exit(-3);
+	}
+
+	size = ex.size;
+
+	ack = ex;
+	ack.request = REQUEST_ACK;
+
+	dprintf("ACK'ing exchange\n");
+	ret = write(sock, &ack, sizeof(ack));
+	if (ret < 0) {
+		fprintf(stderr, "error acknowledging exchange request: %s\n",
+			strerror(errno));
+		close(sock);
+		exit(-4);
+	}
+
+	switch (ex.request) {
+
+	case SERVER:
+		dprintf("calling netrate_server()\n");
+		return netrate_server(sock);
+		
+	case RX:
+		dprintf("calling netrate_receive()\n");
+		return netrate_receive(sock);
+	}
+	fprintf(stderr, "Unknown exchange request: %d\n", ex.request);
+	close(sock);
+	return -1;
+}
+
+
 int main(int argc, char **argv)
 {
 	int ret;
@@ -107,18 +226,14 @@ int main(int argc, char **argv)
 			break;
 
 		switch(opt) {
- -		case RX:
- -			role = RX;
- -			dprintf("role == RX\n");
+		case DAEMON:
+			role = DAEMON;
+			dprintf("role == DAEMON\n");
 			break;
 		case TX:
 			role = TX;
 			dprintf("role == TX\n");
 			break;
- -		case SERVER:
- -			role = SERVER;
- -			dprintf("role == SERVER\n");
- -			break;
 		case RTT:
 			role = RTT;
 			dprintf("role == RTT\n");
@@ -193,8 +308,8 @@ int main(int argc, char **argv)
 		}
 	}
 	if (role == 0) {
- -		fprintf(stderr, "Must specifiy either --transmit or "
- -			"--receive options!\n");
+		fprintf(stderr, "Must specifiy either --transmit, --daemon or "
+			"--rtt options!\n");
 		exit(-1);
 	}
 
@@ -218,11 +333,8 @@ int main(int argc, char **argv)
 	case TX:
 		exit_val = netrate_transmit();
 		break;
- -	case RX:
- -		exit_val = netrate_receive();
- -		break;
- -	case SERVER:
- -		exit_val = netrate_server();
+	case DAEMON:
+		exit_val = netrate_daemon();
 		break;
 	case RTT:
 		exit_val = netrate_rtt();
diff --git a/netrate.h b/netrate.h
index a0f79b5..c2aaba8 100644
- --- a/netrate.h
+++ b/netrate.h
@@ -22,12 +22,18 @@
 #ifndef __NETRATE_H__
 #define __NETRATE_H__
 
+#define MAJOR 0
+#define MINOR 3
+
 #define TRUE  1
 #define FALSE 0
 
- -enum optvals {RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, 
- -	      MULTI, PORT, HOST, DEBUG, HELP,
- -	      SERVER, RTT, NODELAY, HISTOGRAM};
+enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, 
+	       MULTI, PORT, HOST, DEBUG, HELP, DAEMON,
+	       SERVER, RTT, NODELAY, HISTOGRAM,
+	       NUM_OPT_VALS,
+};
+
 
 #define NS_PER_SEC	1000000000
 #define US_PER_SEC	1000000
@@ -48,6 +54,16 @@ enum optvals {RX=1, TX, RATE, SIZE, TCP, UDP, SCTP,
 #define MAX_BUF_SIZE	8192
 #define NETRATE_MSG_DATA 0xa5
 
+#include <linux/types.h>
+struct netrate_exchange {
+	__u16 major;
+	__u16 minor;
+	__u16 request;
+	__u16 size;
+};	
+
+#define REQUEST_ACK	0xffff
+
 struct netrate_message {
 	unsigned long msg_len;	/* message length (including header) */
 	unsigned long msg_seq;	/* sequence number */
@@ -55,7 +71,6 @@ struct netrate_message {
 	char msg_data[]; /* body of message */
 };
 
- -
 extern int protocol;
 extern int type;
 extern int nodelay;
@@ -70,9 +85,10 @@ extern int interrupted;
 extern jmp_buf jmpbuf;
 
 int netrate_transmit(void);
- -int netrate_receive(void);
+int netrate_receive(int sock);
 int netrate_rtt(void);
- -int netrate_server(void);
+int netrate_server(int sock);
+int netrate_tx_socket(int protocol, int port, int request);
 void stop_execution(void);
 void dprintf(char *, ...);
 
diff --git a/receive.c b/receive.c
index ac145d5..b9a255a 100644
- --- a/receive.c
+++ b/receive.c
@@ -36,60 +36,13 @@
  
 static struct statistics *stats;
 
- -static int
- -netrate_rx_socket(int protocol, int port, int multicast)
- -{
- -	int ret;
- -	int sock;
- -	char portstring[10];
- -	struct addrinfo hints, *ai;
- -
- -	memset(&hints, 0, sizeof(hints));
- -	hints.ai_flags = AI_PASSIVE;
- -	hints.ai_family = AF_INET;
- -	hints.ai_socktype = type;
- -	hints.ai_protocol = protocol;
- -	sprintf(portstring, "%d", port);
- -
- -	ret = getaddrinfo(NULL, portstring, &hints, &ai);
- -	if (ret) {
- -		fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
- -		return -ret;
- -	}
- -
- -	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- -	if (sock < 0) {
- -		perror ("receive socket()");
- -		return -(errno);
- -	}
- -
- -	ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
- -	if (ret < 0) {
- -		perror("bind");
- -		return -(errno);
- -	}
- -
- -	if (protocol == IPPROTO_TCP) {
- -		ret = listen(sock, SOMAXCONN);
- -		if (ret < 0) {
- -			perror("listen()");
- -			return -(errno);
- -		}
- -	}
- -	return sock;
- -}
- -
- -
 /*
  * main receiver routine
  */
 int
- -netrate_receive(void)
+netrate_receive(int consock)
 {
 	int ret;
- -	int servsock, consock;
- -	socklen_t socklen;
- -	struct sockaddr_in client;
 	void *ptr;
 	struct netrate_message *msg;
 	long status;
@@ -101,28 +54,6 @@ netrate_receive(void)
 	/* set up our ring buffers */
 	r = setup_ring_buffers(10, bufsize);
 
- -	/* setup a socket */
- -	servsock = netrate_rx_socket(protocol, port, multicast);
- -	if (servsock < 0) {
- -		perror("setting up recieve socket");
- -		return servsock;
- -	}
- -
- -	/* if we're doing TCP, call accept */
- -	if (protocol == IPPROTO_TCP) {
- -		dprintf("calling accept\n");
- -		consock = accept(servsock, (struct sockaddr *)&client, &socklen);
- -		if (consock < 0) {
- -			perror("accept");
- -			close(servsock);
- -			return consock;
- -		}
- -		close(servsock);
- -		dprintf("connection started\n");
- -	}
- -	else {
- -		consock = servsock;
- -	}
 
 	/* allocate statistics space */
 	stats = setup_statistics(MSEC);
diff --git a/rtt.c b/rtt.c
index 067d282..264a9a6 100644
- --- a/rtt.c
+++ b/rtt.c
@@ -44,54 +44,6 @@ static int stop_running = FALSE;
 
 static struct statistics *stats;
 
- -static int
- -setup_socket(int protocol, int port, int multicast)
- -{
- -	int ret;	
- -	int val;
- -	char portstring[10];
- -	struct addrinfo hints, *ai;
- -
- -	memset(&hints, 0, sizeof(hints));
- -	hints.ai_flags = AI_CANONNAME;
- -	hints.ai_family = AF_INET;
- -	hints.ai_socktype = type;
- -	hints.ai_protocol = protocol;
- -	sprintf(portstring, "%d", port);
- -	       
- -	ret = getaddrinfo(hostname, portstring, &hints, &ai);
- -	if (ret) {
- -		fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
- -		return -ret;
- -	}
- -
- -	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- -	if (sock < 0) {
- -		perror("transmit socket()");
- -		return -(errno);
- -	}
- -
- -	dprintf("calling connect\n");
- -	if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
- -		perror("connect");
- -		close(sock);
- -		return -(errno);
- -	}
- -		
- -	freeaddrinfo(ai);
- -
- -	if (protocol == IPPROTO_TCP && nodelay == TRUE) {
- -		/* set TCP_NODELAY */
- -		dprintf("setting TCP_NODELAY\n");
- -		val = 1;
- -		if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &val, sizeof(val)) < 0) {
- -			perror("setsockopt");
- -			close(sock);
- -			return -(errno);
- -		}
- -	}
- -	return sock;
- -}
 
 static void
 setup_buffers(struct ring_buffer **txring, struct ring_buffer **rxring)
@@ -221,14 +173,13 @@ int
 netrate_rtt(void)
 {
 	int ret;
- -	int sock;
 	long val;
 	struct netrate_message *msg;
 	struct timespec ts;
 	pthread_t thread_id;
 
 	dprintf("setting up transmit socket\n");
- -	sock = setup_socket(protocol, port, multicast);
+	sock = netrate_tx_socket(protocol, port, SERVER);
 	if (sock < 0) {
 		perror("transmit socket");
 		return -(errno);
diff --git a/server.c b/server.c
index 8264b4e..9d205ba 100644
- --- a/server.c
+++ b/server.c
@@ -34,61 +34,14 @@ static int bufsize;
 
 #define RING_SIZE 10
 
- -static int
- -netrate_rx_socket(int protocol, int port, int multicast)
- -{
- -	int ret;
- -	int sock;
- -	char portstring[10];
- -	struct addrinfo hints, *ai;
- -
- -	memset(&hints, 0, sizeof(hints));
- -	hints.ai_flags = AI_PASSIVE;
- -	hints.ai_family = AF_INET;
- -	hints.ai_socktype = type;
- -	hints.ai_protocol = protocol;
- -	sprintf(portstring, "%d", port);
- -	       
- -	ret = getaddrinfo(NULL, portstring, &hints, &ai);
- -	if (ret) {
- -		fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
- -		return -ret;
- -	}
- -
- -	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- -	if (sock < 0) {
- -		perror ("receive socket()");
- -		return -(errno);
- -	}
- -
- -	ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
- -	if (ret < 0) {
- -		perror("bind");
- -		return -(errno);
- -	}
- -
- -	freeaddrinfo(ai);
- -
- -	if (protocol == IPPROTO_TCP) {
- -		ret = listen(sock, SOMAXCONN);
- -		if (ret < 0) {
- -			perror("listen()");
- -			return -(errno);
- -		}
- -	}
- -	return sock;
- -}
 
 /*
  * receive netrate messages and return them as quickly as possible
  */
 int
- -netrate_server(void)
+netrate_server(int consock)
 {
 	int ret;
- -	int servsock, consock;
- -	socklen_t socklen;
- -	struct sockaddr_in client;
 	unsigned long packets = 0;
 	struct ring_buffer *r;
 	
@@ -97,31 +50,6 @@ netrate_server(void)
 	/* setup receive ring */
 	r = setup_ring_buffers(RING_SIZE, bufsize);
 
- -	/* setup a socket */
- -	servsock = netrate_rx_socket(protocol, port, multicast);
- -	if (servsock < 0) {
- -		perror("setting up recieve socket");
- -		free_ring_buffers(r);
- -		return servsock;
- -	}
- -
- -	/* if we're doing TCP, call accept */
- -	if (protocol == IPPROTO_TCP) {
- -		dprintf("calling accept\n");
- -		consock = accept(servsock, (struct sockaddr *)&client, &socklen);
- -		if (consock < 0) {
- -			perror("accept");
- -			close(servsock);
- -			free_ring_buffers(r);
- -			return consock;
- -		}
- -		close(servsock);
- -		dprintf("connection started\n");
- -	}
- -	else {
- -		consock = servsock;
- -	}
- -
 	dprintf("entering server loop\n");
 
 	/* save our bailout point for SIGINT */
diff --git a/transmit.c b/transmit.c
index c134916..5e09bf6 100644
- --- a/transmit.c
+++ b/transmit.c
@@ -31,54 +31,6 @@
 
 static unsigned long long sequence = 0;
 
- -static int
- -netrate_tx_socket(int protocol, int port, int multicast)
- -{
- -	int ret;
- -	int sock;
- -	int val;
- -	char portstring[10];
- -	struct addrinfo *ai, hints;
- -
- -	memset(&hints, 0, sizeof(hints));
- -	hints.ai_flags = AI_CANONNAME;
- -	hints.ai_family = AF_INET;
- -	hints.ai_socktype = type;
- -	hints.ai_protocol = protocol;
- -	sprintf(portstring, "%d", port);
- -
- -	ret = getaddrinfo(hostname, portstring, &hints, &ai);
- -	if (ret) {
- -		fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
- -		return -ret;
- -	}
- -	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- -	if (sock < 0) {
- -		perror("transmit socket()");
- -		return -(errno);
- -	}
- -	
- -	dprintf("calling connect\n");
- -	if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
- -		perror("connect");
- -		close(sock);
- -		return -(errno);
- -	}
- -	freeaddrinfo(ai);
- -
- -	if (protocol == IPPROTO_TCP) {
- -		/* set TCP_NODELAY */
- -		dprintf("setting TCP_NODELAY\n");
- -		val = 1;
- -		if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &val, sizeof(val)) < 0) {
- -			perror("setsockopt");
- -			close(sock);
- -			return -(errno);
- -		}
- -	}
- -	return sock;
- -}
- -
 int
 netrate_transmit(void)
 {
@@ -94,7 +46,7 @@ netrate_transmit(void)
 	r = setup_ring_buffers(10, bufsize);
 
 	dprintf("setting up transmit socket\n");
- -	sock = netrate_tx_socket(protocol, port, multicast);
+	sock = netrate_tx_socket(protocol, port, RX);
 	if (sock < 0) {
 		perror("transmit socket");
 		return -(errno);
- -- 
1.6.0.1


- From ed795f7a0c363b7ba2a05c487b5d7e12e80e9762 Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@xxxxxxxxxx>
Date: Wed, 8 Oct 2008 15:08:33 -0500
Subject: [PATCH] make use wildcards

modified Makefile targets to use wildcard builtin

Signed-off-by: Clark Williams <williams@xxxxxxxxxx>
- ---
 Makefile |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 7a5c25e..e9ad854 100644
- --- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 CC	:= gcc
 CFLAGS	:= -g -O2 -Wall
- -SRC	:= main.c receive.c transmit.c rtt.c server.c common.c
- -HDR	:= netrate.h networking.h
+SRC	:= $(wildcard *.c)
+HDR	:= $(wildcard *.h)
 OBJ	:= $(subst .c,.o,$(SRC))
 
 netrate:	$(OBJ)
- -- 
1.6.0.1


- From c212089b4f3e751e7b5cb47a2a207d61af6f07a3 Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@xxxxxxxxxx>
Date: Wed, 8 Oct 2008 15:12:10 -0500
Subject: [PATCH] socket functions to common

moved tx and rx socket setup functions into common.c; changed to u64 type (from unsigned long long)

Signed-off-by: Clark Williams <williams@xxxxxxxxxx>
- ---
 common.c |   98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 87 insertions(+), 11 deletions(-)

diff --git a/common.c b/common.c
index 8ed0590..a990e20 100644
- --- a/common.c
+++ b/common.c
@@ -42,26 +42,26 @@
 /*
  * turn  a struct timespec into a long long of nanoseconds
  */
- -unsigned long long
+u64
 ts2ns(struct timespec *t)
 {
 	return ((t->tv_sec * NS_PER_SEC) + t->tv_nsec);
 }
 
- -unsigned long
+u64
 ts2us(struct timespec *t)
 {
 	return (t->tv_sec * US_PER_SEC) + NS_TO_US(t->tv_nsec);
 }
 
- -unsigned long
+u64
 ts2ms(struct timespec *t)
 {
 	return (t->tv_sec * MS_PER_SEC) + NS_TO_MS(t->tv_nsec);
 }
 
 static unsigned long
- -ns2x(unsigned long ns, int units)
+ns2x(u64 ns, int units)
 {
 	switch(units) {
 	case MSEC:
@@ -76,7 +76,7 @@ ns2x(unsigned long ns, int units)
 	return 0;
 }
 
- -unsigned long
+u64
 ts2x(struct timespec *ts, int units)
 {
 	if (ts == NULL) {
@@ -120,7 +120,7 @@ tsnormalize(struct timespec *ts)
 }
 
 void
- -tsadd(struct timespec *ts, unsigned long ns)
+tsadd(struct timespec *ts, u64 ns)
 {
 	ts->tv_nsec += ns;
 	tsnormalize(ts);
@@ -302,11 +302,29 @@ update_statistics_time (struct statistics *s,
 		s->end = *end;
 }
 		
+void
+check_delta(struct statistics *s, struct timespec *delta)
+{
+	u64 val;
+	if (delta == NULL) {
+		fprintf(stderr, "Invalid timespec pointer!\n");
+		exit(-2);
+	}
+
+	val = ts2ns(delta);
+	if (breakon && val > breakon) {
+		fprintf(stderr, "breakon threshold exceeded!"
+			" sample: %lu, value: %luns\n", 
+			(unsigned long)s->samples, (unsigned long) val);
+		exit(-1);
+	}
+}
+
 /* note: raw values are kept in nanoseconds */
 void
 update_statistics_data (struct statistics *s, struct timespec *tsdelta)
 {
- -	unsigned long long val;
+	u64 val;
 
 	if (s == NULL) {
 		fprintf(stderr, "Invalid statistics structure!\n");
@@ -344,13 +362,23 @@ print_statistics(struct statistics *s)
 		       ns2x(runlen.tv_nsec, s->units), suffix);
 	}
 	printf("Run Statistics:\n");
- -	printf("Number of Samples: %lu\n", s->samples);
+	printf("Number of Samples: %lu\n", (unsigned long) s->samples);
 	printf("Minumum:           %lu%s\n", ns2x(s->min, s->units), suffix);
 	printf("Maximum:           %lu%s\n", ns2x(s->max, s->units), suffix);
 	printf("Average:           %lu%s\n", 
 	       ns2x(s->accum / s->samples, s->units), suffix);
 }
 
+int
+missed_sequence(struct statistics *s, int expected, int got)
+{
+	s->missed_sequence++;
+	if (expected < got)
+		return got+1;
+	return expected;
+}
+
+
 void
 free_statistics(struct statistics *s)
 {
@@ -367,7 +395,7 @@ struct histogram *
 setup_histogram (int units, int nbuckets, int bucketwidth, int base)
 {
 	struct histogram *h;
- -	int hsize = sizeof(struct histogram) + (nbuckets * sizeof(unsigned long)); 
+	int hsize = sizeof(struct histogram) + (nbuckets * sizeof(u64)); 
 
 	h = malloc(hsize);
 	if (h == NULL) {
@@ -385,7 +413,7 @@ setup_histogram (int units, int nbuckets, int bucketwidth, int base)
 void
 histogram_record(struct histogram *h, struct timespec *ts)
 {
- -	unsigned long long val;
+	u64 val;
 
 	if (h == NULL) {
 		fprintf(stderr, "invalid histogram structure!\n");
@@ -423,7 +451,8 @@ histogram_print(struct histogram *h)
 	printf("Histogram (%d  %d%s buckets)\n",
 	       h->nbuckets, h->bucketwidth, suffix);
 	for (i = 0; i < h->nbuckets; i++)
- -		printf("%4.4d%s: %lu\n", i*h->bucketwidth, suffix, h->bucket[i]);
+		printf("%4.4d%s: %lu\n", i*h->bucketwidth, suffix, 
+		       (unsigned long)h->bucket[i]);
 
 }
 
@@ -515,3 +544,50 @@ netrate_tx_socket(int protocol, int port, int request)
 	}
 	return sock;
 }
+
+int
+netrate_rx_socket(int protocol, int type)
+{
+	int ret;
+	int sock;
+	char portstring[10];
+	struct addrinfo hints, *ai;
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_flags = AI_PASSIVE;
+	hints.ai_family = AF_INET;
+	hints.ai_socktype = type;
+	hints.ai_protocol = protocol;
+	sprintf(portstring, "%d", port);
+
+	dprintf("calling getaddrinfo\n");
+	ret = getaddrinfo(NULL, portstring, &hints, &ai);
+	if (ret) {
+		fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
+		return -ret;
+	}
+
+	dprintf("calling socket\n");
+	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+	if (sock < 0) {
+		perror ("receive socket()");
+		return -(errno);
+	}
+
+	dprintf("calling accept\n");
+	ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
+	if (ret < 0) {
+		perror("bind");
+		return -(errno);
+	}
+
+	if (protocol == IPPROTO_TCP) {
+		dprintf("calling listen\n");
+		ret = listen(sock, SOMAXCONN);
+		if (ret < 0) {
+			perror("listen()");
+			return -(errno);
+		}
+	}
+	return sock;
+}
- -- 
1.6.0.1


- From fa8721403c9e3111ae236139414062868642514d Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@xxxxxxxxxx>
Date: Wed, 8 Oct 2008 15:12:53 -0500
Subject: [PATCH] add net exchange

removed netrate_rx_socket; added function exchange

Signed-off-by: Clark Williams <williams@xxxxxxxxxx>
- ---
 main.c |  130 ++++++++++++++++++++++++++++-----------------------------------
 1 files changed, 58 insertions(+), 72 deletions(-)

diff --git a/main.c b/main.c
index a13f7f6..2ee5ad3 100644
- --- a/main.c
+++ b/main.c
@@ -42,6 +42,7 @@ int type	= SOCK_STREAM;  /* type of socket */
 int nodelay	= FALSE;	/* use TCP_NODELAY for TCP sockets */
 int role 	= 0;		/* should be either TX or RX */
 int rate 	= DEF_TX_RATE;	/* transmit packet rate in nanoseconds */
+u64 breakon	= 0;            /* stop if this threshold exceeded */
 int size 	= DEF_MSG_SIZE;	/* size of message */
 int port 	= DEF_PORT;	/* tx/rx port to use */
 int multicast 	= FALSE;	/* are we multicasting? */
@@ -69,6 +70,7 @@ static struct option long_options[] = {
 	{"help", 0, 0, HELP},
 	{"nodelay", 0, 0, NODELAY},
 	{"histogram", 0, 0, HISTOGRAM},
+	{"breakon", 1, 0, BREAKON},
 	{0, 0, 0, 0},
 };
 
@@ -91,52 +93,6 @@ void usage(void)
 }
 
 
- -int
- -netrate_rx_socket(int protocol, int type)
- -{
- -	int ret;
- -	int sock;
- -	char portstring[10];
- -	struct addrinfo hints, *ai;
- -
- -	memset(&hints, 0, sizeof(hints));
- -	hints.ai_flags = AI_PASSIVE;
- -	hints.ai_family = AF_INET;
- -	hints.ai_socktype = type;
- -	hints.ai_protocol = protocol;
- -	sprintf(portstring, "%d", port);
- -
- -	dprintf("calling getaddrinfo\n");
- -	ret = getaddrinfo(NULL, portstring, &hints, &ai);
- -	if (ret) {
- -		fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
- -		return -ret;
- -	}
- -
- -	dprintf("calling socket\n");
- -	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- -	if (sock < 0) {
- -		perror ("receive socket()");
- -		return -(errno);
- -	}
- -
- -	dprintf("calling accept\n");
- -	ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
- -	if (ret < 0) {
- -		perror("bind");
- -		return -(errno);
- -	}
- -
- -	if (protocol == IPPROTO_TCP) {
- -		dprintf("calling listen\n");
- -		ret = listen(sock, SOMAXCONN);
- -		if (ret < 0) {
- -			perror("listen()");
- -			return -(errno);
- -		}
- -	}
- -	return sock;
- -}
 
 int
 netrate_daemon(void)
@@ -145,7 +101,7 @@ netrate_daemon(void)
 	int servsock, sock;
 	socklen_t clientlen;
 	struct sockaddr_in client;
- -	struct netrate_exchange ex, ack;
+	struct netrate_exchange ex;
 
 	dprintf("netrate_daemon: starting\n");
 	servsock = netrate_rx_socket(protocol, type);
@@ -183,18 +139,6 @@ netrate_daemon(void)
 
 	size = ex.size;
 
- -	ack = ex;
- -	ack.request = REQUEST_ACK;
- -
- -	dprintf("ACK'ing exchange\n");
- -	ret = write(sock, &ack, sizeof(ack));
- -	if (ret < 0) {
- -		fprintf(stderr, "error acknowledging exchange request: %s\n",
- -			strerror(errno));
- -		close(sock);
- -		exit(-4);
- -	}
- -
 	switch (ex.request) {
 
 	case SERVER:
@@ -211,6 +155,47 @@ netrate_daemon(void)
 }
 
 
+void
+netrate_sendack(int sock)
+{
+	int ret;
+	struct netrate_exchange ack;
+
+	memset(&ack, 0, sizeof(ack));
+	ack.major = MAJOR;
+	ack.minor = MINOR;
+	ack.request = REQUEST_ACK;
+
+	dprintf("ACK'ing exchange\n");
+	ret = write(sock, &ack, sizeof(ack));
+	if (ret < 0) {
+		fprintf(stderr, "error acknowledging exchange request: %s\n",
+			strerror(errno));
+		close(sock);
+		exit(-4);
+	}
+}
+	
+	
+u64
+adjustns(char *suffix, u64 val)
+{
+	u64 newval = val;
+	if (suffix) {
+		if (strcmp(suffix, "ms") == 0)
+			newval = MS_TO_NS(val);
+		else if (strcmp(suffix, "us") == 0)
+			newval = US_TO_NS(val);
+		else if (strcmp(suffix, "s"))
+			newval = val * NS_PER_SEC;
+		else {
+			fprintf(stderr, "unknown time suffix: %s\n", suffix);
+			exit(-1);
+		}
+	}
+	return newval;
+}
+
 int main(int argc, char **argv)
 {
 	int ret;
@@ -220,7 +205,7 @@ int main(int argc, char **argv)
 
 	strcpy(hostname, "localhost");
 	while (1) {
- -		opt = getopt_long(argc, argv, "rta:z:cdmp", 
+		opt = getopt_long(argc, argv, "rta:z:cdmpb:", 
 				  long_options, &idx);
 		if (opt == -1)
 			break;
@@ -240,23 +225,24 @@ int main(int argc, char **argv)
 			break;
 		case RATE:
 			rate = strtol(optarg, &endptr, 10);
- -			if (endptr) {
- -				if (strcmp(endptr, "ms") == 0)
- -					rate = MS_TO_NS(rate);
- -				else if (strcmp(endptr, "us") == 0)
- -					rate = US_TO_NS(rate);
- -				else if (strcmp(endptr, "s"))
- -					rate = rate * NS_PER_SEC;
- -				else {
- -					fprintf(stderr, "unknown time suffix: %s\n", endptr);
- -					exit(-1);
- -				}
- -			}
+			if (endptr)
+				rate = adjustns(endptr, rate);
 			/* default (no suffix) is milliseconds */
 			else
 				rate = MS_TO_NS(rate);
 			dprintf("rate set to %dms\n", NS_TO_MS(rate));
 			break;
+		case BREAKON:
+			breakon = strtol(optarg, &endptr, 10);
+			if (endptr)
+				breakon = adjustns(endptr, breakon);
+			else
+				breakon = MS_TO_NS(breakon);
+			dprintf("breakon set to %lums\n", 
+				(unsigned long) NS_TO_MS(breakon));
+			break;
+			
+
 		case SIZE:
 			size = strtol(optarg, NULL, 10);
 			dprintf("size set to %d\n", size);
- -- 
1.6.0.1


- From e5ce0e98fc81cbbfdb88cdd47902965b7d731d1b Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@xxxxxxxxxx>
Date: Wed, 8 Oct 2008 15:13:38 -0500
Subject: [PATCH] breakon and short typenames

added the BREAKON enumerated type and option to stop on a latency greater than X; changed to short typenames

Signed-off-by: Clark Williams <williams@xxxxxxxxxx>
- ---
 netrate.h |   50 ++++++++++++++++++++++++++++++--------------------
 1 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/netrate.h b/netrate.h
index c2aaba8..9f073dd 100644
- --- a/netrate.h
+++ b/netrate.h
@@ -30,7 +30,7 @@
 
 enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, 
 	       MULTI, PORT, HOST, DEBUG, HELP, DAEMON,
- -	       SERVER, RTT, NODELAY, HISTOGRAM,
+	       SERVER, RTT, NODELAY, HISTOGRAM, BREAKON,
 	       NUM_OPT_VALS,
 };
 
@@ -55,18 +55,22 @@ enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP,
 #define NETRATE_MSG_DATA 0xa5
 
 #include <linux/types.h>
+typedef __u16  u16;
+typedef __u32  u32;
+typedef __u64  u64;
+
 struct netrate_exchange {
- -	__u16 major;
- -	__u16 minor;
- -	__u16 request;
- -	__u16 size;
+	u16 major;
+	u16 minor;
+	u16 request;
+	u16 size;
 };	
 
 #define REQUEST_ACK	0xffff
 
 struct netrate_message {
- -	unsigned long msg_len;	/* message length (including header) */
- -	unsigned long msg_seq;	/* sequence number */
+	u64 msg_len;	/* message length (including header) */
+	u64 msg_seq;	/* sequence number */
 	struct timespec msg_ts; /* time message was sent */
 	char msg_data[]; /* body of message */
 };
@@ -76,6 +80,7 @@ extern int type;
 extern int nodelay;
 extern int role;
 extern int rate;
+extern u64 breakon;
 extern int size;
 extern int multicast;
 extern int port;
@@ -89,17 +94,19 @@ int netrate_receive(int sock);
 int netrate_rtt(void);
 int netrate_server(int sock);
 int netrate_tx_socket(int protocol, int port, int request);
+int netrate_rx_socket(int protocol, int type);
+void netrate_sendack(int sock);
 void stop_execution(void);
 void dprintf(char *, ...);
 
- -unsigned long long ts2ns(struct timespec *ts);
- -unsigned long ts2us(struct timespec *ts);
- -unsigned long ts2ms(struct timespec *ts);
+u64 ts2ns(struct timespec *ts);
+u64 ts2us(struct timespec *ts);
+u64 ts2ms(struct timespec *ts);
 void tsdelta(struct timespec *later, 
 		    struct timespec *earlier, 
 		    struct timespec *delta);
 void tsnormalize(struct timespec *ts);
- -void tsadd(struct timespec *ts, unsigned long ns);
+void tsadd(struct timespec *ts, u64 ns);
 
 
 struct ring_buffer {
@@ -123,12 +130,13 @@ enum units { SEC=1, MSEC, USEC, NSEC };
 struct statistics {
 	struct timespec start;
 	struct timespec end;
- -	unsigned long min;
- -	unsigned long max;
- -	unsigned long average;
- -	unsigned long long accum;
- -	unsigned long samples;
- -	unsigned int  units;
+	u64 min;
+	u64 max;
+	u64 average;
+	u64 accum;
+	u64 samples;
+	u32 units;
+	u32 missed_sequence;
 };
 
 
@@ -136,17 +144,19 @@ struct statistics *setup_statistics(int units);
 void update_statistics_data(struct statistics *s, struct timespec *tsdelta);
 void update_statistics_time(struct statistics *s, 
 			    struct timespec *start, struct timespec *end);
+void check_delta(struct statistics *s, struct timespec *delta);
 void print_statistics(struct statistics *s);
 void free_statistics(struct statistics *s);
+int missed_sequence(struct statistics *s, int expected, int got);
 
 struct histogram {
 	int units;
 	int base;
 	int nbuckets;
 	int bucketwidth;
- -	unsigned long underflow;
- -	unsigned long overflow;
- -	unsigned long bucket[];
+	u64 underflow;
+	u64 overflow;
+	u64 bucket[];
 };
 
 struct histogram *setup_histogram (int units, int nbuckets, 
- -- 
1.6.0.1


- From 761d49f846e1947d708c3b2053b2f048562485bd Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@xxxxxxxxxx>
Date: Tue, 21 Oct 2008 20:45:48 -0500
Subject: [PATCH] keep going on sequence mismatch

dont exit on sequence mismatch; added exchange code

Signed-off-by: Clark Williams <williams@xxxxxxxxxx>
- ---
 receive.c  |   27 +++++++++++++++++++--------
 rtt.c      |    2 +-
 server.c   |    5 ++++-
 transmit.c |    2 +-
 4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/receive.c b/receive.c
index b9a255a..798daff 100644
- --- a/receive.c
+++ b/receive.c
@@ -54,26 +54,36 @@ netrate_receive(int consock)
 	/* set up our ring buffers */
 	r = setup_ring_buffers(10, bufsize);
 
- -
 	/* allocate statistics space */
 	stats = setup_statistics(MSEC);
 
+	/* mark our start time */
+	status = clock_gettime(CLOCK_MONOTONIC, &current);
+	if (status < 0) {
+		fprintf(stderr, "error from clock_gettime: %s\n", 
+			strerror(abs(status)));
+		return (int) status;
+	}
+	update_statistics_time(stats, &current, NULL);
+
+	/* ack the request so the transmitter starts */
+	netrate_sendack(consock);
+
+	/* get a valid "last" time */
 	status = clock_gettime(CLOCK_MONOTONIC, &last);
 	if (status < 0) {
 		fprintf(stderr, "error from clock_gettime: %s\n", 
 			strerror(abs(status)));
 		return (int) status;
 	}
- -	update_statistics_time(stats, &last, NULL);
 
 	/* save our bailout point for SIGINT */
 	setjmp(jmpbuf);
- -
 	dprintf("entering receive loop\n");
 
 	/* loop until done */
 	while(!interrupted) {
- -		ptr = get_next_ring_buffer(r);
+		msg = ptr = get_next_ring_buffer(r);
 		ret = read_message(consock, ptr, bufsize);
 		if (ret <= 0)
 			break;
@@ -87,15 +97,16 @@ netrate_receive(int consock)
 		}
 		if (sequence++) {
 			tsdelta(&current, &last, &delta);
+			check_delta(stats, &delta);
 			update_statistics_data(stats, &delta);
 		}
- -		msg = ptr;
+		else
+			dprintf("skipped first packet\n");
 		if (msg->msg_seq != sequence) {
 			fprintf(stderr, "sequence number wrong!\n"
 				"    calculated: %lu, received: %lu\n", 
- -				sequence, msg->msg_seq);
- -			close(consock);
- -			break;
+				sequence, (unsigned long) msg->msg_seq);
+			sequence = missed_sequence(stats, sequence, msg->msg_seq);
 		}
 		last = current;
 	}
diff --git a/rtt.c b/rtt.c
index 264a9a6..5f9d052 100644
- --- a/rtt.c
+++ b/rtt.c
@@ -36,7 +36,7 @@ static struct ring_buffer *tx_ring;
 static struct ring_buffer *rx_ring;
 static int bufsize;
 
- -static unsigned long long sequence = 0;
+static u64 sequence = 0;
 
 static int sock = -1;
 
diff --git a/server.c b/server.c
index 9d205ba..f4c9508 100644
- --- a/server.c
+++ b/server.c
@@ -42,7 +42,7 @@ int
 netrate_server(int consock)
 {
 	int ret;
- -	unsigned long packets = 0;
+	u64 packets = 0;
 	struct ring_buffer *r;
 	
 	bufsize = sizeof(struct netrate_message) + size;
@@ -52,6 +52,9 @@ netrate_server(int consock)
 
 	dprintf("entering server loop\n");
 
+	/* send the ack to start the transmitter */
+	netrate_sendack(consock);
+
 	/* save our bailout point for SIGINT */
 	setjmp(jmpbuf);
 
diff --git a/transmit.c b/transmit.c
index 5e09bf6..f0db186 100644
- --- a/transmit.c
+++ b/transmit.c
@@ -29,7 +29,7 @@
 #include "networking.h"
 
 
- -static unsigned long long sequence = 0;
+static u64 sequence = 0;
 
 int
 netrate_transmit(void)
- -- 
1.6.0.1


- From e6e0454a1b8b7c57c1459c3498bf5bd8e37118a3 Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@xxxxxxxxxx>
Date: Tue, 21 Oct 2008 20:52:24 -0500
Subject: [PATCH] packet skip and connected UDP

added logic to put UDP socket in connected mode; added packet skip option
added versioning in the Makefile

Signed-off-by: Clark Williams <williams@xxxxxxxxxx>
- ---
 .gitignore |    1 +
 Makefile   |    7 +++++--
 main.c     |   41 +++++++++++++++++++++++++++++++++--------
 netrate.h  |   11 +++++++++--
 receive.c  |    9 +++++++--
 rtt.c      |    9 +++++++++
 server.c   |    9 +++++++--
 transmit.c |   10 ++++++++++
 8 files changed, 81 insertions(+), 16 deletions(-)

diff --git a/.gitignore b/.gitignore
index 2e01fe3..d056f27 100644
- --- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 *.o
 *~
 netrate
+*.bz2
diff --git a/Makefile b/Makefile
index e9ad854..d75f741 100644
- --- a/Makefile
+++ b/Makefile
@@ -3,6 +3,9 @@ CFLAGS	:= -g -O2 -Wall
 SRC	:= $(wildcard *.c)
 HDR	:= $(wildcard *.h)
 OBJ	:= $(subst .c,.o,$(SRC))
+MAJOR	:= $(shell awk '/MAJOR/ {print $$3}' netrate.h)
+MINOR	:= $(shell awk '/MINOR/ {print $$3}' netrate.h)
+VERSION	:= $(MAJOR).$(MINOR)
 
 netrate:	$(OBJ)
 	$(CC) $(CFLAGS) -o netrate $(OBJ) -lrt
@@ -15,5 +18,5 @@ clean:
 tarball:  clean
 	mkdir -p tmp/netrate
 	cp Makefile $(SRC) $(HDR) tmp/netrate
- -	(cd tmp && tar -cjvf netrate.tar.bz2 netrate)
- -	mv tmp/netrate.tar.bz2 .
+	(cd tmp && tar -cjvf netrate-$(VERSION).tar.bz2 netrate)
+	mv tmp/netrate-$(VERSION).tar.bz2 .
diff --git a/main.c b/main.c
index 2ee5ad3..0293a1b 100644
- --- a/main.c
+++ b/main.c
@@ -50,6 +50,7 @@ int debugging 	= FALSE;	/* Are we edbugging? */
 int interrupted = FALSE;	/* have we been interrupted? */
 jmp_buf jmpbuf;			/* bailout state for being interrupted */
 int histogram   = FALSE;	/* keep a histogram of time values */
+int skip	= 0;		/* number of packets to skip before measuring */
 char hostname[1024];		/* host to connect to */
 
 static void interrupt(int sig);
@@ -71,6 +72,7 @@ static struct option long_options[] = {
 	{"nodelay", 0, 0, NODELAY},
 	{"histogram", 0, 0, HISTOGRAM},
 	{"breakon", 1, 0, BREAKON},
+	{"skip", 1, 0, SKIP},
 	{0, 0, 0, 0},
 };
 
@@ -116,16 +118,35 @@ netrate_daemon(void)
 		}
 		close(servsock);
 		dprintf("out of accept\n");
+		dprintf("calling read for exchange\n");
+		ret = read(sock, &ex, sizeof(ex));
+		if (ret < 0) {
+			fprintf(stderr, "error reading exchange message: %s\n", strerror(errno));
+			close(sock);
+			exit(-2);
+		}
 	}
- -	else
- -		sock = servsock;
+	else {
+		struct sockaddr_in addr;
+		socklen_t addrlen;
 
- -	dprintf("calling read for exchange\n");
- -	ret = read(sock, &ex, sizeof(ex));
- -	if (ret < 0) {
- -		fprintf(stderr, "error reading exchange message: %s\n", strerror(errno));
- -		close(sock);
- -		exit(-2);
+		sock = servsock;
+		dprintf("Calling recvfrom for exchange\n");
+		ret = recvfrom(sock, &ex, sizeof(ex), 0, 
+			       (struct sockaddr *) &addr, 
+			       (socklen_t *) &addrlen);
+		if (ret == -1) {
+			fprintf(stderr, "error receiving exchange data: %s\n",
+				strerror(errno));
+			close(sock);
+			exit(-2);
+		}
+		if (connect(sock, (struct sockaddr *) &addr, addrlen) < 0) {
+			fprintf(stderr, "error connecting UDP socket: %s\n",
+				strerror(errno));
+			close(sock);
+			exit(-2);
+		}
 	}
 	dprintf("got exchange: major: %d, minor: %d, request: %d, size: %d\n",
 		ex.major, ex.minor, ex.request, ex.size);
@@ -287,6 +308,10 @@ int main(int argc, char **argv)
 			histogram = TRUE;
 			dprintf("histogram set to true\n");
 			break;
+		case SKIP:
+			skip = strtol(optarg, NULL, 10);
+			dprintf("packet skip set to %d\n", skip);
+			break;
 		case HELP:
 		default:
 			usage();
diff --git a/netrate.h b/netrate.h
index 9f073dd..8186dc4 100644
- --- a/netrate.h
+++ b/netrate.h
@@ -23,7 +23,7 @@
 #define __NETRATE_H__
 
 #define MAJOR 0
- -#define MINOR 3
+#define MINOR 4
 
 #define TRUE  1
 #define FALSE 0
@@ -31,7 +31,7 @@
 enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, 
 	       MULTI, PORT, HOST, DEBUG, HELP, DAEMON,
 	       SERVER, RTT, NODELAY, HISTOGRAM, BREAKON,
- -	       NUM_OPT_VALS,
+	       SKIP, NUM_OPT_VALS,
 };
 
 
@@ -54,6 +54,9 @@ enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP,
 #define MAX_BUF_SIZE	8192
 #define NETRATE_MSG_DATA 0xa5
 
+/* number of packets to skip before starting measurements */
+#define STEADY_STATE_DELAY 1
+
 #include <linux/types.h>
 typedef __u16  u16;
 typedef __u32  u32;
@@ -68,7 +71,10 @@ struct netrate_exchange {
 
 #define REQUEST_ACK	0xffff
 
+enum msg_types { MSG_DATA=1, MSG_EOF=0xffffffff};
+
 struct netrate_message {
+	u32 msg_type;
 	u64 msg_len;	/* message length (including header) */
 	u64 msg_seq;	/* sequence number */
 	struct timespec msg_ts; /* time message was sent */
@@ -85,6 +91,7 @@ extern int size;
 extern int multicast;
 extern int port;
 extern int histogram;
+extern int skip;
 extern char hostname[];
 extern int interrupted;
 extern jmp_buf jmpbuf;
diff --git a/receive.c b/receive.c
index 798daff..edadc02 100644
- --- a/receive.c
+++ b/receive.c
@@ -88,6 +88,10 @@ netrate_receive(int consock)
 		if (ret <= 0)
 			break;
 
+		/* bail out if the other end going away */
+		if (msg->msg_type == MSG_EOF)
+			break;
+
 		//dprintf(".");
 		status = clock_gettime(CLOCK_MONOTONIC, &current);
 		if (status < 0) {
@@ -95,13 +99,13 @@ netrate_receive(int consock)
 				strerror(abs(status)));
 			return (int) status;
 		}
- -		if (sequence++) {
+		if (sequence++ > skip) { 
 			tsdelta(&current, &last, &delta);
 			check_delta(stats, &delta);
 			update_statistics_data(stats, &delta);
 		}
 		else
- -			dprintf("skipped first packet\n");
+			dprintf("skipped packet %d\n", sequence);
 		if (msg->msg_seq != sequence) {
 			fprintf(stderr, "sequence number wrong!\n"
 				"    calculated: %lu, received: %lu\n", 
@@ -111,6 +115,7 @@ netrate_receive(int consock)
 		last = current;
 	}
 	dprintf("out of receive loop\n");
+	close(consock);
 	status = clock_gettime(CLOCK_MONOTONIC, &last);
 	if (status < 0) {
 		fprintf(stderr, "error from clock_gettime: %s\n", 
diff --git a/rtt.c b/rtt.c
index 5f9d052..d9b563e 100644
- --- a/rtt.c
+++ b/rtt.c
@@ -104,6 +104,7 @@ setup_message(int sequence, struct netrate_message *m)
 		fprintf(stderr, "invalid buffer pointer!\n");
 		exit(-1);
 	}
+	m->msg_type = MSG_DATA;
 	m->msg_seq = sequence;
 	m->msg_len = size;
 	ret = clock_gettime(CLOCK_MONOTONIC, &m->msg_ts);
@@ -229,6 +230,14 @@ netrate_rtt(void)
 		}	
 	}
 	dprintf("out of transmit loop (%lu messages transmitted)\n", sequence);
+	if (protocol == IPPROTO_UDP) {
+		msg = (struct netrate_message *) get_next_ring_buffer(tx_ring);
+		msg->msg_type = MSG_EOF;
+		msg->msg_seq = sequence;
+		msg->msg_len = size;
+		write_message(msg);
+	}
+	close(sock);
 	dprintf("freeing transmit ring\n");
 	free_ring_buffers(tx_ring);
 	dprintf("freeing receive ring\n");
diff --git a/server.c b/server.c
index f4c9508..4f0e1bb 100644
- --- a/server.c
+++ b/server.c
@@ -44,7 +44,8 @@ netrate_server(int consock)
 	int ret;
 	u64 packets = 0;
 	struct ring_buffer *r;
- -	
+	struct netrate_message *m;
+
 	bufsize = sizeof(struct netrate_message) + size;
 
 	/* setup receive ring */
@@ -60,11 +61,14 @@ netrate_server(int consock)
 
 	/* loop until done */
 	while(!interrupted) {
- -		char *buf = get_next_ring_buffer(r);
+		void *buf = get_next_ring_buffer(r);
 
+		m = buf;
 		if ((ret = read_message(consock, buf, bufsize)) <= 0)
 				break;
 
+		if (m->msg_type == MSG_EOF)
+			break;
 		if ((ret = write(consock, buf, bufsize)) < 0) {
 			fprintf(stderr, "Error echoing packet: %s\n",
 				strerror(errno));
@@ -73,6 +77,7 @@ netrate_server(int consock)
 		packets++;
 	}
 	dprintf("out of receive loop (processed %d packets)\n", packets);
+	close(consock);
 
 	free_ring_buffers(r);
 	return 0;
diff --git a/transmit.c b/transmit.c
index f0db186..dd90fab 100644
- --- a/transmit.c
+++ b/transmit.c
@@ -61,6 +61,7 @@ netrate_transmit(void)
 	setjmp(jmpbuf);
 	while(!interrupted) {
 		msg = (struct netrate_message *) get_next_ring_buffer(r);
+		msg->msg_type = MSG_DATA;
 		msg->msg_seq = ++sequence;
 		msg->msg_len = size;
 
@@ -81,6 +82,15 @@ netrate_transmit(void)
 		}	
 	}
 	dprintf("out of transmit loop (%lu messages transmitted)\n", sequence);
+	if (protocol == IPPROTO_UDP) {
+		msg = (struct netrate_message *) get_next_ring_buffer(r);
+		msg->msg_type = MSG_EOF;
+		msg->msg_seq = ++sequence;
+		msg->msg_len = size;
+
+		if ((ret = write(sock, msg, bufsize)) < 0)
+			perror("transmit");
+	}
 	close(sock);
 	free_ring_buffers(r);
 	return ret;
- -- 
1.6.0.1


- From 1abef56d17e4a081db2b73fdbfe3c8d228c38a5e Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@xxxxxxxxxx>
Date: Thu, 16 Oct 2008 12:12:25 -0500
Subject: [PATCH] fixed nodelay option setting


Signed-off-by: Clark Williams <williams@xxxxxxxxxx>
- ---
 common.c |   20 +++++++++++---------
 1 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/common.c b/common.c
index a990e20..5302785 100644
- --- a/common.c
+++ b/common.c
@@ -473,7 +473,6 @@ netrate_tx_socket(int protocol, int port, int request)
 {
 	int ret;
 	int sock;
- -	int val;
 	char portstring[10];
 	struct addrinfo *ai, hints;
 	struct netrate_exchange ex;
@@ -506,15 +505,18 @@ netrate_tx_socket(int protocol, int port, int request)
 
 	freeaddrinfo(ai);
 
- -	if (protocol == IPPROTO_TCP && nodelay == TRUE) {
+	if (protocol == IPPROTO_TCP) {
+		int val;
 		/* set TCP_NODELAY */
- -		dprintf("setting TCP_NODELAY\n");
- -		val = 1;
- -		if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &val, sizeof(val)) < 0) {
- -			perror("setsockopt");
- -			ret = -errno;
- -			close(sock);
- -			return ret;
+		if (nodelay == TRUE) {
+			dprintf("setting TCP_NODELAY\n");
+			val = 1;
+			if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &val, sizeof(val)) < 0) {
+				perror("setsockopt");
+				ret = -errno;
+				close(sock);
+				return ret;
+			}
 		}
 	}
 	memset(&ex, 0, sizeof(ex));
- -- 
1.6.0.1


- From 2bdbd044f1d1fd94f565e812b2bffdad5147087e Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@xxxxxxxxxx>
Date: Tue, 21 Oct 2008 20:54:33 -0500
Subject: [PATCH] renamed daemon option to listen

changed DAEMON to LISTEN; changed default msg size to 536

Signed-off-by: Clark Williams <williams@xxxxxxxxxx>
- ---
 main.c    |   27 ++++++++++++++-------------
 netrate.h |    4 ++--
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/main.c b/main.c
index 0293a1b..aa41637 100644
- --- a/main.c
+++ b/main.c
@@ -58,7 +58,7 @@ static void interrupt(int sig);
 static struct option long_options[] = {
 	{"transmit", 0, 0, TX},
 	{"rtt", 0, 0, RTT},
- -	{"daemon", 0, 0, DAEMON},
+	{"listen", 0, 0, LISTEN},
 	{"rate", 1, 0, RATE},
 	{"size", 1, 0, SIZE},
 	{"tcp", 0, 0, TCP},
@@ -78,7 +78,7 @@ static struct option long_options[] = {
 
 void usage(void)
 {
- -	fprintf(stderr, "usage: netrate {--transmit|--rtt|--daemon} [options]\n");
+	fprintf(stderr, "usage: netrate {--transmit|--rtt|--listen} [options]\n");
 	fprintf(stderr, "   where options are:\n");
 	fprintf(stderr, "        --rate=<Inter-Packet Interval>\n");
 	fprintf(stderr, "        --size=<packet size>\n");
@@ -97,7 +97,7 @@ void usage(void)
 
 
 int
- -netrate_daemon(void)
+netrate_listen(void)
 {
 	int ret;
 	int servsock, sock;
@@ -105,7 +105,7 @@ netrate_daemon(void)
 	struct sockaddr_in client;
 	struct netrate_exchange ex;
 
- -	dprintf("netrate_daemon: starting\n");
+	dprintf("netrate_listen: starting\n");
 	servsock = netrate_rx_socket(protocol, type);
 	
 	if (protocol == IPPROTO_TCP) {
@@ -121,7 +121,8 @@ netrate_daemon(void)
 		dprintf("calling read for exchange\n");
 		ret = read(sock, &ex, sizeof(ex));
 		if (ret < 0) {
- -			fprintf(stderr, "error reading exchange message: %s\n", strerror(errno));
+			fprintf(stderr, "error reading exchange message: %s\n",
+				strerror(errno));
 			close(sock);
 			exit(-2);
 		}
@@ -232,9 +233,9 @@ int main(int argc, char **argv)
 			break;
 
 		switch(opt) {
- -		case DAEMON:
- -			role = DAEMON;
- -			dprintf("role == DAEMON\n");
+		case LISTEN:
+			role = LISTEN;
+			dprintf("role == LISTEN\n");
 			break;
 		case TX:
 			role = TX;
@@ -305,6 +306,8 @@ int main(int argc, char **argv)
 			dprintf("setting nodelay\n");
 			break;
 		case HISTOGRAM:
+			fprintf(stderr, "histogram option not supported yet\n");
+			exit(-1);
 			histogram = TRUE;
 			dprintf("histogram set to true\n");
 			break;
@@ -319,7 +322,7 @@ int main(int argc, char **argv)
 		}
 	}
 	if (role == 0) {
- -		fprintf(stderr, "Must specifiy either --transmit, --daemon or "
+		fprintf(stderr, "Must specifiy either --transmit, --listen or "
 			"--rtt options!\n");
 		exit(-1);
 	}
@@ -338,14 +341,12 @@ int main(int argc, char **argv)
 	}
 	signal(SIGINT, interrupt);
 
- -	dprintf("startup up with message size == %d\n", size);
- -
 	switch(role) {
 	case TX:
 		exit_val = netrate_transmit();
 		break;
- -	case DAEMON:
- -		exit_val = netrate_daemon();
+	case LISTEN:
+		exit_val = netrate_listen();
 		break;
 	case RTT:
 		exit_val = netrate_rtt();
diff --git a/netrate.h b/netrate.h
index 8186dc4..88a2f6d 100644
- --- a/netrate.h
+++ b/netrate.h
@@ -29,7 +29,7 @@
 #define FALSE 0
 
 enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, 
- -	       MULTI, PORT, HOST, DEBUG, HELP, DAEMON,
+	       MULTI, PORT, HOST, DEBUG, HELP, LISTEN,
 	       SERVER, RTT, NODELAY, HISTOGRAM, BREAKON,
 	       SKIP, NUM_OPT_VALS,
 };
@@ -49,7 +49,7 @@ enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP,
 #define NS_TO_MS(n)	(NS_TO_US(n) / 1000)
 
 #define DEF_TX_RATE 	MS_TO_NS(100)
- -#define DEF_MSG_SIZE 	50
+#define DEF_MSG_SIZE 	536
 #define DEF_PORT 	5001 /* steal the ttcp port :) */
 #define MAX_BUF_SIZE	8192
 #define NETRATE_MSG_DATA 0xa5
- -- 
1.6.0.1


- From bdc0d3f6e90c97927a6aa736d9321b975d3b3c51 Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@xxxxxxxxxx>
Date: Thu, 16 Oct 2008 12:34:23 -0500
Subject: [PATCH] rearranged includes

Changed order of socket includes

Signed-off-by: Clark Williams <williams@xxxxxxxxxx>
- ---
 networking.h |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/networking.h b/networking.h
index db08758..e870591 100644
- --- a/networking.h
+++ b/networking.h
@@ -22,13 +22,15 @@
 #define __NETWORKING_H__
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <linux/tcp.h>
 #include <sys/time.h>
 #include <time.h>
- -#include <netinet/in.h>
- -#include <fcntl.h>
- -#include <signal.h>
 #include <sys/un.h>
 #include <sys/wait.h>
 #include <netdb.h>
- -#include <linux/tcp.h>
+#include <fcntl.h>
+#include <signal.h>
+
 #endif
- -- 
1.6.0.1


- From 8a2c923b7345c64543e4cd4d8a19f4ca64494e1a Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@xxxxxxxxxx>
Date: Thu, 16 Oct 2008 12:35:18 -0500
Subject: [PATCH] move tx buffer setup

don't setup tx buffers until we know we're connected

Signed-off-by: Clark Williams <williams@xxxxxxxxxx>
- ---
 transmit.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/transmit.c b/transmit.c
index dd90fab..0bd414a 100644
- --- a/transmit.c
+++ b/transmit.c
@@ -40,10 +40,7 @@ netrate_transmit(void)
 	struct netrate_message *msg;
 	struct timespec ts;
 	struct ring_buffer *r;
- -	int bufsize = sizeof(struct netrate_message) + size;
- -
- -	/* setup transmit buffers */
- -	r = setup_ring_buffers(10, bufsize);
+	int bufsize = sizeof(struct netrate_message) + size;;
 
 	dprintf("setting up transmit socket\n");
 	sock = netrate_tx_socket(protocol, port, RX);
@@ -52,6 +49,9 @@ netrate_transmit(void)
 		return -(errno);
 	}
 
+	/* setup transmit buffers */
+	r = setup_ring_buffers(10, bufsize);
+
 	dprintf("entering transmit loop (IPI == %dms)\n", NS_TO_MS(rate));
 	if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
 		fprintf(stderr, "clock_gettime failed\n");
- -- 
1.6.0.1

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)

iEUEARECAAYFAkj+oLEACgkQqA4JVb61b9dBoACYtn9gXlCGv4N9SKifK4UDSMsJ
tACeJ6gQ05BJMzqqOvk8C5oUEXWFfIY=
=VZTH
-----END PGP SIGNATURE-----
ÿôèº{.nÇ+?·?®?­?+%?Ëÿ±éݶ¥?wÿº{.nÇ+?·¥?{±þ»ÿºÇ«³ø§¶?¡Ü¨}©?²Æ zÚ&j:+v?¨þø¯ù®w¥þ?à2?Þ?¨è­Ú&¢)ß¡«a¶Úÿÿûàz¿äz¹Þ?ú+?ù???Ý¢jÿ?wèþf


[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux