* [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
* Re: [PATCH 2/2] netrate - network rate/rtt measurement utility
2008-10-22 3:40 [PATCH 2/2] netrate - network rate/rtt measurement utility Clark Williams
@ 2008-10-22 4:39 ` Clark Williams
0 siblings, 0 replies; 2+ messages in thread
From: Clark Williams @ 2008-10-22 4:39 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: RT
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Sigh.
Gmail really trashed my first message. From what Dave Miller forwarded to me, it looks like it got base64'ed and went over the 100K limit.
Easist thing to do is fetch the tarball:
http://people.redhat.com/williams/netrate-0.4.tar.bz2
Thanks,
Clark
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
iEYEARECAAYFAkj+rnQACgkQHyuj/+TTEp1mYQCcDAj0dt2j+Mpk+YHFjooouX3Z
F3kAn2YWUBpqjYzepUXw3f+4r+X0Vpqa
=Y7D8
-----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).