* [PATCH 2/2] netrate - network rate/rtt measurement utility
@ 2008-10-22 3:40 Clark Williams
2008-10-22 4:39 ` Clark Williams
0 siblings, 1 reply; 2+ messages in thread
From: Clark Williams @ 2008-10-22 3:40 UTC (permalink / raw)
To: Thomas Gleixner, RT
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
- From 1ecdeb7f48302a2ea8a37fd8aecd90081637e0dc Mon Sep 17 00:00:00 2001
From: Clark Williams <williams@redhat.com>
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@redhat.com>
- ---
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@redhat.com>
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@redhat.com>
- ---
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@redhat.com>
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@redhat.com>
- ---
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@redhat.com>
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@redhat.com>
- ---
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@redhat.com>
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@redhat.com>
- ---
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@redhat.com>
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@redhat.com>
- ---
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, ¤t);
+ if (status < 0) {
+ fprintf(stderr, "error from clock_gettime: %s\n",
+ strerror(abs(status)));
+ return (int) status;
+ }
+ update_statistics_time(stats, ¤t, 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(¤t, &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@redhat.com>
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@redhat.com>
- ---
.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, ¤t);
if (status < 0) {
@@ -95,13 +99,13 @@ netrate_receive(int consock)
strerror(abs(status)));
return (int) status;
}
- - if (sequence++) {
+ if (sequence++ > skip) {
tsdelta(¤t, &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@redhat.com>
Date: Thu, 16 Oct 2008 12:12:25 -0500
Subject: [PATCH] fixed nodelay option setting
Signed-off-by: Clark Williams <williams@redhat.com>
- ---
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@redhat.com>
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@redhat.com>
- ---
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@redhat.com>
Date: Thu, 16 Oct 2008 12:34:23 -0500
Subject: [PATCH] rearranged includes
Changed order of socket includes
Signed-off-by: Clark Williams <williams@redhat.com>
- ---
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@redhat.com>
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@redhat.com>
- ---
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-----
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-10-22 4:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-22 3:40 [PATCH 2/2] netrate - network rate/rtt measurement utility Clark Williams
2008-10-22 4:39 ` Clark Williams
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).