fixed bug with -i mode in the server

This commit is contained in:
Brian Tierney 2009-11-10 16:03:17 +00:00
parent 5083c489af
commit d44c04d478
6 changed files with 84 additions and 24 deletions

View File

@ -1,20 +1,24 @@
Current list of things to fix/add to iperf 3.0
- (-i N) mode on server does not work (bus error)
- add sanity checks on -l, -i, -t, -n, and -w options
- test -T option on server
- separate iperf_api.c into iperf_client.c and iperf_utils.c
- verify placment of all timing calls and total_bytes_sent computations
- look for 'XXX' in code and address
- add -v (version)
- much better/standard error handling throughout
- better packaging/makefile, README, LICENCE, etc files
- currently several places in the code where a linked list must be scanned to find the end.
It would be better to store a pointer to the last element.
- finish/fix receive_result_from_server()
- should this be called for TCP too, or only UDP (currently its both,
but I think it should be UDP only, or maybe a command line option for TCP
- document and verify the 'state machine'. Is it an error to send messages in the wrong order?
- e.g.: what is "STREAM_RUNNING" vs "TEST_RUNNING"??
- cleanup/fix/test UDP mode
add TCP control socket?
use clock_nanosleep() for more accurate timing in Linux?
(http://www.kernel.org/doc/man-pages/online/pages/man2/clock_nanosleep.2.html)
- add verbose and debug options
- add human readable vs machine readable output mode
(my idea on this is that "human readable" = compatable with old iperf,

View File

@ -180,5 +180,14 @@ enum
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
#define MAX_RESULT_STRING 4096
/* constants for command line arg sanity checks
*/
#define MAX_TCP_BUFFER 128 * 1024 * 1024
#define MAX_BLOCKSIZE 1024 * 1024
#define MAX_INTERVAL 60
#define MAX_TIME 3600
#define MAX_MSS 9 * 1024
#define MAX_STREAMS 128
#endif /* IPERF_API_H */

View File

@ -144,32 +144,32 @@ exchange_parameters(struct iperf_test * test)
/*************************************************************/
/**
* add_interval_list -- adds new interval to the interval_list
* add_to_interval_list -- adds new interval to the interval_list
*
*/
void
add_interval_list(struct iperf_stream_result * rp, struct iperf_interval_results temp)
add_to_interval_list(struct iperf_stream_result * rp, struct iperf_interval_results *new)
{
struct iperf_interval_results *n;
struct iperf_interval_results *ip = (struct iperf_interval_results *) malloc(sizeof(struct iperf_interval_results));
ip->bytes_transferred = temp.bytes_transferred;
ip->interval_duration = temp.interval_duration;
ip->tcpInfo = temp.tcpInfo;
ip->bytes_transferred = new->bytes_transferred;
ip->interval_duration = new->interval_duration;
ip->tcpInfo = new->tcpInfo; /* XXX: or should this be a memcpy? */
ip->next = NULL;
//printf("add_interval_list: Mbytes = %d, duration = %f \n", (int) (ip->bytes_transferred / 1000000), ip->interval_duration);
//printf("add_to_interval_list: Mbytes = %d, duration = %f \n", (int) (ip->bytes_transferred / 1000000), ip->interval_duration);
if (!rp->interval_results)
if (!rp->interval_results) /* if 1st interval */
{
rp->interval_results = ip;
} else
} else /* add to end of list */
{
n = rp->interval_results;
while (n->next) /* find the end of the list */
n = n->next;
n->next = ip;
}
ip->next = NULL;
@ -466,14 +466,14 @@ iperf_stats_callback(struct iperf_test * test)
struct iperf_stream *sp = test->streams;
struct iperf_stream_result *rp = test->streams->result;
struct iperf_interval_results *ip, temp;
struct iperf_interval_results *ip = NULL, temp;
//printf("in stats_callback: num_streams = %d \n", test->num_streams);
for (i = 0; i < test->num_streams; i++)
{
rp = sp->result;
if (!rp->interval_results)
if (!rp->interval_results) /* 1st entry in list */
{
if (test->role == 'c')
temp.bytes_transferred = rp->bytes_sent;
@ -485,14 +485,14 @@ iperf_stats_callback(struct iperf_test * test)
temp.interval_duration = timeval_diff(&sp->result->start_time, &temp.interval_time);
gettimeofday(&sp->result->end_time, NULL);
add_interval_list(rp, temp);
add_to_interval_list(rp, &temp);
} else
{
ip = sp->result->interval_results;
while (1)
{
cumulative_bytes += ip->bytes_transferred;
if (ip->next != NULL)
if (ip->next != NULL) /* find end of list */
ip = ip->next;
else
break;
@ -507,7 +507,7 @@ iperf_stats_callback(struct iperf_test * test)
temp.interval_duration = timeval_diff(&sp->result->start_time, &temp.interval_time);
gettimeofday(&sp->result->end_time, NULL);
add_interval_list(rp, temp);
add_to_interval_list(rp, &temp);
}
if (test->tcp_info)
get_tcpinfo(test, &temp);
@ -540,14 +540,12 @@ iperf_reporter_callback(struct iperf_test * test)
struct iperf_stream *sp = NULL;
iperf_size_t bytes = 0;
double start_time, end_time;
struct iperf_interval_results *ip = NULL, *ip_prev = NULL;
char *message = (char *) malloc(MAX_RESULT_STRING);
char *message_final = (char *) malloc(MAX_RESULT_STRING);
memset(message_final, 0, strlen(message_final));
struct iperf_interval_results *ip = test->streams->result->interval_results;
struct iperf_interval_results *ip_prev = ip;
sp = test->streams;
curr_state = sp->settings->state;
//printf("in iperf_reporter_callback: state = %d \n", curr_state);
@ -558,6 +556,11 @@ iperf_reporter_callback(struct iperf_test * test)
while (sp)
{ /* for each stream */
ip = sp->result->interval_results;
if (ip == NULL)
{
printf("iperf_reporter_callback Error: interval_results = NULL \n");
break;
}
while (ip->next != NULL) /* find end of list. XXX: why not just keep track of this pointer?? */
{
ip_prev = ip;
@ -957,7 +960,9 @@ iperf_run_client(struct iperf_test * test)
sp = np;
sp->settings->state = STREAM_END;
printf("sending state = STREAM_END to stream %d \n", sp->socket);
sp->snd(sp);
result = sp->snd(sp);
if (result < 0)
break;
np = sp->next;
} while (np);
//printf("Done Sending STREAM_END. \n");

View File

@ -17,10 +17,10 @@
void exchange_parameters(struct iperf_test * test);
/**
* add_interval_list -- adds new interval to the interval_list
* add_to_interval_list -- adds new interval to the interval_list
*
*/
void add_interval_list(struct iperf_stream_result * rp, struct iperf_interval_results temp);
void add_to_interval_list(struct iperf_stream_result * rp, struct iperf_interval_results *temp);
/**
* Display -- Displays interval results for test

View File

@ -187,6 +187,7 @@ iperf_run_server(struct iperf_test * test)
test->default_settings->state = TEST_RUNNING;
FD_CLR(test->listener_sock_tcp, &test->temp_set);
printf("iperf_run_server: accepted TCP connection \n");
test->num_streams++;
}
} else
{

View File

@ -118,6 +118,13 @@ main(int argc, char **argv)
break;
case 't':
test->duration = atoi(optarg);
if (test->duration > MAX_TIME)
{
fprintf(stderr, "\n Error: test duration too long. Maximum value = %d \n\n", MAX_TIME);
fprintf(stderr, usage_long1);
fprintf(stderr, usage_long2);
exit(1);
}
break;
case 'u':
test->protocol = Pudp;
@ -126,20 +133,47 @@ main(int argc, char **argv)
break;
case 'P':
test->num_streams = atoi(optarg);
if (test->num_streams > MAX_STREAMS)
{
fprintf(stderr, "\n Error: Number of parallel streams too large. Maximum value = %d \n\n", MAX_STREAMS);
fprintf(stderr, usage_long1);
fprintf(stderr, usage_long2);
exit(1);
}
break;
case 'b':
test->default_settings->rate = unit_atof(optarg);
break;
case 'l':
test->default_settings->blksize = unit_atoi(optarg);
printf("%d is the blksize\n", test->default_settings->blksize);
if (test->default_settings->blksize > MAX_BLOCKSIZE)
{
fprintf(stderr, "\n Error: Block size too large. Maximum value = %d \n\n", MAX_BLOCKSIZE);
fprintf(stderr, usage_long1);
fprintf(stderr, usage_long2);
exit(1);
}
break;
case 'w':
test->default_settings->socket_bufsize = unit_atof(optarg);
if (test->default_settings->socket_bufsize > MAX_TCP_BUFFER)
{
fprintf(stderr, "\n Error: TCP buffer too large. Maximum value = %d \n\n", MAX_TCP_BUFFER);
fprintf(stderr, usage_long1);
fprintf(stderr, usage_long2);
exit(1);
}
break;
case 'i':
test->stats_interval = atoi(optarg);
test->reporter_interval = atoi(optarg);
if (test->stats_interval > MAX_INTERVAL)
{
fprintf(stderr, "\n Error: Report interval too large. Maximum value = %d \n\n", MAX_INTERVAL);
fprintf(stderr, usage_long1);
fprintf(stderr, usage_long2);
exit(1);
}
break;
case 'n':
test->default_settings->bytes = unit_atoi(optarg);
@ -153,6 +187,13 @@ main(int argc, char **argv)
break;
case 'M':
test->default_settings->mss = atoi(optarg);
if (test->default_settings->mss > MAX_MSS)
{
fprintf(stderr, "\n Error: MSS too large. Maximum value = %d \n\n", MAX_MSS);
fprintf(stderr, usage_long1);
fprintf(stderr, usage_long2);
exit(1);
}
break;
case 'f':
test->default_settings->unit_format = *optarg;
@ -168,7 +209,7 @@ main(int argc, char **argv)
}
}
/* untill this is done.... */
/* exit until this is done.... */
if (test->protocol == Pudp) {
printf("UDP mode not yet supported. Exiting. \n");
exit(0);