more cleanup, lots of comments/questions/debug code added, currently broken

This commit is contained in:
Brian Tierney 2009-10-20 16:56:02 +00:00
parent 371c23d833
commit 657083f27f
6 changed files with 696 additions and 869 deletions

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,8 @@ struct iperf_interval_results
struct timeval interval_time;
float interval_duration;
#if defined(linux) || defined(__FreeBSD__)
/* include getsockopt(TCP_INFO results here for Linux and FreeBSD */
struct tcp_info tcpInfo;
struct tcp_info tcpInfo; /* getsockopt(TCP_INFO) results here for
* Linux and FreeBSD stored here */
#endif
struct iperf_interval_results *next;
void *custom_data;
@ -32,41 +32,39 @@ struct iperf_stream_result
struct iperf_settings
{
int socket_bufsize; // -w buffer size for setsockopt(), window size for TCP
int socket_snd_bufsize; // overrides bufsize in the send direction
int socket_rcv_bufsize; // overrides bufsize in the receive direction
int blksize; // -l size of each read/write, in UDP this relates directly to packet_size
uint64_t rate; // target data rate, UDP only
int socket_bufsize; /* window size for TCP */
int blksize; /* size of read/writes (-l) */
uint64_t rate; /* target data rate, UDP only */
int mss; /* for TCP MSS */
int ttl;
int tos;
iperf_size_t bytes; /* -n option */
char unit_format; /* -f */
int state; /* This is state of a stream/test */
char cookie[37];
char cookie[37]; /* XXX: why 37? This should be a constant
* -blt */
};
struct iperf_stream
{
/* configurable members */
int local_port; // local port
int remote_port; // remote machine port
struct iperf_settings *settings; // pointer to structure settings
int protocol; // protocol- TCP/UDP
int local_port;
int remote_port;
struct iperf_settings *settings; /* pointer to structure settings */
int protocol; /* TCP or UDP */
/* non configurable members */
struct iperf_stream_result *result; //structure pointer to result
int socket; // socket
struct iperf_stream_result *result; /* structure pointer to result */
int socket;
struct timer *send_timer;
char *buffer; /* data to send */
char *buffer;
/* for udp measurements - This can be a structure outside stream,
and stream can have a pointer to this */
/*
* for udp measurements - This can be a structure outside stream, and
* stream can have a pointer to this
*/
int packet_count;
int stream_id; // stream identity
int stream_id; /* stream identity */
double jitter;
double prev_transit;
int outoforder_packets;
@ -87,20 +85,19 @@ struct iperf_stream
struct iperf_test
{
char role; // 'c'lient or 's'erver -s / -c
char role; /* c' lient or 's' erver */
int protocol;
char *server_hostname; // arg of -c
int server_port; // arg of -p
int duration; // total duration of test -t
char *server_hostname; /* -c option */
int server_port;
int duration; /* total duration of test (-t flag) */
int listener_sock_tcp;
int listener_sock_udp;
/* boolen variables for Options */
int daemon; // -D
int no_delay; // -N
int print_mss; // -m
int domain; // -V
int daemon; /* -D option */
int no_delay; /* -N option */
int print_mss; /* -m option */
int domain; /* -V option */
/* Select related parameters */
int max_fd;
@ -110,17 +107,16 @@ struct iperf_test
int (*accept) (struct iperf_test *);
struct iperf_stream *(*new_stream) (struct iperf_test *);
int stats_interval; // time interval to gather stats -i
void *(*stats_callback)(struct iperf_test *); // callback function pointer for stats
int reporter_interval; // time interval for reporter
char *(*reporter_callback)(struct iperf_test *); // callback function pointer for reporter
int reporter_fd; // file descriptor for reporter
int num_streams; // total streams in the test -P
int stats_interval; /* time interval to gather stats (-i) */
void *(*stats_callback) (struct iperf_test *); /* callback function
* pointer for stats */
int reporter_interval;/* time interval for reporter */
char *(*reporter_callback) (struct iperf_test *); /* callback function
* pointer for reporter */
int reporter_fd; /* file descriptor for reporter */
int num_streams; /* total streams in the test (-P) */
int tcp_info; /* display getsockopt(TCP_INFO) results */
struct iperf_stream *streams; // pointer to list of struct stream
struct iperf_stream *streams; /* pointer to list of struct stream */
struct iperf_settings *default_settings;
};
@ -141,17 +137,23 @@ struct param_exchange
int send_window;
int mss;
char format;
char cookie[37];
char cookie[37]; /* size 37 makes total size 64 */
};
enum {
enum
{
/* default settings */
Ptcp = SOCK_STREAM,
Pudp = SOCK_DGRAM,
PORT = 5001, /* default port to listen on */
uS_TO_NS = 1000,
RATE = 1000000,
MAX_BUFFER_SIZE =10,
DEFAULT_UDP_BLKSIZE = 1470,
DEFAULT_TCP_BLKSIZE = 8192,
SEC_TO_US = 1000000,
RATE = 1024 * 1024, /* 1 Mbps */
DURATION = 10, /* seconds */
DEFAULT_UDP_BLKSIZE = 1450, /* 1 packet per ethernet frame, IPV6 too */
DEFAULT_TCP_BLKSIZE = 256 * 1024, /* default read/write block size */
/* other useful constants */
TEST_START = 1,
TEST_RUNNING = 2,
RESULT_REQUEST = 3,
@ -163,7 +165,6 @@ enum {
ALL_STREAMS_END = 9,
PARAM_EXCHANGE = 10,
ACCESS_DENIED = -1,
SEC_TO_US = 1000000,
};
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
@ -276,7 +277,7 @@ int iperf_udp_recv(struct iperf_stream *sp);
/**
* iperf_tcp_send -- sends the client data for TCP
* and the Param/result message exchanges
*returns bytes sent
* returns: bytes sent
*
*/
int iperf_tcp_send(struct iperf_stream * sp);
@ -284,7 +285,7 @@ int iperf_tcp_send(struct iperf_stream *sp);
/**
* iperf_udp_send -- sends the client data for UDP
*
*returns bytes sent
* returns: bytes sent
*
*/
int iperf_udp_send(struct iperf_stream * sp);
@ -388,4 +389,3 @@ void iperf_init_stream(struct iperf_stream *sp, struct iperf_test *testp);
*
*/
void iperf_free_stream(struct iperf_test * test, struct iperf_stream * sp);

View File

@ -8,6 +8,7 @@
#include <string.h>
/* make connection to server */
int
netdial(int proto, char *client, int port)
{
@ -16,6 +17,7 @@ netdial(int proto, char *client, int port)
struct sockaddr_in sa;
socklen_t sn;
/* XXX: should this be called server?? -blt */
if ((hent = gethostbyname(client)) == 0)
{
perror("gethostbyname");

View File

@ -1,256 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* socket.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* set/getsockopt
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
/* -------------------------------------------------------------------
* If req_mss > 0, set the TCP maximum segment size for sock.
* Otherwise leave it as the system default.
* ------------------------------------------------------------------- */
const char warn_mss_fail[] = "\
WARNING: attempt to set TCP maxmimum segment size to %d failed.\n\
Setting the MSS may not be implemented on this OS.\n";
const char warn_mss_notset[] =
"WARNING: attempt to set TCP maximum segment size to %d, but got %d\n";
void
setsock_tcp_mss(int sock, int req_mss)
{
#ifdef TCP_MAXSEG
int rc;
int new_mss;
Socklen_t len;
assert(sock != INVALID_SOCKET);
if (req_mss > 0)
{
/* set */
new_mss = req_mss;
len = sizeof(new_mss);
rc = setsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, (char *) &new_mss, len);
if (rc == SOCKET_ERROR)
{
fprintf(stderr, warn_mss_fail, new_mss);
return;
}
/* verify results */
rc = getsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, (char *) &new_mss, &len);
WARN_errno(rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG");
if (new_mss != req_mss)
{
fprintf(stderr, warn_mss_notset, req_mss, new_mss);
}
}
#endif
}
/* -------------------------------------------------------------------
* returns the TCP maximum segment size
* ------------------------------------------------------------------- */
int
getsock_tcp_mss(int sock)
{
int mss = 0;
#ifdef TCP_MAXSEG
int rc;
Socklen_t len;
assert(sock >= 0);
/* query for MSS */
len = sizeof(mss);
rc = getsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, (char *) &mss, &len);
WARN_errno(rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG");
#endif
return mss;
}
/* -------------------------------------------------------------------
* If inTCPWin > 0, set the TCP window size (via the socket buffer
* sizes) for inSock. Otherwise leave it as the system default.
*
* This must be called prior to calling listen() or connect() on
* the socket, for TCP window sizes > 64 KB to be effective.
*
* This now works on UNICOS also, by setting TCP_WINSHIFT.
* This now works on AIX, by enabling RFC1323.
* returns -1 on error, 0 on no error.
* ------------------------------------------------------------------- */
int
setsock_tcp_windowsize(int inSock, int inTCPWin, int inSend)
{
#ifdef SO_SNDBUF
int rc;
int newTCPWin;
assert(inSock >= 0);
if (inTCPWin > 0)
{
#ifdef TCP_WINSHIFT
/* UNICOS requires setting the winshift explicitly */
if (inTCPWin > 65535)
{
int winShift = 0;
int scaledWin = inTCPWin >> 16;
while (scaledWin > 0)
{
scaledWin >>= 1;
winShift++;
}
/* set TCP window shift */
rc = setsockopt(inSock, IPPROTO_TCP, TCP_WINSHIFT,
(char *) &winShift, sizeof(winShift));
if (rc < 0)
{
return rc;
}
/*
* Note: you cannot verify TCP window shift, since it returns a
* structure and not the same integer we use to set it. (ugh)
*/
}
#endif /* TCP_WINSHIFT */
#ifdef TCP_RFC1323
/*
* On AIX, RFC 1323 extensions can be set system-wide, using the 'no'
* network options command. But we can also set them per-socket, so
* let's try just in case.
*/
if (inTCPWin > 65535)
{
/* enable RFC 1323 */
int on = 1;
rc = setsockopt(inSock, IPPROTO_TCP, TCP_RFC1323,
(char *) &on, sizeof(on));
if (rc < 0)
{
return rc;
}
}
#endif /* TCP_RFC1323 */
if (!inSend)
{
/*
* receive buffer -- set note: results are verified after
* connect() or listen(), since some OS's don't show the
* corrected value until then.
*/
newTCPWin = inTCPWin;
rc = setsockopt(inSock, SOL_SOCKET, SO_RCVBUF,
(char *) &newTCPWin, sizeof(newTCPWin));
} else
{
/*
* send buffer -- set note: results are verified after connect()
* or listen(), since some OS's don't show the corrected value
* until then.
*/
newTCPWin = inTCPWin;
rc = setsockopt(inSock, SOL_SOCKET, SO_SNDBUF,
(char *) &newTCPWin, sizeof(newTCPWin));
}
if (rc < 0)
{
return rc;
}
}
#endif /* SO_SNDBUF */
return 0;
}
/* -------------------------------------------------------------------
* returns the TCP window size (on the sending buffer, SO_SNDBUF),
* or -1 on error.
* ------------------------------------------------------------------- */
int
getsock_tcp_windowsize(int inSock, int inSend)
{
int theTCPWin = 0;
#ifdef SO_SNDBUF
int rc;
Socklen_t len;
/* send buffer -- query for buffer size */
len = sizeof(theTCPWin);
if (inSend)
{
rc = getsockopt(inSock, SOL_SOCKET, SO_SNDBUF,
(char *) &theTCPWin, &len);
} else
{
rc = getsockopt(inSock, SOL_SOCKET, SO_RCVBUF,
(char *) &theTCPWin, &len);
}
if (rc < 0)
{
return rc;
}
#endif
return theTCPWin;
}

View File

@ -57,14 +57,10 @@
* removed some cruft
*/
#include <stdio.h>
#include <sys/socket.h>
#include <assert.h>
#ifdef __cplusplus
extern "C"
{
#endif
/* -------------------------------------------------------------------
* If bufsize > 0, set the TCP window size (via the socket buffer
* sizes) for sock. Otherwise leave it as the system default.
@ -75,12 +71,12 @@ extern "C"
* This now works on UNICOS also, by setting TCP_WINSHIFT.
* This now works on AIX, by enabling RFC1323.
* returns -1 on error, 0 on no error.
* ------------------------------------------------------------------- */
* -------------------------------------------------------------------
*/
int
set_tcp_windowsize(int sock, int bufsize, int dir)
{
#ifdef SO_SNDBUF
int rc;
int newbufsize;
@ -88,61 +84,18 @@ extern "C"
if (bufsize > 0)
{
#ifdef TCP_WINSHIFT
/* XXX: audit -- do we care about UNICOS? */
/* UNICOS requires setting the winshift explicitly */
if (bufsize > 65535)
{
int winshift = 0;
int scaledwin = bufsize >> 16;
while (scaledwin > 0)
{
scaledwin >>= 1;
winshift++;
}
/* set TCP window shift */
rc = setsockopt(sock, IPPROTO_TCP, TCP_WINSHIFT,
(char *) &winshift, sizeof(winshift));
if (rc < 0)
return rc;
/*
* Note: you cannot verify TCP window shift, since it returns
* a structure and not the same integer we use to set it.
* (ugh)
*/
}
#endif /* TCP_WINSHIFT */
#ifdef TCP_RFC1323
/*
* On AIX, RFC 1323 extensions can be set system-wide, using the
* 'no' network options command. But we can also set them
* per-socket, so let's try just in case.
*/
if (bufsize > 65535)
{
/* enable RFC 1323 */
int on = 1;
rc = setsockopt(sock, IPPROTO_TCP, TCP_RFC1323,
(char *) &on, sizeof(on));
if (rc < 0)
return rc;
}
#endif /* TCP_RFC1323 */
/*
* note: results are verified after connect() or listen(), since
* some OS's don't show the corrected value until then.
*/
printf("Setting TCP buffer to size: %d\n", bufsize);
newbufsize = bufsize;
rc = setsockopt(sock, SOL_SOCKET, dir, (char *) &newbufsize, sizeof newbufsize);
if (rc < 0)
return rc;
} else {
printf("Using default TCP buffer size and assuming OS will do autotuning \n");
}
#endif /* SO_SNDBUF */
return 0;
}
@ -153,11 +106,10 @@ extern "C"
* ------------------------------------------------------------------- */
int
getsock_tcp_windowsize(int sock, int dir)
get_tcp_windowsize(int sock, int dir)
{
int bufsize = 0;
#ifdef SO_SNDBUF
int rc;
socklen_t len;
@ -167,12 +119,7 @@ extern "C"
if (rc < 0)
return rc;
#endif
return bufsize;
}
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1,2 +1,2 @@
int set_tcp_windowsize(int sock, int bufsize, int dir);
int getsock_tcp_windowsize(int sock, int dir);
int get_tcp_windowsize(int sock, int dir);