fixed bug with -i mode in the server
Этот коммит содержится в:
родитель
5083c489af
Коммит
d44c04d478
@ -1,20 +1,24 @@
|
|||||||
|
|
||||||
Current list of things to fix/add to iperf 3.0
|
Current list of things to fix/add to iperf 3.0
|
||||||
|
|
||||||
- (-i N) mode on server does not work (bus error)
|
- test -T option on server
|
||||||
- add sanity checks on -l, -i, -t, -n, and -w options
|
|
||||||
- separate iperf_api.c into iperf_client.c and iperf_utils.c
|
- separate iperf_api.c into iperf_client.c and iperf_utils.c
|
||||||
- verify placment of all timing calls and total_bytes_sent computations
|
- verify placment of all timing calls and total_bytes_sent computations
|
||||||
- look for 'XXX' in code and address
|
- look for 'XXX' in code and address
|
||||||
- add -v (version)
|
- add -v (version)
|
||||||
- much better/standard error handling throughout
|
- much better/standard error handling throughout
|
||||||
- better packaging/makefile, README, LICENCE, etc files
|
- 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()
|
- finish/fix receive_result_from_server()
|
||||||
- should this be called for TCP too, or only UDP (currently its both,
|
- 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
|
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?
|
- 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"??
|
- e.g.: what is "STREAM_RUNNING" vs "TEST_RUNNING"??
|
||||||
- cleanup/fix/test UDP mode
|
- 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 verbose and debug options
|
||||||
- add human readable vs machine readable output mode
|
- add human readable vs machine readable output mode
|
||||||
(my idea on this is that "human readable" = compatable with old iperf,
|
(my idea on this is that "human readable" = compatable with old iperf,
|
||||||
|
@ -180,5 +180,14 @@ enum
|
|||||||
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
|
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
|
||||||
#define MAX_RESULT_STRING 4096
|
#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 */
|
#endif /* IPERF_API_H */
|
||||||
|
|
||||||
|
@ -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
|
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 *n;
|
||||||
|
|
||||||
struct iperf_interval_results *ip = (struct iperf_interval_results *) malloc(sizeof(struct iperf_interval_results));
|
struct iperf_interval_results *ip = (struct iperf_interval_results *) malloc(sizeof(struct iperf_interval_results));
|
||||||
|
|
||||||
ip->bytes_transferred = temp.bytes_transferred;
|
ip->bytes_transferred = new->bytes_transferred;
|
||||||
ip->interval_duration = temp.interval_duration;
|
ip->interval_duration = new->interval_duration;
|
||||||
ip->tcpInfo = temp.tcpInfo;
|
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;
|
rp->interval_results = ip;
|
||||||
} else
|
} else /* add to end of list */
|
||||||
{
|
{
|
||||||
n = rp->interval_results;
|
n = rp->interval_results;
|
||||||
while (n->next) /* find the end of the list */
|
while (n->next) /* find the end of the list */
|
||||||
n = n->next;
|
n = n->next;
|
||||||
|
|
||||||
n->next = ip;
|
n->next = ip;
|
||||||
}
|
}
|
||||||
ip->next = NULL;
|
ip->next = NULL;
|
||||||
@ -466,14 +466,14 @@ iperf_stats_callback(struct iperf_test * test)
|
|||||||
|
|
||||||
struct iperf_stream *sp = test->streams;
|
struct iperf_stream *sp = test->streams;
|
||||||
struct iperf_stream_result *rp = test->streams->result;
|
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);
|
//printf("in stats_callback: num_streams = %d \n", test->num_streams);
|
||||||
for (i = 0; i < test->num_streams; i++)
|
for (i = 0; i < test->num_streams; i++)
|
||||||
{
|
{
|
||||||
rp = sp->result;
|
rp = sp->result;
|
||||||
|
|
||||||
if (!rp->interval_results)
|
if (!rp->interval_results) /* 1st entry in list */
|
||||||
{
|
{
|
||||||
if (test->role == 'c')
|
if (test->role == 'c')
|
||||||
temp.bytes_transferred = rp->bytes_sent;
|
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);
|
temp.interval_duration = timeval_diff(&sp->result->start_time, &temp.interval_time);
|
||||||
|
|
||||||
gettimeofday(&sp->result->end_time, NULL);
|
gettimeofday(&sp->result->end_time, NULL);
|
||||||
add_interval_list(rp, temp);
|
add_to_interval_list(rp, &temp);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
ip = sp->result->interval_results;
|
ip = sp->result->interval_results;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
cumulative_bytes += ip->bytes_transferred;
|
cumulative_bytes += ip->bytes_transferred;
|
||||||
if (ip->next != NULL)
|
if (ip->next != NULL) /* find end of list */
|
||||||
ip = ip->next;
|
ip = ip->next;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
@ -507,7 +507,7 @@ iperf_stats_callback(struct iperf_test * test)
|
|||||||
temp.interval_duration = timeval_diff(&sp->result->start_time, &temp.interval_time);
|
temp.interval_duration = timeval_diff(&sp->result->start_time, &temp.interval_time);
|
||||||
|
|
||||||
gettimeofday(&sp->result->end_time, NULL);
|
gettimeofday(&sp->result->end_time, NULL);
|
||||||
add_interval_list(rp, temp);
|
add_to_interval_list(rp, &temp);
|
||||||
}
|
}
|
||||||
if (test->tcp_info)
|
if (test->tcp_info)
|
||||||
get_tcpinfo(test, &temp);
|
get_tcpinfo(test, &temp);
|
||||||
@ -540,14 +540,12 @@ iperf_reporter_callback(struct iperf_test * test)
|
|||||||
struct iperf_stream *sp = NULL;
|
struct iperf_stream *sp = NULL;
|
||||||
iperf_size_t bytes = 0;
|
iperf_size_t bytes = 0;
|
||||||
double start_time, end_time;
|
double start_time, end_time;
|
||||||
|
struct iperf_interval_results *ip = NULL, *ip_prev = NULL;
|
||||||
char *message = (char *) malloc(MAX_RESULT_STRING);
|
char *message = (char *) malloc(MAX_RESULT_STRING);
|
||||||
char *message_final = (char *) malloc(MAX_RESULT_STRING);
|
char *message_final = (char *) malloc(MAX_RESULT_STRING);
|
||||||
|
|
||||||
memset(message_final, 0, strlen(message_final));
|
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;
|
sp = test->streams;
|
||||||
curr_state = sp->settings->state;
|
curr_state = sp->settings->state;
|
||||||
//printf("in iperf_reporter_callback: state = %d \n", curr_state);
|
//printf("in iperf_reporter_callback: state = %d \n", curr_state);
|
||||||
@ -558,6 +556,11 @@ iperf_reporter_callback(struct iperf_test * test)
|
|||||||
while (sp)
|
while (sp)
|
||||||
{ /* for each stream */
|
{ /* for each stream */
|
||||||
ip = sp->result->interval_results;
|
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?? */
|
while (ip->next != NULL) /* find end of list. XXX: why not just keep track of this pointer?? */
|
||||||
{
|
{
|
||||||
ip_prev = ip;
|
ip_prev = ip;
|
||||||
@ -957,7 +960,9 @@ iperf_run_client(struct iperf_test * test)
|
|||||||
sp = np;
|
sp = np;
|
||||||
sp->settings->state = STREAM_END;
|
sp->settings->state = STREAM_END;
|
||||||
printf("sending state = STREAM_END to stream %d \n", sp->socket);
|
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;
|
np = sp->next;
|
||||||
} while (np);
|
} while (np);
|
||||||
//printf("Done Sending STREAM_END. \n");
|
//printf("Done Sending STREAM_END. \n");
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
void exchange_parameters(struct iperf_test * test);
|
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
|
* Display -- Displays interval results for test
|
||||||
|
@ -187,6 +187,7 @@ iperf_run_server(struct iperf_test * test)
|
|||||||
test->default_settings->state = TEST_RUNNING;
|
test->default_settings->state = TEST_RUNNING;
|
||||||
FD_CLR(test->listener_sock_tcp, &test->temp_set);
|
FD_CLR(test->listener_sock_tcp, &test->temp_set);
|
||||||
printf("iperf_run_server: accepted TCP connection \n");
|
printf("iperf_run_server: accepted TCP connection \n");
|
||||||
|
test->num_streams++;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
45
src/main.c
45
src/main.c
@ -118,6 +118,13 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
test->duration = atoi(optarg);
|
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;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
test->protocol = Pudp;
|
test->protocol = Pudp;
|
||||||
@ -126,20 +133,47 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
test->num_streams = atoi(optarg);
|
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;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
test->default_settings->rate = unit_atof(optarg);
|
test->default_settings->rate = unit_atof(optarg);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
test->default_settings->blksize = unit_atoi(optarg);
|
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;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
test->default_settings->socket_bufsize = unit_atof(optarg);
|
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;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
test->stats_interval = atoi(optarg);
|
test->stats_interval = atoi(optarg);
|
||||||
test->reporter_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;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
test->default_settings->bytes = unit_atoi(optarg);
|
test->default_settings->bytes = unit_atoi(optarg);
|
||||||
@ -153,6 +187,13 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
test->default_settings->mss = atoi(optarg);
|
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;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
test->default_settings->unit_format = *optarg;
|
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) {
|
if (test->protocol == Pudp) {
|
||||||
printf("UDP mode not yet supported. Exiting. \n");
|
printf("UDP mode not yet supported. Exiting. \n");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user