-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 - From 1ecdeb7f48302a2ea8a37fd8aecd90081637e0dc Mon Sep 17 00:00:00 2001 From: Clark Williams <williams@xxxxxxxxxx> Date: Thu, 2 Oct 2008 17:26:05 -0500 Subject: [PATCH] consolidate into common consolidated both rtt and transmit to use same socket setup function; added exchange code and daemon mode; removed --server and --receive; added versioning Signed-off-by: Clark Williams <williams@xxxxxxxxxx> - --- common.c | 82 +++++++++++++++++++++++++++++++++ main.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- netrate.h | 28 +++++++++--- receive.c | 71 +----------------------------- rtt.c | 51 +-------------------- server.c | 74 +------------------------------ transmit.c | 50 +-------------------- 7 files changed, 237 insertions(+), 265 deletions(-) diff --git a/common.c b/common.c index 48cd4e9..8ed0590 100644 - --- a/common.c +++ b/common.c @@ -433,3 +433,85 @@ free_histogram(struct histogram *h) free(h); } +/* + *********************************************************************** + * socket stuff + *********************************************************************** + */ + +int +netrate_tx_socket(int protocol, int port, int request) +{ + int ret; + int sock; + int val; + char portstring[10]; + struct addrinfo *ai, hints; + struct netrate_exchange ex; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_CANONNAME; + hints.ai_family = AF_INET; + hints.ai_socktype = type; + hints.ai_protocol = protocol; + sprintf(portstring, "%d", port); + + ret = getaddrinfo(hostname, portstring, &hints, &ai); + if (ret) { + fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret)); + return -ret; + } + + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock < 0) { + perror("transmit socket()"); + return -(errno); + } + + dprintf("calling connect\n"); + if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + perror("connect"); + close(sock); + return -(errno); + } + + freeaddrinfo(ai); + + if (protocol == IPPROTO_TCP && nodelay == TRUE) { + /* set TCP_NODELAY */ + dprintf("setting TCP_NODELAY\n"); + val = 1; + if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &val, sizeof(val)) < 0) { + perror("setsockopt"); + ret = -errno; + close(sock); + return ret; + } + } + memset(&ex, 0, sizeof(ex)); + ex.major = MAJOR; + ex.minor = MINOR; + ex.request = request; + ex.size = size; + ret = write(sock, (void *) &ex, sizeof(ex)); + if (ret < 0) { + fprintf(stderr, "Error sending exchange request: %s\n", strerror(errno)); + ret = -errno; + close(sock); + return ret; + } + ret = read(sock, (void *) &ex, sizeof(ex)); + if (ret < 0) { + fprintf(stderr, "Error reading exchange ack: %s\n", strerror(errno)); + ret = -errno; + close(sock); + return ret; + } + if (ex.request != REQUEST_ACK) { + fprintf(stderr, "Exchange ack not valid: %x\n", ex.request); + ret = -errno; + close(sock); + return ret; + } + return sock; +} diff --git a/main.c b/main.c index 838642c..a13f7f6 100644 - --- a/main.c +++ b/main.c @@ -54,10 +54,9 @@ char hostname[1024]; /* host to connect to */ static void interrupt(int sig); static struct option long_options[] = { - - {"receive", 0, 0, RX}, {"transmit", 0, 0, TX}, - - {"server", 0, 0, SERVER}, {"rtt", 0, 0, RTT}, + {"daemon", 0, 0, DAEMON}, {"rate", 1, 0, RATE}, {"size", 1, 0, SIZE}, {"tcp", 0, 0, TCP}, @@ -75,7 +74,7 @@ static struct option long_options[] = { void usage(void) { - - fprintf(stderr, "usage: netrate {--transmit|--receive|--server|--rtt} [options]\n"); + fprintf(stderr, "usage: netrate {--transmit|--rtt|--daemon} [options]\n"); fprintf(stderr, " where options are:\n"); fprintf(stderr, " --rate=<Inter-Packet Interval>\n"); fprintf(stderr, " --size=<packet size>\n"); @@ -92,6 +91,126 @@ void usage(void) } +int +netrate_rx_socket(int protocol, int type) +{ + int ret; + int sock; + char portstring[10]; + struct addrinfo hints, *ai; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_INET; + hints.ai_socktype = type; + hints.ai_protocol = protocol; + sprintf(portstring, "%d", port); + + dprintf("calling getaddrinfo\n"); + ret = getaddrinfo(NULL, portstring, &hints, &ai); + if (ret) { + fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret)); + return -ret; + } + + dprintf("calling socket\n"); + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock < 0) { + perror ("receive socket()"); + return -(errno); + } + + dprintf("calling accept\n"); + ret = bind(sock, ai->ai_addr, ai->ai_addrlen); + if (ret < 0) { + perror("bind"); + return -(errno); + } + + if (protocol == IPPROTO_TCP) { + dprintf("calling listen\n"); + ret = listen(sock, SOMAXCONN); + if (ret < 0) { + perror("listen()"); + return -(errno); + } + } + return sock; +} + +int +netrate_daemon(void) +{ + int ret; + int servsock, sock; + socklen_t clientlen; + struct sockaddr_in client; + struct netrate_exchange ex, ack; + + dprintf("netrate_daemon: starting\n"); + servsock = netrate_rx_socket(protocol, type); + + if (protocol == IPPROTO_TCP) { + dprintf("calling accept\n"); + sock = accept(servsock, (struct sockaddr *)&client, &clientlen); + if (sock < 0) { + fprintf(stderr, "error from accept: %s\n", strerror(errno)); + close(servsock); + exit(-1); + } + close(servsock); + dprintf("out of accept\n"); + } + else + sock = servsock; + + dprintf("calling read for exchange\n"); + ret = read(sock, &ex, sizeof(ex)); + if (ret < 0) { + fprintf(stderr, "error reading exchange message: %s\n", strerror(errno)); + close(sock); + exit(-2); + } + dprintf("got exchange: major: %d, minor: %d, request: %d, size: %d\n", + ex.major, ex.minor, ex.request, ex.size); + + if (ex.major != MAJOR || ex.minor != MINOR) { + fprintf(stderr, "protocol mismatch us: (%d, %d), them:(%d, %d)\n", + MAJOR, MINOR, ex.major, ex.minor); + close(sock); + exit(-3); + } + + size = ex.size; + + ack = ex; + ack.request = REQUEST_ACK; + + dprintf("ACK'ing exchange\n"); + ret = write(sock, &ack, sizeof(ack)); + if (ret < 0) { + fprintf(stderr, "error acknowledging exchange request: %s\n", + strerror(errno)); + close(sock); + exit(-4); + } + + switch (ex.request) { + + case SERVER: + dprintf("calling netrate_server()\n"); + return netrate_server(sock); + + case RX: + dprintf("calling netrate_receive()\n"); + return netrate_receive(sock); + } + fprintf(stderr, "Unknown exchange request: %d\n", ex.request); + close(sock); + return -1; +} + + int main(int argc, char **argv) { int ret; @@ -107,18 +226,14 @@ int main(int argc, char **argv) break; switch(opt) { - - case RX: - - role = RX; - - dprintf("role == RX\n"); + case DAEMON: + role = DAEMON; + dprintf("role == DAEMON\n"); break; case TX: role = TX; dprintf("role == TX\n"); break; - - case SERVER: - - role = SERVER; - - dprintf("role == SERVER\n"); - - break; case RTT: role = RTT; dprintf("role == RTT\n"); @@ -193,8 +308,8 @@ int main(int argc, char **argv) } } if (role == 0) { - - fprintf(stderr, "Must specifiy either --transmit or " - - "--receive options!\n"); + fprintf(stderr, "Must specifiy either --transmit, --daemon or " + "--rtt options!\n"); exit(-1); } @@ -218,11 +333,8 @@ int main(int argc, char **argv) case TX: exit_val = netrate_transmit(); break; - - case RX: - - exit_val = netrate_receive(); - - break; - - case SERVER: - - exit_val = netrate_server(); + case DAEMON: + exit_val = netrate_daemon(); break; case RTT: exit_val = netrate_rtt(); diff --git a/netrate.h b/netrate.h index a0f79b5..c2aaba8 100644 - --- a/netrate.h +++ b/netrate.h @@ -22,12 +22,18 @@ #ifndef __NETRATE_H__ #define __NETRATE_H__ +#define MAJOR 0 +#define MINOR 3 + #define TRUE 1 #define FALSE 0 - -enum optvals {RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, - - MULTI, PORT, HOST, DEBUG, HELP, - - SERVER, RTT, NODELAY, HISTOGRAM}; +enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, + MULTI, PORT, HOST, DEBUG, HELP, DAEMON, + SERVER, RTT, NODELAY, HISTOGRAM, + NUM_OPT_VALS, +}; + #define NS_PER_SEC 1000000000 #define US_PER_SEC 1000000 @@ -48,6 +54,16 @@ enum optvals {RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, #define MAX_BUF_SIZE 8192 #define NETRATE_MSG_DATA 0xa5 +#include <linux/types.h> +struct netrate_exchange { + __u16 major; + __u16 minor; + __u16 request; + __u16 size; +}; + +#define REQUEST_ACK 0xffff + struct netrate_message { unsigned long msg_len; /* message length (including header) */ unsigned long msg_seq; /* sequence number */ @@ -55,7 +71,6 @@ struct netrate_message { char msg_data[]; /* body of message */ }; - - extern int protocol; extern int type; extern int nodelay; @@ -70,9 +85,10 @@ extern int interrupted; extern jmp_buf jmpbuf; int netrate_transmit(void); - -int netrate_receive(void); +int netrate_receive(int sock); int netrate_rtt(void); - -int netrate_server(void); +int netrate_server(int sock); +int netrate_tx_socket(int protocol, int port, int request); void stop_execution(void); void dprintf(char *, ...); diff --git a/receive.c b/receive.c index ac145d5..b9a255a 100644 - --- a/receive.c +++ b/receive.c @@ -36,60 +36,13 @@ static struct statistics *stats; - -static int - -netrate_rx_socket(int protocol, int port, int multicast) - -{ - - int ret; - - int sock; - - char portstring[10]; - - struct addrinfo hints, *ai; - - - - memset(&hints, 0, sizeof(hints)); - - hints.ai_flags = AI_PASSIVE; - - hints.ai_family = AF_INET; - - hints.ai_socktype = type; - - hints.ai_protocol = protocol; - - sprintf(portstring, "%d", port); - - - - ret = getaddrinfo(NULL, portstring, &hints, &ai); - - if (ret) { - - fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret)); - - return -ret; - - } - - - - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - - if (sock < 0) { - - perror ("receive socket()"); - - return -(errno); - - } - - - - ret = bind(sock, ai->ai_addr, ai->ai_addrlen); - - if (ret < 0) { - - perror("bind"); - - return -(errno); - - } - - - - if (protocol == IPPROTO_TCP) { - - ret = listen(sock, SOMAXCONN); - - if (ret < 0) { - - perror("listen()"); - - return -(errno); - - } - - } - - return sock; - -} - - - - /* * main receiver routine */ int - -netrate_receive(void) +netrate_receive(int consock) { int ret; - - int servsock, consock; - - socklen_t socklen; - - struct sockaddr_in client; void *ptr; struct netrate_message *msg; long status; @@ -101,28 +54,6 @@ netrate_receive(void) /* set up our ring buffers */ r = setup_ring_buffers(10, bufsize); - - /* setup a socket */ - - servsock = netrate_rx_socket(protocol, port, multicast); - - if (servsock < 0) { - - perror("setting up recieve socket"); - - return servsock; - - } - - - - /* if we're doing TCP, call accept */ - - if (protocol == IPPROTO_TCP) { - - dprintf("calling accept\n"); - - consock = accept(servsock, (struct sockaddr *)&client, &socklen); - - if (consock < 0) { - - perror("accept"); - - close(servsock); - - return consock; - - } - - close(servsock); - - dprintf("connection started\n"); - - } - - else { - - consock = servsock; - - } /* allocate statistics space */ stats = setup_statistics(MSEC); diff --git a/rtt.c b/rtt.c index 067d282..264a9a6 100644 - --- a/rtt.c +++ b/rtt.c @@ -44,54 +44,6 @@ static int stop_running = FALSE; static struct statistics *stats; - -static int - -setup_socket(int protocol, int port, int multicast) - -{ - - int ret; - - int val; - - char portstring[10]; - - struct addrinfo hints, *ai; - - - - memset(&hints, 0, sizeof(hints)); - - hints.ai_flags = AI_CANONNAME; - - hints.ai_family = AF_INET; - - hints.ai_socktype = type; - - hints.ai_protocol = protocol; - - sprintf(portstring, "%d", port); - - - - ret = getaddrinfo(hostname, portstring, &hints, &ai); - - if (ret) { - - fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret)); - - return -ret; - - } - - - - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - - if (sock < 0) { - - perror("transmit socket()"); - - return -(errno); - - } - - - - dprintf("calling connect\n"); - - if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { - - perror("connect"); - - close(sock); - - return -(errno); - - } - - - - freeaddrinfo(ai); - - - - if (protocol == IPPROTO_TCP && nodelay == TRUE) { - - /* set TCP_NODELAY */ - - dprintf("setting TCP_NODELAY\n"); - - val = 1; - - if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &val, sizeof(val)) < 0) { - - perror("setsockopt"); - - close(sock); - - return -(errno); - - } - - } - - return sock; - -} static void setup_buffers(struct ring_buffer **txring, struct ring_buffer **rxring) @@ -221,14 +173,13 @@ int netrate_rtt(void) { int ret; - - int sock; long val; struct netrate_message *msg; struct timespec ts; pthread_t thread_id; dprintf("setting up transmit socket\n"); - - sock = setup_socket(protocol, port, multicast); + sock = netrate_tx_socket(protocol, port, SERVER); if (sock < 0) { perror("transmit socket"); return -(errno); diff --git a/server.c b/server.c index 8264b4e..9d205ba 100644 - --- a/server.c +++ b/server.c @@ -34,61 +34,14 @@ static int bufsize; #define RING_SIZE 10 - -static int - -netrate_rx_socket(int protocol, int port, int multicast) - -{ - - int ret; - - int sock; - - char portstring[10]; - - struct addrinfo hints, *ai; - - - - memset(&hints, 0, sizeof(hints)); - - hints.ai_flags = AI_PASSIVE; - - hints.ai_family = AF_INET; - - hints.ai_socktype = type; - - hints.ai_protocol = protocol; - - sprintf(portstring, "%d", port); - - - - ret = getaddrinfo(NULL, portstring, &hints, &ai); - - if (ret) { - - fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret)); - - return -ret; - - } - - - - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - - if (sock < 0) { - - perror ("receive socket()"); - - return -(errno); - - } - - - - ret = bind(sock, ai->ai_addr, ai->ai_addrlen); - - if (ret < 0) { - - perror("bind"); - - return -(errno); - - } - - - - freeaddrinfo(ai); - - - - if (protocol == IPPROTO_TCP) { - - ret = listen(sock, SOMAXCONN); - - if (ret < 0) { - - perror("listen()"); - - return -(errno); - - } - - } - - return sock; - -} /* * receive netrate messages and return them as quickly as possible */ int - -netrate_server(void) +netrate_server(int consock) { int ret; - - int servsock, consock; - - socklen_t socklen; - - struct sockaddr_in client; unsigned long packets = 0; struct ring_buffer *r; @@ -97,31 +50,6 @@ netrate_server(void) /* setup receive ring */ r = setup_ring_buffers(RING_SIZE, bufsize); - - /* setup a socket */ - - servsock = netrate_rx_socket(protocol, port, multicast); - - if (servsock < 0) { - - perror("setting up recieve socket"); - - free_ring_buffers(r); - - return servsock; - - } - - - - /* if we're doing TCP, call accept */ - - if (protocol == IPPROTO_TCP) { - - dprintf("calling accept\n"); - - consock = accept(servsock, (struct sockaddr *)&client, &socklen); - - if (consock < 0) { - - perror("accept"); - - close(servsock); - - free_ring_buffers(r); - - return consock; - - } - - close(servsock); - - dprintf("connection started\n"); - - } - - else { - - consock = servsock; - - } - - dprintf("entering server loop\n"); /* save our bailout point for SIGINT */ diff --git a/transmit.c b/transmit.c index c134916..5e09bf6 100644 - --- a/transmit.c +++ b/transmit.c @@ -31,54 +31,6 @@ static unsigned long long sequence = 0; - -static int - -netrate_tx_socket(int protocol, int port, int multicast) - -{ - - int ret; - - int sock; - - int val; - - char portstring[10]; - - struct addrinfo *ai, hints; - - - - memset(&hints, 0, sizeof(hints)); - - hints.ai_flags = AI_CANONNAME; - - hints.ai_family = AF_INET; - - hints.ai_socktype = type; - - hints.ai_protocol = protocol; - - sprintf(portstring, "%d", port); - - - - ret = getaddrinfo(hostname, portstring, &hints, &ai); - - if (ret) { - - fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret)); - - return -ret; - - } - - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - - if (sock < 0) { - - perror("transmit socket()"); - - return -(errno); - - } - - - - dprintf("calling connect\n"); - - if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { - - perror("connect"); - - close(sock); - - return -(errno); - - } - - freeaddrinfo(ai); - - - - if (protocol == IPPROTO_TCP) { - - /* set TCP_NODELAY */ - - dprintf("setting TCP_NODELAY\n"); - - val = 1; - - if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &val, sizeof(val)) < 0) { - - perror("setsockopt"); - - close(sock); - - return -(errno); - - } - - } - - return sock; - -} - - int netrate_transmit(void) { @@ -94,7 +46,7 @@ netrate_transmit(void) r = setup_ring_buffers(10, bufsize); dprintf("setting up transmit socket\n"); - - sock = netrate_tx_socket(protocol, port, multicast); + sock = netrate_tx_socket(protocol, port, RX); if (sock < 0) { perror("transmit socket"); return -(errno); - -- 1.6.0.1 - From ed795f7a0c363b7ba2a05c487b5d7e12e80e9762 Mon Sep 17 00:00:00 2001 From: Clark Williams <williams@xxxxxxxxxx> Date: Wed, 8 Oct 2008 15:08:33 -0500 Subject: [PATCH] make use wildcards modified Makefile targets to use wildcard builtin Signed-off-by: Clark Williams <williams@xxxxxxxxxx> - --- Makefile | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 7a5c25e..e9ad854 100644 - --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC := gcc CFLAGS := -g -O2 -Wall - -SRC := main.c receive.c transmit.c rtt.c server.c common.c - -HDR := netrate.h networking.h +SRC := $(wildcard *.c) +HDR := $(wildcard *.h) OBJ := $(subst .c,.o,$(SRC)) netrate: $(OBJ) - -- 1.6.0.1 - From c212089b4f3e751e7b5cb47a2a207d61af6f07a3 Mon Sep 17 00:00:00 2001 From: Clark Williams <williams@xxxxxxxxxx> Date: Wed, 8 Oct 2008 15:12:10 -0500 Subject: [PATCH] socket functions to common moved tx and rx socket setup functions into common.c; changed to u64 type (from unsigned long long) Signed-off-by: Clark Williams <williams@xxxxxxxxxx> - --- common.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 87 insertions(+), 11 deletions(-) diff --git a/common.c b/common.c index 8ed0590..a990e20 100644 - --- a/common.c +++ b/common.c @@ -42,26 +42,26 @@ /* * turn a struct timespec into a long long of nanoseconds */ - -unsigned long long +u64 ts2ns(struct timespec *t) { return ((t->tv_sec * NS_PER_SEC) + t->tv_nsec); } - -unsigned long +u64 ts2us(struct timespec *t) { return (t->tv_sec * US_PER_SEC) + NS_TO_US(t->tv_nsec); } - -unsigned long +u64 ts2ms(struct timespec *t) { return (t->tv_sec * MS_PER_SEC) + NS_TO_MS(t->tv_nsec); } static unsigned long - -ns2x(unsigned long ns, int units) +ns2x(u64 ns, int units) { switch(units) { case MSEC: @@ -76,7 +76,7 @@ ns2x(unsigned long ns, int units) return 0; } - -unsigned long +u64 ts2x(struct timespec *ts, int units) { if (ts == NULL) { @@ -120,7 +120,7 @@ tsnormalize(struct timespec *ts) } void - -tsadd(struct timespec *ts, unsigned long ns) +tsadd(struct timespec *ts, u64 ns) { ts->tv_nsec += ns; tsnormalize(ts); @@ -302,11 +302,29 @@ update_statistics_time (struct statistics *s, s->end = *end; } +void +check_delta(struct statistics *s, struct timespec *delta) +{ + u64 val; + if (delta == NULL) { + fprintf(stderr, "Invalid timespec pointer!\n"); + exit(-2); + } + + val = ts2ns(delta); + if (breakon && val > breakon) { + fprintf(stderr, "breakon threshold exceeded!" + " sample: %lu, value: %luns\n", + (unsigned long)s->samples, (unsigned long) val); + exit(-1); + } +} + /* note: raw values are kept in nanoseconds */ void update_statistics_data (struct statistics *s, struct timespec *tsdelta) { - - unsigned long long val; + u64 val; if (s == NULL) { fprintf(stderr, "Invalid statistics structure!\n"); @@ -344,13 +362,23 @@ print_statistics(struct statistics *s) ns2x(runlen.tv_nsec, s->units), suffix); } printf("Run Statistics:\n"); - - printf("Number of Samples: %lu\n", s->samples); + printf("Number of Samples: %lu\n", (unsigned long) s->samples); printf("Minumum: %lu%s\n", ns2x(s->min, s->units), suffix); printf("Maximum: %lu%s\n", ns2x(s->max, s->units), suffix); printf("Average: %lu%s\n", ns2x(s->accum / s->samples, s->units), suffix); } +int +missed_sequence(struct statistics *s, int expected, int got) +{ + s->missed_sequence++; + if (expected < got) + return got+1; + return expected; +} + + void free_statistics(struct statistics *s) { @@ -367,7 +395,7 @@ struct histogram * setup_histogram (int units, int nbuckets, int bucketwidth, int base) { struct histogram *h; - - int hsize = sizeof(struct histogram) + (nbuckets * sizeof(unsigned long)); + int hsize = sizeof(struct histogram) + (nbuckets * sizeof(u64)); h = malloc(hsize); if (h == NULL) { @@ -385,7 +413,7 @@ setup_histogram (int units, int nbuckets, int bucketwidth, int base) void histogram_record(struct histogram *h, struct timespec *ts) { - - unsigned long long val; + u64 val; if (h == NULL) { fprintf(stderr, "invalid histogram structure!\n"); @@ -423,7 +451,8 @@ histogram_print(struct histogram *h) printf("Histogram (%d %d%s buckets)\n", h->nbuckets, h->bucketwidth, suffix); for (i = 0; i < h->nbuckets; i++) - - printf("%4.4d%s: %lu\n", i*h->bucketwidth, suffix, h->bucket[i]); + printf("%4.4d%s: %lu\n", i*h->bucketwidth, suffix, + (unsigned long)h->bucket[i]); } @@ -515,3 +544,50 @@ netrate_tx_socket(int protocol, int port, int request) } return sock; } + +int +netrate_rx_socket(int protocol, int type) +{ + int ret; + int sock; + char portstring[10]; + struct addrinfo hints, *ai; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_INET; + hints.ai_socktype = type; + hints.ai_protocol = protocol; + sprintf(portstring, "%d", port); + + dprintf("calling getaddrinfo\n"); + ret = getaddrinfo(NULL, portstring, &hints, &ai); + if (ret) { + fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret)); + return -ret; + } + + dprintf("calling socket\n"); + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock < 0) { + perror ("receive socket()"); + return -(errno); + } + + dprintf("calling accept\n"); + ret = bind(sock, ai->ai_addr, ai->ai_addrlen); + if (ret < 0) { + perror("bind"); + return -(errno); + } + + if (protocol == IPPROTO_TCP) { + dprintf("calling listen\n"); + ret = listen(sock, SOMAXCONN); + if (ret < 0) { + perror("listen()"); + return -(errno); + } + } + return sock; +} - -- 1.6.0.1 - From fa8721403c9e3111ae236139414062868642514d Mon Sep 17 00:00:00 2001 From: Clark Williams <williams@xxxxxxxxxx> Date: Wed, 8 Oct 2008 15:12:53 -0500 Subject: [PATCH] add net exchange removed netrate_rx_socket; added function exchange Signed-off-by: Clark Williams <williams@xxxxxxxxxx> - --- main.c | 130 ++++++++++++++++++++++++++++----------------------------------- 1 files changed, 58 insertions(+), 72 deletions(-) diff --git a/main.c b/main.c index a13f7f6..2ee5ad3 100644 - --- a/main.c +++ b/main.c @@ -42,6 +42,7 @@ int type = SOCK_STREAM; /* type of socket */ int nodelay = FALSE; /* use TCP_NODELAY for TCP sockets */ int role = 0; /* should be either TX or RX */ int rate = DEF_TX_RATE; /* transmit packet rate in nanoseconds */ +u64 breakon = 0; /* stop if this threshold exceeded */ int size = DEF_MSG_SIZE; /* size of message */ int port = DEF_PORT; /* tx/rx port to use */ int multicast = FALSE; /* are we multicasting? */ @@ -69,6 +70,7 @@ static struct option long_options[] = { {"help", 0, 0, HELP}, {"nodelay", 0, 0, NODELAY}, {"histogram", 0, 0, HISTOGRAM}, + {"breakon", 1, 0, BREAKON}, {0, 0, 0, 0}, }; @@ -91,52 +93,6 @@ void usage(void) } - -int - -netrate_rx_socket(int protocol, int type) - -{ - - int ret; - - int sock; - - char portstring[10]; - - struct addrinfo hints, *ai; - - - - memset(&hints, 0, sizeof(hints)); - - hints.ai_flags = AI_PASSIVE; - - hints.ai_family = AF_INET; - - hints.ai_socktype = type; - - hints.ai_protocol = protocol; - - sprintf(portstring, "%d", port); - - - - dprintf("calling getaddrinfo\n"); - - ret = getaddrinfo(NULL, portstring, &hints, &ai); - - if (ret) { - - fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret)); - - return -ret; - - } - - - - dprintf("calling socket\n"); - - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - - if (sock < 0) { - - perror ("receive socket()"); - - return -(errno); - - } - - - - dprintf("calling accept\n"); - - ret = bind(sock, ai->ai_addr, ai->ai_addrlen); - - if (ret < 0) { - - perror("bind"); - - return -(errno); - - } - - - - if (protocol == IPPROTO_TCP) { - - dprintf("calling listen\n"); - - ret = listen(sock, SOMAXCONN); - - if (ret < 0) { - - perror("listen()"); - - return -(errno); - - } - - } - - return sock; - -} int netrate_daemon(void) @@ -145,7 +101,7 @@ netrate_daemon(void) int servsock, sock; socklen_t clientlen; struct sockaddr_in client; - - struct netrate_exchange ex, ack; + struct netrate_exchange ex; dprintf("netrate_daemon: starting\n"); servsock = netrate_rx_socket(protocol, type); @@ -183,18 +139,6 @@ netrate_daemon(void) size = ex.size; - - ack = ex; - - ack.request = REQUEST_ACK; - - - - dprintf("ACK'ing exchange\n"); - - ret = write(sock, &ack, sizeof(ack)); - - if (ret < 0) { - - fprintf(stderr, "error acknowledging exchange request: %s\n", - - strerror(errno)); - - close(sock); - - exit(-4); - - } - - switch (ex.request) { case SERVER: @@ -211,6 +155,47 @@ netrate_daemon(void) } +void +netrate_sendack(int sock) +{ + int ret; + struct netrate_exchange ack; + + memset(&ack, 0, sizeof(ack)); + ack.major = MAJOR; + ack.minor = MINOR; + ack.request = REQUEST_ACK; + + dprintf("ACK'ing exchange\n"); + ret = write(sock, &ack, sizeof(ack)); + if (ret < 0) { + fprintf(stderr, "error acknowledging exchange request: %s\n", + strerror(errno)); + close(sock); + exit(-4); + } +} + + +u64 +adjustns(char *suffix, u64 val) +{ + u64 newval = val; + if (suffix) { + if (strcmp(suffix, "ms") == 0) + newval = MS_TO_NS(val); + else if (strcmp(suffix, "us") == 0) + newval = US_TO_NS(val); + else if (strcmp(suffix, "s")) + newval = val * NS_PER_SEC; + else { + fprintf(stderr, "unknown time suffix: %s\n", suffix); + exit(-1); + } + } + return newval; +} + int main(int argc, char **argv) { int ret; @@ -220,7 +205,7 @@ int main(int argc, char **argv) strcpy(hostname, "localhost"); while (1) { - - opt = getopt_long(argc, argv, "rta:z:cdmp", + opt = getopt_long(argc, argv, "rta:z:cdmpb:", long_options, &idx); if (opt == -1) break; @@ -240,23 +225,24 @@ int main(int argc, char **argv) break; case RATE: rate = strtol(optarg, &endptr, 10); - - if (endptr) { - - if (strcmp(endptr, "ms") == 0) - - rate = MS_TO_NS(rate); - - else if (strcmp(endptr, "us") == 0) - - rate = US_TO_NS(rate); - - else if (strcmp(endptr, "s")) - - rate = rate * NS_PER_SEC; - - else { - - fprintf(stderr, "unknown time suffix: %s\n", endptr); - - exit(-1); - - } - - } + if (endptr) + rate = adjustns(endptr, rate); /* default (no suffix) is milliseconds */ else rate = MS_TO_NS(rate); dprintf("rate set to %dms\n", NS_TO_MS(rate)); break; + case BREAKON: + breakon = strtol(optarg, &endptr, 10); + if (endptr) + breakon = adjustns(endptr, breakon); + else + breakon = MS_TO_NS(breakon); + dprintf("breakon set to %lums\n", + (unsigned long) NS_TO_MS(breakon)); + break; + + case SIZE: size = strtol(optarg, NULL, 10); dprintf("size set to %d\n", size); - -- 1.6.0.1 - From e5ce0e98fc81cbbfdb88cdd47902965b7d731d1b Mon Sep 17 00:00:00 2001 From: Clark Williams <williams@xxxxxxxxxx> Date: Wed, 8 Oct 2008 15:13:38 -0500 Subject: [PATCH] breakon and short typenames added the BREAKON enumerated type and option to stop on a latency greater than X; changed to short typenames Signed-off-by: Clark Williams <williams@xxxxxxxxxx> - --- netrate.h | 50 ++++++++++++++++++++++++++++++-------------------- 1 files changed, 30 insertions(+), 20 deletions(-) diff --git a/netrate.h b/netrate.h index c2aaba8..9f073dd 100644 - --- a/netrate.h +++ b/netrate.h @@ -30,7 +30,7 @@ enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, MULTI, PORT, HOST, DEBUG, HELP, DAEMON, - - SERVER, RTT, NODELAY, HISTOGRAM, + SERVER, RTT, NODELAY, HISTOGRAM, BREAKON, NUM_OPT_VALS, }; @@ -55,18 +55,22 @@ enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, #define NETRATE_MSG_DATA 0xa5 #include <linux/types.h> +typedef __u16 u16; +typedef __u32 u32; +typedef __u64 u64; + struct netrate_exchange { - - __u16 major; - - __u16 minor; - - __u16 request; - - __u16 size; + u16 major; + u16 minor; + u16 request; + u16 size; }; #define REQUEST_ACK 0xffff struct netrate_message { - - unsigned long msg_len; /* message length (including header) */ - - unsigned long msg_seq; /* sequence number */ + u64 msg_len; /* message length (including header) */ + u64 msg_seq; /* sequence number */ struct timespec msg_ts; /* time message was sent */ char msg_data[]; /* body of message */ }; @@ -76,6 +80,7 @@ extern int type; extern int nodelay; extern int role; extern int rate; +extern u64 breakon; extern int size; extern int multicast; extern int port; @@ -89,17 +94,19 @@ int netrate_receive(int sock); int netrate_rtt(void); int netrate_server(int sock); int netrate_tx_socket(int protocol, int port, int request); +int netrate_rx_socket(int protocol, int type); +void netrate_sendack(int sock); void stop_execution(void); void dprintf(char *, ...); - -unsigned long long ts2ns(struct timespec *ts); - -unsigned long ts2us(struct timespec *ts); - -unsigned long ts2ms(struct timespec *ts); +u64 ts2ns(struct timespec *ts); +u64 ts2us(struct timespec *ts); +u64 ts2ms(struct timespec *ts); void tsdelta(struct timespec *later, struct timespec *earlier, struct timespec *delta); void tsnormalize(struct timespec *ts); - -void tsadd(struct timespec *ts, unsigned long ns); +void tsadd(struct timespec *ts, u64 ns); struct ring_buffer { @@ -123,12 +130,13 @@ enum units { SEC=1, MSEC, USEC, NSEC }; struct statistics { struct timespec start; struct timespec end; - - unsigned long min; - - unsigned long max; - - unsigned long average; - - unsigned long long accum; - - unsigned long samples; - - unsigned int units; + u64 min; + u64 max; + u64 average; + u64 accum; + u64 samples; + u32 units; + u32 missed_sequence; }; @@ -136,17 +144,19 @@ struct statistics *setup_statistics(int units); void update_statistics_data(struct statistics *s, struct timespec *tsdelta); void update_statistics_time(struct statistics *s, struct timespec *start, struct timespec *end); +void check_delta(struct statistics *s, struct timespec *delta); void print_statistics(struct statistics *s); void free_statistics(struct statistics *s); +int missed_sequence(struct statistics *s, int expected, int got); struct histogram { int units; int base; int nbuckets; int bucketwidth; - - unsigned long underflow; - - unsigned long overflow; - - unsigned long bucket[]; + u64 underflow; + u64 overflow; + u64 bucket[]; }; struct histogram *setup_histogram (int units, int nbuckets, - -- 1.6.0.1 - From 761d49f846e1947d708c3b2053b2f048562485bd Mon Sep 17 00:00:00 2001 From: Clark Williams <williams@xxxxxxxxxx> Date: Tue, 21 Oct 2008 20:45:48 -0500 Subject: [PATCH] keep going on sequence mismatch dont exit on sequence mismatch; added exchange code Signed-off-by: Clark Williams <williams@xxxxxxxxxx> - --- receive.c | 27 +++++++++++++++++++-------- rtt.c | 2 +- server.c | 5 ++++- transmit.c | 2 +- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/receive.c b/receive.c index b9a255a..798daff 100644 - --- a/receive.c +++ b/receive.c @@ -54,26 +54,36 @@ netrate_receive(int consock) /* set up our ring buffers */ r = setup_ring_buffers(10, bufsize); - - /* allocate statistics space */ stats = setup_statistics(MSEC); + /* mark our start time */ + status = clock_gettime(CLOCK_MONOTONIC, ¤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@xxxxxxxxxx> Date: Tue, 21 Oct 2008 20:52:24 -0500 Subject: [PATCH] packet skip and connected UDP added logic to put UDP socket in connected mode; added packet skip option added versioning in the Makefile Signed-off-by: Clark Williams <williams@xxxxxxxxxx> - --- .gitignore | 1 + Makefile | 7 +++++-- main.c | 41 +++++++++++++++++++++++++++++++++-------- netrate.h | 11 +++++++++-- receive.c | 9 +++++++-- rtt.c | 9 +++++++++ server.c | 9 +++++++-- transmit.c | 10 ++++++++++ 8 files changed, 81 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 2e01fe3..d056f27 100644 - --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.o *~ netrate +*.bz2 diff --git a/Makefile b/Makefile index e9ad854..d75f741 100644 - --- a/Makefile +++ b/Makefile @@ -3,6 +3,9 @@ CFLAGS := -g -O2 -Wall SRC := $(wildcard *.c) HDR := $(wildcard *.h) OBJ := $(subst .c,.o,$(SRC)) +MAJOR := $(shell awk '/MAJOR/ {print $$3}' netrate.h) +MINOR := $(shell awk '/MINOR/ {print $$3}' netrate.h) +VERSION := $(MAJOR).$(MINOR) netrate: $(OBJ) $(CC) $(CFLAGS) -o netrate $(OBJ) -lrt @@ -15,5 +18,5 @@ clean: tarball: clean mkdir -p tmp/netrate cp Makefile $(SRC) $(HDR) tmp/netrate - - (cd tmp && tar -cjvf netrate.tar.bz2 netrate) - - mv tmp/netrate.tar.bz2 . + (cd tmp && tar -cjvf netrate-$(VERSION).tar.bz2 netrate) + mv tmp/netrate-$(VERSION).tar.bz2 . diff --git a/main.c b/main.c index 2ee5ad3..0293a1b 100644 - --- a/main.c +++ b/main.c @@ -50,6 +50,7 @@ int debugging = FALSE; /* Are we edbugging? */ int interrupted = FALSE; /* have we been interrupted? */ jmp_buf jmpbuf; /* bailout state for being interrupted */ int histogram = FALSE; /* keep a histogram of time values */ +int skip = 0; /* number of packets to skip before measuring */ char hostname[1024]; /* host to connect to */ static void interrupt(int sig); @@ -71,6 +72,7 @@ static struct option long_options[] = { {"nodelay", 0, 0, NODELAY}, {"histogram", 0, 0, HISTOGRAM}, {"breakon", 1, 0, BREAKON}, + {"skip", 1, 0, SKIP}, {0, 0, 0, 0}, }; @@ -116,16 +118,35 @@ netrate_daemon(void) } close(servsock); dprintf("out of accept\n"); + dprintf("calling read for exchange\n"); + ret = read(sock, &ex, sizeof(ex)); + if (ret < 0) { + fprintf(stderr, "error reading exchange message: %s\n", strerror(errno)); + close(sock); + exit(-2); + } } - - else - - sock = servsock; + else { + struct sockaddr_in addr; + socklen_t addrlen; - - dprintf("calling read for exchange\n"); - - ret = read(sock, &ex, sizeof(ex)); - - if (ret < 0) { - - fprintf(stderr, "error reading exchange message: %s\n", strerror(errno)); - - close(sock); - - exit(-2); + sock = servsock; + dprintf("Calling recvfrom for exchange\n"); + ret = recvfrom(sock, &ex, sizeof(ex), 0, + (struct sockaddr *) &addr, + (socklen_t *) &addrlen); + if (ret == -1) { + fprintf(stderr, "error receiving exchange data: %s\n", + strerror(errno)); + close(sock); + exit(-2); + } + if (connect(sock, (struct sockaddr *) &addr, addrlen) < 0) { + fprintf(stderr, "error connecting UDP socket: %s\n", + strerror(errno)); + close(sock); + exit(-2); + } } dprintf("got exchange: major: %d, minor: %d, request: %d, size: %d\n", ex.major, ex.minor, ex.request, ex.size); @@ -287,6 +308,10 @@ int main(int argc, char **argv) histogram = TRUE; dprintf("histogram set to true\n"); break; + case SKIP: + skip = strtol(optarg, NULL, 10); + dprintf("packet skip set to %d\n", skip); + break; case HELP: default: usage(); diff --git a/netrate.h b/netrate.h index 9f073dd..8186dc4 100644 - --- a/netrate.h +++ b/netrate.h @@ -23,7 +23,7 @@ #define __NETRATE_H__ #define MAJOR 0 - -#define MINOR 3 +#define MINOR 4 #define TRUE 1 #define FALSE 0 @@ -31,7 +31,7 @@ enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, MULTI, PORT, HOST, DEBUG, HELP, DAEMON, SERVER, RTT, NODELAY, HISTOGRAM, BREAKON, - - NUM_OPT_VALS, + SKIP, NUM_OPT_VALS, }; @@ -54,6 +54,9 @@ enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, #define MAX_BUF_SIZE 8192 #define NETRATE_MSG_DATA 0xa5 +/* number of packets to skip before starting measurements */ +#define STEADY_STATE_DELAY 1 + #include <linux/types.h> typedef __u16 u16; typedef __u32 u32; @@ -68,7 +71,10 @@ struct netrate_exchange { #define REQUEST_ACK 0xffff +enum msg_types { MSG_DATA=1, MSG_EOF=0xffffffff}; + struct netrate_message { + u32 msg_type; u64 msg_len; /* message length (including header) */ u64 msg_seq; /* sequence number */ struct timespec msg_ts; /* time message was sent */ @@ -85,6 +91,7 @@ extern int size; extern int multicast; extern int port; extern int histogram; +extern int skip; extern char hostname[]; extern int interrupted; extern jmp_buf jmpbuf; diff --git a/receive.c b/receive.c index 798daff..edadc02 100644 - --- a/receive.c +++ b/receive.c @@ -88,6 +88,10 @@ netrate_receive(int consock) if (ret <= 0) break; + /* bail out if the other end going away */ + if (msg->msg_type == MSG_EOF) + break; + //dprintf("."); status = clock_gettime(CLOCK_MONOTONIC, ¤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@xxxxxxxxxx> Date: Thu, 16 Oct 2008 12:12:25 -0500 Subject: [PATCH] fixed nodelay option setting Signed-off-by: Clark Williams <williams@xxxxxxxxxx> - --- common.c | 20 +++++++++++--------- 1 files changed, 11 insertions(+), 9 deletions(-) diff --git a/common.c b/common.c index a990e20..5302785 100644 - --- a/common.c +++ b/common.c @@ -473,7 +473,6 @@ netrate_tx_socket(int protocol, int port, int request) { int ret; int sock; - - int val; char portstring[10]; struct addrinfo *ai, hints; struct netrate_exchange ex; @@ -506,15 +505,18 @@ netrate_tx_socket(int protocol, int port, int request) freeaddrinfo(ai); - - if (protocol == IPPROTO_TCP && nodelay == TRUE) { + if (protocol == IPPROTO_TCP) { + int val; /* set TCP_NODELAY */ - - dprintf("setting TCP_NODELAY\n"); - - val = 1; - - if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &val, sizeof(val)) < 0) { - - perror("setsockopt"); - - ret = -errno; - - close(sock); - - return ret; + if (nodelay == TRUE) { + dprintf("setting TCP_NODELAY\n"); + val = 1; + if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &val, sizeof(val)) < 0) { + perror("setsockopt"); + ret = -errno; + close(sock); + return ret; + } } } memset(&ex, 0, sizeof(ex)); - -- 1.6.0.1 - From 2bdbd044f1d1fd94f565e812b2bffdad5147087e Mon Sep 17 00:00:00 2001 From: Clark Williams <williams@xxxxxxxxxx> Date: Tue, 21 Oct 2008 20:54:33 -0500 Subject: [PATCH] renamed daemon option to listen changed DAEMON to LISTEN; changed default msg size to 536 Signed-off-by: Clark Williams <williams@xxxxxxxxxx> - --- main.c | 27 ++++++++++++++------------- netrate.h | 4 ++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/main.c b/main.c index 0293a1b..aa41637 100644 - --- a/main.c +++ b/main.c @@ -58,7 +58,7 @@ static void interrupt(int sig); static struct option long_options[] = { {"transmit", 0, 0, TX}, {"rtt", 0, 0, RTT}, - - {"daemon", 0, 0, DAEMON}, + {"listen", 0, 0, LISTEN}, {"rate", 1, 0, RATE}, {"size", 1, 0, SIZE}, {"tcp", 0, 0, TCP}, @@ -78,7 +78,7 @@ static struct option long_options[] = { void usage(void) { - - fprintf(stderr, "usage: netrate {--transmit|--rtt|--daemon} [options]\n"); + fprintf(stderr, "usage: netrate {--transmit|--rtt|--listen} [options]\n"); fprintf(stderr, " where options are:\n"); fprintf(stderr, " --rate=<Inter-Packet Interval>\n"); fprintf(stderr, " --size=<packet size>\n"); @@ -97,7 +97,7 @@ void usage(void) int - -netrate_daemon(void) +netrate_listen(void) { int ret; int servsock, sock; @@ -105,7 +105,7 @@ netrate_daemon(void) struct sockaddr_in client; struct netrate_exchange ex; - - dprintf("netrate_daemon: starting\n"); + dprintf("netrate_listen: starting\n"); servsock = netrate_rx_socket(protocol, type); if (protocol == IPPROTO_TCP) { @@ -121,7 +121,8 @@ netrate_daemon(void) dprintf("calling read for exchange\n"); ret = read(sock, &ex, sizeof(ex)); if (ret < 0) { - - fprintf(stderr, "error reading exchange message: %s\n", strerror(errno)); + fprintf(stderr, "error reading exchange message: %s\n", + strerror(errno)); close(sock); exit(-2); } @@ -232,9 +233,9 @@ int main(int argc, char **argv) break; switch(opt) { - - case DAEMON: - - role = DAEMON; - - dprintf("role == DAEMON\n"); + case LISTEN: + role = LISTEN; + dprintf("role == LISTEN\n"); break; case TX: role = TX; @@ -305,6 +306,8 @@ int main(int argc, char **argv) dprintf("setting nodelay\n"); break; case HISTOGRAM: + fprintf(stderr, "histogram option not supported yet\n"); + exit(-1); histogram = TRUE; dprintf("histogram set to true\n"); break; @@ -319,7 +322,7 @@ int main(int argc, char **argv) } } if (role == 0) { - - fprintf(stderr, "Must specifiy either --transmit, --daemon or " + fprintf(stderr, "Must specifiy either --transmit, --listen or " "--rtt options!\n"); exit(-1); } @@ -338,14 +341,12 @@ int main(int argc, char **argv) } signal(SIGINT, interrupt); - - dprintf("startup up with message size == %d\n", size); - - switch(role) { case TX: exit_val = netrate_transmit(); break; - - case DAEMON: - - exit_val = netrate_daemon(); + case LISTEN: + exit_val = netrate_listen(); break; case RTT: exit_val = netrate_rtt(); diff --git a/netrate.h b/netrate.h index 8186dc4..88a2f6d 100644 - --- a/netrate.h +++ b/netrate.h @@ -29,7 +29,7 @@ #define FALSE 0 enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, - - MULTI, PORT, HOST, DEBUG, HELP, DAEMON, + MULTI, PORT, HOST, DEBUG, HELP, LISTEN, SERVER, RTT, NODELAY, HISTOGRAM, BREAKON, SKIP, NUM_OPT_VALS, }; @@ -49,7 +49,7 @@ enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, #define NS_TO_MS(n) (NS_TO_US(n) / 1000) #define DEF_TX_RATE MS_TO_NS(100) - -#define DEF_MSG_SIZE 50 +#define DEF_MSG_SIZE 536 #define DEF_PORT 5001 /* steal the ttcp port :) */ #define MAX_BUF_SIZE 8192 #define NETRATE_MSG_DATA 0xa5 - -- 1.6.0.1 - From bdc0d3f6e90c97927a6aa736d9321b975d3b3c51 Mon Sep 17 00:00:00 2001 From: Clark Williams <williams@xxxxxxxxxx> Date: Thu, 16 Oct 2008 12:34:23 -0500 Subject: [PATCH] rearranged includes Changed order of socket includes Signed-off-by: Clark Williams <williams@xxxxxxxxxx> - --- networking.h | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diff --git a/networking.h b/networking.h index db08758..e870591 100644 - --- a/networking.h +++ b/networking.h @@ -22,13 +22,15 @@ #define __NETWORKING_H__ #include <sys/types.h> #include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <linux/tcp.h> #include <sys/time.h> #include <time.h> - -#include <netinet/in.h> - -#include <fcntl.h> - -#include <signal.h> #include <sys/un.h> #include <sys/wait.h> #include <netdb.h> - -#include <linux/tcp.h> +#include <fcntl.h> +#include <signal.h> + #endif - -- 1.6.0.1 - From 8a2c923b7345c64543e4cd4d8a19f4ca64494e1a Mon Sep 17 00:00:00 2001 From: Clark Williams <williams@xxxxxxxxxx> Date: Thu, 16 Oct 2008 12:35:18 -0500 Subject: [PATCH] move tx buffer setup don't setup tx buffers until we know we're connected Signed-off-by: Clark Williams <williams@xxxxxxxxxx> - --- transmit.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/transmit.c b/transmit.c index dd90fab..0bd414a 100644 - --- a/transmit.c +++ b/transmit.c @@ -40,10 +40,7 @@ netrate_transmit(void) struct netrate_message *msg; struct timespec ts; struct ring_buffer *r; - - int bufsize = sizeof(struct netrate_message) + size; - - - - /* setup transmit buffers */ - - r = setup_ring_buffers(10, bufsize); + int bufsize = sizeof(struct netrate_message) + size;; dprintf("setting up transmit socket\n"); sock = netrate_tx_socket(protocol, port, RX); @@ -52,6 +49,9 @@ netrate_transmit(void) return -(errno); } + /* setup transmit buffers */ + r = setup_ring_buffers(10, bufsize); + dprintf("entering transmit loop (IPI == %dms)\n", NS_TO_MS(rate)); if (clock_gettime(CLOCK_MONOTONIC, &ts)) { fprintf(stderr, "clock_gettime failed\n"); - -- 1.6.0.1 -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) iEUEARECAAYFAkj+oLEACgkQqA4JVb61b9dBoACYtn9gXlCGv4N9SKifK4UDSMsJ tACeJ6gQ05BJMzqqOvk8C5oUEXWFfIY= =VZTH -----END PGP SIGNATURE----- ÿôèº{.nÇ+?·?®??+%?Ëÿ±éݶ¥?wÿº{.nÇ+?·¥?{±þ»ÿºÇ«³ø§¶?¡Ü¨}©?²Æ zÚ&j:+v?¨þø¯ù®w¥þ?à2?Þ?¨èÚ&¢)ß¡«a¶Úÿÿûàz¿äz¹Þ?ú+?ù???Ý¢jÿ?wèþf