more bug fixes, still needs work
Этот коммит содержится в:
родитель
c27f38e5be
Коммит
8d41fbd712
@ -72,7 +72,7 @@ struct iperf_stream
|
||||
* stream can have a pointer to this
|
||||
*/
|
||||
int packet_count;
|
||||
int stream_id; /* stream identity */
|
||||
int stream_id; /* stream identity for UDP mode */
|
||||
double jitter;
|
||||
double prev_transit;
|
||||
int outoforder_packets;
|
||||
@ -176,6 +176,7 @@ enum
|
||||
};
|
||||
|
||||
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
|
||||
#define MAX_RESULT_STRING 4096
|
||||
|
||||
#endif /* IPERF_API_H */
|
||||
|
||||
|
445
src/iperf_api.c
445
src/iperf_api.c
@ -39,36 +39,39 @@
|
||||
#include "uuid.h"
|
||||
#include "locale.h"
|
||||
|
||||
jmp_buf env; /* to handle longjmp on signal */
|
||||
jmp_buf env; /* to handle longjmp on signal */
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
/* check to see if client has sent the requested number of bytes to the server yet
|
||||
*/
|
||||
/*
|
||||
* check to see if client has sent the requested number of bytes to the
|
||||
* server yet
|
||||
*/
|
||||
|
||||
/* XXX: should probably just compute this as we go and store it in the iperf_test structure -blt */
|
||||
/*
|
||||
* XXX: should probably just compute this as we go and store it in the
|
||||
* iperf_test structure -blt
|
||||
*/
|
||||
int
|
||||
all_data_sent(struct iperf_test * test)
|
||||
all_data_sent(struct iperf_test *test)
|
||||
{
|
||||
if (test->default_settings->bytes == 0)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
uint64_t total_bytes = 0;
|
||||
else {
|
||||
uint64_t total_bytes = 0;
|
||||
struct iperf_stream *sp;
|
||||
|
||||
sp = test->streams;
|
||||
|
||||
while (sp)
|
||||
{
|
||||
while (sp) {
|
||||
total_bytes += sp->result->bytes_sent;
|
||||
sp = sp->next;
|
||||
}
|
||||
|
||||
if (total_bytes >= (test->num_streams * test->default_settings->bytes))
|
||||
{
|
||||
if (total_bytes >= (test->num_streams * test->default_settings->bytes)) {
|
||||
return 1;
|
||||
} else
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -82,16 +85,16 @@ all_data_sent(struct iperf_test * test)
|
||||
*/
|
||||
|
||||
void
|
||||
exchange_parameters(struct iperf_test * test)
|
||||
exchange_parameters(struct iperf_test *test)
|
||||
{
|
||||
int result;
|
||||
int result;
|
||||
struct iperf_stream *sp;
|
||||
struct param_exchange *param;
|
||||
|
||||
//printf("in exchange_parameters \n");
|
||||
sp = test->streams;
|
||||
sp->settings->state = PARAM_EXCHANGE;
|
||||
param = (struct param_exchange *) sp->buffer;
|
||||
param = (struct param_exchange *)sp->buffer;
|
||||
|
||||
get_uuid(test->default_settings->cookie);
|
||||
strncpy(param->cookie, test->default_settings->cookie, 37);
|
||||
@ -104,7 +107,7 @@ exchange_parameters(struct iperf_test * test)
|
||||
param->send_window = test->default_settings->socket_bufsize;
|
||||
param->format = test->default_settings->unit_format;
|
||||
|
||||
//printf(" sending exchange params: size = %d \n", (int) sizeof(struct param_exchange));
|
||||
//printf(" sending exchange params: size = %d \n", (int)sizeof(struct param_exchange));
|
||||
/* XXX: can we use iperf_tcp_send for this? that would be cleaner */
|
||||
result = send(sp->socket, sp->buffer, sizeof(struct param_exchange), 0);
|
||||
if (result < 0)
|
||||
@ -113,16 +116,14 @@ exchange_parameters(struct iperf_test * test)
|
||||
//printf("result = %d state = %d, error = %d \n", result, sp->buffer[0], errno);
|
||||
|
||||
/* get answer back from server */
|
||||
do
|
||||
{
|
||||
do {
|
||||
//printf("exchange_parameters: reading result from server .. \n");
|
||||
result = recv(sp->socket, sp->buffer, sizeof(struct param_exchange), 0);
|
||||
} while (result == -1 && errno == EINTR);
|
||||
if (result < 0)
|
||||
perror("Error getting exchange params ack from server");
|
||||
|
||||
if (result > 0 && sp->buffer[0] == ACCESS_DENIED)
|
||||
{
|
||||
if (result > 0 && sp->buffer[0] == ACCESS_DENIED) {
|
||||
fprintf(stderr, "Busy server Detected. Try again later. Exiting.\n");
|
||||
exit(-1);
|
||||
}
|
||||
@ -136,23 +137,22 @@ exchange_parameters(struct iperf_test * test)
|
||||
*/
|
||||
|
||||
void
|
||||
add_interval_list(struct iperf_stream_result * rp, struct iperf_interval_results temp)
|
||||
add_interval_list(struct iperf_stream_result *rp, struct iperf_interval_results temp)
|
||||
{
|
||||
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->interval_duration = temp.interval_duration;
|
||||
ip->tcpInfo = temp.tcpInfo;
|
||||
|
||||
//printf("add_interval_list: Mbytes = %d, duration = %f \n", (int) (ip->bytes_transferred / 1000000), ip->interval_duration);
|
||||
//printf("add_interval_list: Mbytes = %d, duration = %f \n", (int)(ip->bytes_transferred / 1000000), ip->interval_duration);
|
||||
|
||||
if (!rp->interval_results)
|
||||
{
|
||||
if (!rp->interval_results) {
|
||||
rp->interval_results = ip;
|
||||
} else
|
||||
{
|
||||
}
|
||||
else {
|
||||
n = rp->interval_results;
|
||||
while (n->next)
|
||||
n = n->next;
|
||||
@ -166,14 +166,13 @@ add_interval_list(struct iperf_stream_result * rp, struct iperf_interval_results
|
||||
|
||||
/* for debugging only */
|
||||
void
|
||||
display_interval_list(struct iperf_stream_result * rp, int tflag)
|
||||
display_interval_list(struct iperf_stream_result *rp, int tflag)
|
||||
{
|
||||
struct iperf_interval_results *n;
|
||||
|
||||
n = rp->interval_results;
|
||||
|
||||
while (n)
|
||||
{
|
||||
while (n) {
|
||||
printf("Interval = %f\tBytes transferred = %llu\n", n->interval_duration, n->bytes_transferred);
|
||||
if (tflag)
|
||||
print_tcpinfo(n);
|
||||
@ -188,19 +187,19 @@ display_interval_list(struct iperf_stream_result * rp, int tflag)
|
||||
*/
|
||||
|
||||
void
|
||||
receive_result_from_server(struct iperf_test * test)
|
||||
receive_result_from_server(struct iperf_test *test)
|
||||
{
|
||||
int result;
|
||||
int result;
|
||||
struct iperf_stream *sp;
|
||||
int size = 0;
|
||||
char *buf = NULL;
|
||||
int size = 0;
|
||||
char *buf = NULL;
|
||||
|
||||
printf("in receive_result_from_server \n");
|
||||
sp = test->streams;
|
||||
size = sp->settings->blksize; /* XXX: Is blksize really what we
|
||||
* want to use for the results? */
|
||||
|
||||
buf = (char *) malloc(size);
|
||||
buf = (char *)malloc(size);
|
||||
|
||||
printf("receive_result_from_server: send ALL_STREAMS_END to server \n");
|
||||
sp->settings->state = ALL_STREAMS_END;
|
||||
@ -213,8 +212,7 @@ receive_result_from_server(struct iperf_test * test)
|
||||
/* receive from server */
|
||||
|
||||
printf("reading results (size=%d) back from server \n", size);
|
||||
do
|
||||
{
|
||||
do {
|
||||
result = recv(sp->socket, buf, size, 0);
|
||||
} while (result == -1 && errno == EINTR);
|
||||
printf("Got size of results from server: %d \n", result);
|
||||
@ -233,17 +231,17 @@ receive_result_from_server(struct iperf_test * test)
|
||||
*/
|
||||
|
||||
void
|
||||
connect_msg(struct iperf_stream * sp)
|
||||
connect_msg(struct iperf_stream *sp)
|
||||
{
|
||||
char ipl[512], ipr[512];
|
||||
char ipl [512], ipr[512];
|
||||
|
||||
inet_ntop(AF_INET, (void *) (&((struct sockaddr_in *) & sp->local_addr)->sin_addr), (void *) ipl, sizeof(ipl));
|
||||
inet_ntop(AF_INET, (void *) (&((struct sockaddr_in *) & sp->remote_addr)->sin_addr), (void *) ipr, sizeof(ipr));
|
||||
inet_ntop(AF_INET, (void *)(&((struct sockaddr_in *)&sp->local_addr)->sin_addr), (void *)ipl, sizeof(ipl));
|
||||
inet_ntop(AF_INET, (void *)(&((struct sockaddr_in *)&sp->remote_addr)->sin_addr), (void *)ipr, sizeof(ipr));
|
||||
|
||||
printf("[%3d] local %s port %d connected to %s port %d\n",
|
||||
sp->socket,
|
||||
ipl, ntohs(((struct sockaddr_in *) & sp->local_addr)->sin_port),
|
||||
ipr, ntohs(((struct sockaddr_in *) & sp->remote_addr)->sin_port));
|
||||
ipl, ntohs(((struct sockaddr_in *)&sp->local_addr)->sin_port),
|
||||
ipr, ntohs(((struct sockaddr_in *)&sp->remote_addr)->sin_port));
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
@ -254,26 +252,23 @@ connect_msg(struct iperf_stream * sp)
|
||||
*/
|
||||
|
||||
void
|
||||
Display(struct iperf_test * test)
|
||||
Display(struct iperf_test *test)
|
||||
{
|
||||
struct iperf_stream *n;
|
||||
|
||||
n = test->streams;
|
||||
int count = 1;
|
||||
int count = 1;
|
||||
|
||||
printf("===============DISPLAY==================\n");
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (n)
|
||||
{
|
||||
while (1) {
|
||||
if (n) {
|
||||
if (test->role == 'c')
|
||||
printf("position-%d\tsp=%d\tsocket=%d\tbytes sent=%llu\n", count++, (int) n, n->socket, n->result->bytes_sent);
|
||||
printf("position-%d\tsp=%d\tsocket=%d\tbytes sent=%llu\n", count++, (int)n, n->socket, n->result->bytes_sent);
|
||||
else
|
||||
printf("position-%d\tsp=%d\tsocket=%d\tbytes received=%llu\n", count++, (int) n, n->socket, n->result->bytes_received);
|
||||
printf("position-%d\tsp=%d\tsocket=%d\tbytes received=%llu\n", count++, (int)n, n->socket, n->result->bytes_received);
|
||||
|
||||
if (n->next == NULL)
|
||||
{
|
||||
if (n->next == NULL) {
|
||||
printf("=================END====================\n");
|
||||
fflush(stdout);
|
||||
break;
|
||||
@ -291,16 +286,15 @@ iperf_new_test()
|
||||
struct iperf_test *testp;
|
||||
|
||||
printf("in iperf_new_test: reinit default settings \n");
|
||||
testp = (struct iperf_test *) malloc(sizeof(struct iperf_test));
|
||||
if (!testp)
|
||||
{
|
||||
testp = (struct iperf_test *)malloc(sizeof(struct iperf_test));
|
||||
if (!testp) {
|
||||
perror("malloc");
|
||||
return (NULL);
|
||||
}
|
||||
/* initialise everything to zero */
|
||||
memset(testp, 0, sizeof(struct iperf_test));
|
||||
|
||||
testp->default_settings = (struct iperf_settings *) malloc(sizeof(struct iperf_settings));
|
||||
testp->default_settings = (struct iperf_settings *)malloc(sizeof(struct iperf_settings));
|
||||
memset(testp->default_settings, 0, sizeof(struct iperf_settings));
|
||||
|
||||
/* return an empty iperf_test* with memory alloted. */
|
||||
@ -309,7 +303,7 @@ iperf_new_test()
|
||||
|
||||
/**************************************************************************/
|
||||
void
|
||||
iperf_defaults(struct iperf_test * testp)
|
||||
iperf_defaults(struct iperf_test *testp)
|
||||
{
|
||||
testp->protocol = Ptcp;
|
||||
testp->role = 's';
|
||||
@ -337,17 +331,15 @@ iperf_defaults(struct iperf_test * testp)
|
||||
/**************************************************************************/
|
||||
|
||||
void
|
||||
iperf_init_test(struct iperf_test * test)
|
||||
iperf_init_test(struct iperf_test *test)
|
||||
{
|
||||
char ubuf[UNIT_LEN];
|
||||
char ubuf [UNIT_LEN];
|
||||
struct iperf_stream *sp;
|
||||
int i, s = 0;
|
||||
int i , s = 0;
|
||||
|
||||
printf("in iperf_init_test \n");
|
||||
if (test->role == 's')
|
||||
{ /* server */
|
||||
if (test->protocol == Pudp)
|
||||
{
|
||||
if (test->role == 's') { /* server */
|
||||
if (test->protocol == Pudp) {
|
||||
test->listener_sock_udp = netannounce(Pudp, NULL, test->server_port);
|
||||
if (test->listener_sock_udp < 0)
|
||||
exit(0);
|
||||
@ -357,8 +349,7 @@ iperf_init_test(struct iperf_test * test)
|
||||
if (test->listener_sock_tcp < 0)
|
||||
exit(0);
|
||||
|
||||
if (test->protocol == Ptcp)
|
||||
{
|
||||
if (test->protocol == Ptcp) {
|
||||
if (set_tcp_windowsize(test->listener_sock_tcp, test->default_settings->socket_bufsize, SO_RCVBUF) < 0)
|
||||
perror("unable to set TCP window");
|
||||
}
|
||||
@ -368,29 +359,27 @@ iperf_init_test(struct iperf_test * test)
|
||||
|
||||
printf("-----------------------------------------------------------\n");
|
||||
printf("Server listening on %d\n", test->server_port);
|
||||
int x;
|
||||
int x;
|
||||
|
||||
/* make sure we got what we asked for */
|
||||
if ((x = get_tcp_windowsize(test->listener_sock_tcp, SO_RCVBUF)) < 0)
|
||||
perror("SO_RCVBUF");
|
||||
|
||||
if (test->protocol == Ptcp)
|
||||
{
|
||||
if (test->protocol == Ptcp) {
|
||||
{
|
||||
if (test->default_settings->socket_bufsize > 0)
|
||||
{
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double) x, 'A');
|
||||
if (test->default_settings->socket_bufsize > 0) {
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double)x, 'A');
|
||||
printf("TCP window size: %s\n", ubuf);
|
||||
} else
|
||||
{
|
||||
}
|
||||
else {
|
||||
printf("Using TCP Autotuning \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("-----------------------------------------------------------\n");
|
||||
|
||||
} else if (test->role == 'c')
|
||||
{ /* Client */
|
||||
}
|
||||
else if (test->role == 'c') { /* Client */
|
||||
FD_ZERO(&test->write_set);
|
||||
FD_SET(s, &test->write_set);
|
||||
|
||||
@ -398,11 +387,9 @@ iperf_init_test(struct iperf_test * test)
|
||||
* XXX: I think we need to create a TCP control socket here too for
|
||||
* UDP mode -blt
|
||||
*/
|
||||
for (i = 0; i < test->num_streams; i++)
|
||||
{
|
||||
for (i = 0; i < test->num_streams; i++) {
|
||||
s = netdial(test->protocol, test->server_hostname, test->server_port);
|
||||
if (s < 0)
|
||||
{
|
||||
if (s < 0) {
|
||||
fprintf(stderr, "netdial failed\n");
|
||||
exit(0);
|
||||
}
|
||||
@ -414,14 +401,14 @@ iperf_init_test(struct iperf_test * test)
|
||||
iperf_init_stream(sp, test);
|
||||
iperf_add_stream(test, sp);
|
||||
|
||||
connect_msg(sp); /* print connection established message */
|
||||
connect_msg(sp); /* print connection established message */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void
|
||||
iperf_free_test(struct iperf_test * test)
|
||||
iperf_free_test(struct iperf_test *test)
|
||||
{
|
||||
free(test->default_settings);
|
||||
|
||||
@ -446,23 +433,21 @@ iperf_free_test(struct iperf_test * test)
|
||||
*/
|
||||
|
||||
|
||||
void *
|
||||
iperf_stats_callback(struct iperf_test * test)
|
||||
void *
|
||||
iperf_stats_callback(struct iperf_test *test)
|
||||
{
|
||||
iperf_size_t cumulative_bytes = 0;
|
||||
int i;
|
||||
iperf_size_t cumulative_bytes = 0;
|
||||
int i;
|
||||
|
||||
struct iperf_stream *sp = test->streams;
|
||||
struct iperf_stream_result *rp = test->streams->result;
|
||||
struct iperf_interval_results *ip, temp;
|
||||
|
||||
//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;
|
||||
|
||||
if (!rp->interval_results)
|
||||
{
|
||||
if (!rp->interval_results) {
|
||||
if (test->role == 'c')
|
||||
temp.bytes_transferred = rp->bytes_sent;
|
||||
else
|
||||
@ -474,11 +459,10 @@ iperf_stats_callback(struct iperf_test * test)
|
||||
|
||||
gettimeofday(&sp->result->end_time, NULL);
|
||||
add_interval_list(rp, temp);
|
||||
} else
|
||||
{
|
||||
}
|
||||
else {
|
||||
ip = sp->result->interval_results;
|
||||
while (1)
|
||||
{
|
||||
while (1) {
|
||||
cumulative_bytes += ip->bytes_transferred;
|
||||
if (ip->next != NULL)
|
||||
ip = ip->next;
|
||||
@ -518,20 +502,17 @@ iperf_stats_callback(struct iperf_test * test)
|
||||
*
|
||||
*/
|
||||
|
||||
char *
|
||||
iperf_reporter_callback(struct iperf_test * test)
|
||||
char *
|
||||
iperf_reporter_callback(struct iperf_test *test)
|
||||
{
|
||||
int total_packets = 0, lost_packets = 0, curr_state = 0;
|
||||
char ubuf[UNIT_LEN];
|
||||
char nbuf[UNIT_LEN];
|
||||
int total_packets = 0, lost_packets = 0, curr_state = 0;
|
||||
char ubuf [UNIT_LEN];
|
||||
char nbuf [UNIT_LEN];
|
||||
struct iperf_stream *sp = test->streams;
|
||||
iperf_size_t bytes = 0;
|
||||
double start_time, end_time;
|
||||
char *message = (char *) malloc(500); /* XXX: define this size in iperf.h */
|
||||
|
||||
|
||||
char *message_final = (char *) malloc(test->num_streams * (strlen(report_bw_jitter_loss_header)
|
||||
+ strlen(report_bw_jitter_loss_format) + strlen(report_sum_bw_jitter_loss_format)));
|
||||
iperf_size_t bytes = 0;
|
||||
double start_time, end_time;
|
||||
char *message = (char *)malloc(MAX_RESULT_STRING);
|
||||
char *message_final = (char *)malloc(MAX_RESULT_STRING);
|
||||
|
||||
memset(message_final, 0, strlen(message_final));
|
||||
|
||||
@ -542,159 +523,162 @@ iperf_reporter_callback(struct iperf_test * test)
|
||||
curr_state = sp->settings->state;
|
||||
//printf("in iperf_reporter_callback: state = %d \n", curr_state);
|
||||
|
||||
if (curr_state == TEST_RUNNING)
|
||||
{
|
||||
if (curr_state == TEST_RUNNING) {
|
||||
/* print interval results */
|
||||
while (sp)
|
||||
{ /* for each stream */
|
||||
while (sp) { /* for each stream */
|
||||
ip = sp->result->interval_results;
|
||||
while (ip->next != NULL)
|
||||
{
|
||||
while (ip->next != NULL) {
|
||||
ip_prev = ip;
|
||||
ip = ip->next;
|
||||
}
|
||||
|
||||
bytes += ip->bytes_transferred;
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double) (ip->bytes_transferred), 'A');
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double)(ip->bytes_transferred), 'A');
|
||||
|
||||
if (test->streams->result->interval_results->next != NULL)
|
||||
{
|
||||
if (test->streams->result->interval_results->next != NULL) {
|
||||
unit_snprintf(nbuf, UNIT_LEN,
|
||||
(double) (ip->bytes_transferred / (ip->interval_duration - ip_prev->interval_duration)),
|
||||
(double)(ip->bytes_transferred / (ip->interval_duration - ip_prev->interval_duration)),
|
||||
test->default_settings->unit_format);
|
||||
sprintf(message, report_bw_format, sp->socket, ip_prev->interval_duration, ip->interval_duration, ubuf, nbuf);
|
||||
|
||||
|
||||
} else
|
||||
{
|
||||
}
|
||||
else {
|
||||
sprintf(message, report_bw_header);
|
||||
strcat(message_final, message);
|
||||
safe_strcat(message_final, message);
|
||||
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) (ip->bytes_transferred / ip->interval_duration), test->default_settings->unit_format);
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double)(ip->bytes_transferred / ip->interval_duration), test->default_settings->unit_format);
|
||||
sprintf(message, report_bw_format, sp->socket, 0.0, ip->interval_duration, ubuf, nbuf);
|
||||
}
|
||||
strcat(message_final, message);
|
||||
if (test->tcp_info)
|
||||
{
|
||||
if (strlen(message_final) + strlen(message) < MAX_RESULT_STRING)
|
||||
safe_strcat(message_final, message);
|
||||
else {
|
||||
printf("Error: results string too long \n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (test->tcp_info) {
|
||||
build_tcpinfo_message(ip, message);
|
||||
strcat(message_final, message);
|
||||
safe_strcat(message_final, message);
|
||||
}
|
||||
sp = sp->next;
|
||||
}
|
||||
} /* while (sp) */
|
||||
|
||||
|
||||
if (test->num_streams > 1)
|
||||
{
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double) (bytes), 'A');
|
||||
if (test->num_streams > 1) {
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double)(bytes), 'A');
|
||||
|
||||
if (test->streams->result->interval_results->next != NULL)
|
||||
{
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) (bytes / (ip->interval_duration - ip_prev->interval_duration)),
|
||||
if (test->streams->result->interval_results->next != NULL) {
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double)(bytes / (ip->interval_duration - ip_prev->interval_duration)),
|
||||
test->default_settings->unit_format);
|
||||
sprintf(message, report_sum_bw_format, ip_prev->interval_duration, ip->interval_duration, ubuf, nbuf);
|
||||
} else
|
||||
{
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) (bytes / ip->interval_duration), test->default_settings->unit_format);
|
||||
}
|
||||
else {
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double)(bytes / ip->interval_duration), test->default_settings->unit_format);
|
||||
sprintf(message, report_sum_bw_format, 0.0, ip->interval_duration, ubuf, nbuf);
|
||||
}
|
||||
strcat(message_final, message);
|
||||
if (test->tcp_info)
|
||||
{
|
||||
safe_strcat(message_final, message);
|
||||
if (test->tcp_info) {
|
||||
build_tcpinfo_message(ip, message);
|
||||
strcat(message_final, message);
|
||||
safe_strcat(message_final, message);
|
||||
}
|
||||
free(message);
|
||||
}
|
||||
}
|
||||
/* if TEST_RUNNING */
|
||||
else if (curr_state == ALL_STREAMS_END || curr_state == RESULT_REQUEST)
|
||||
{
|
||||
else if (curr_state == ALL_STREAMS_END || curr_state == RESULT_REQUEST) {
|
||||
/* if TEST_RUNNING */
|
||||
sp = test->streams;
|
||||
|
||||
while (sp)
|
||||
{
|
||||
while (sp) {
|
||||
if (test->role == 'c')
|
||||
bytes += sp->result->bytes_sent;
|
||||
else
|
||||
bytes += sp->result->bytes_received;
|
||||
|
||||
if (test->protocol == Pudp)
|
||||
{
|
||||
if (test->protocol == Pudp) {
|
||||
total_packets += sp->packet_count;
|
||||
lost_packets += sp->cnt_error;
|
||||
}
|
||||
start_time = timeval_diff(&sp->result->start_time, &sp->result->start_time);
|
||||
end_time = timeval_diff(&sp->result->start_time, &sp->result->end_time);
|
||||
|
||||
if (test->role == 'c')
|
||||
{
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double) (sp->result->bytes_sent), 'A');
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) (sp->result->bytes_sent / end_time), test->default_settings->unit_format);
|
||||
if (test->role == 'c') {
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double)(sp->result->bytes_sent), 'A');
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double)(sp->result->bytes_sent / end_time), test->default_settings->unit_format);
|
||||
|
||||
} else
|
||||
{
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double) (sp->result->bytes_received), 'A');
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) (sp->result->bytes_received / end_time), test->default_settings->unit_format);
|
||||
}
|
||||
else {
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double)(sp->result->bytes_received), 'A');
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double)(sp->result->bytes_received / end_time), test->default_settings->unit_format);
|
||||
}
|
||||
|
||||
if (test->protocol == Ptcp)
|
||||
{
|
||||
if (test->protocol == Ptcp) {
|
||||
sprintf(message, report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf);
|
||||
strcat(message_final, message);
|
||||
} else
|
||||
{ /* UDP mode */
|
||||
safe_strcat(message_final, message);
|
||||
}
|
||||
else { /* UDP mode */
|
||||
sprintf(message, report_bw_jitter_loss_format, sp->socket, start_time,
|
||||
end_time, ubuf, nbuf, sp->jitter * 1000, sp->cnt_error, sp->packet_count, (double) (100.0 * sp->cnt_error / sp->packet_count));
|
||||
strcat(message_final, message);
|
||||
end_time, ubuf, nbuf, sp->jitter * 1000, sp->cnt_error, sp->packet_count, (double)(100.0 * sp->cnt_error / sp->packet_count));
|
||||
safe_strcat(message_final, message);
|
||||
|
||||
if (test->role == 'c')
|
||||
{
|
||||
if (test->role == 'c') {
|
||||
sprintf(message, report_datagrams, sp->socket, sp->packet_count);
|
||||
strcat(message_final, message);
|
||||
safe_strcat(message_final, message);
|
||||
}
|
||||
if (sp->outoforder_packets > 0)
|
||||
printf(report_sum_outoforder, start_time, end_time, sp->cnt_error);
|
||||
}
|
||||
/*
|
||||
* XXX: we need to do something with any TCP_INFO results here
|
||||
*/
|
||||
* XXX: we need to do something with any TCP_INFO results here
|
||||
*/
|
||||
sp = sp->next;
|
||||
}
|
||||
} /* while (sp) */
|
||||
|
||||
sp = test->streams; /* reset to first socket */
|
||||
|
||||
start_time = timeval_diff(&sp->result->start_time, &sp->result->start_time);
|
||||
end_time = timeval_diff(&sp->result->start_time, &sp->result->end_time);
|
||||
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double) bytes, 'A');
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) bytes / end_time, test->default_settings->unit_format);
|
||||
unit_snprintf(ubuf, UNIT_LEN, (double)bytes, 'A');
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double)bytes / end_time, test->default_settings->unit_format);
|
||||
|
||||
if ((test->role == 'c' && test->num_streams > 1) || (test->role == 's'))
|
||||
{
|
||||
if (test->protocol == Ptcp)
|
||||
{
|
||||
if ((test->role == 'c' && test->num_streams > 1) || (test->role == 's')) {
|
||||
if (test->protocol == Ptcp) {
|
||||
sprintf(message, report_sum_bw_format, start_time, end_time, ubuf, nbuf);
|
||||
strcat(message_final, message);
|
||||
} else
|
||||
{
|
||||
sprintf(message, report_sum_bw_jitter_loss_format, start_time, end_time, ubuf, nbuf, sp->jitter, lost_packets, total_packets, (double) (100.0 * lost_packets / total_packets));
|
||||
strcat(message_final, message);
|
||||
safe_strcat(message_final, message);
|
||||
}
|
||||
else {
|
||||
sprintf(message, report_sum_bw_jitter_loss_format, start_time, end_time, ubuf, nbuf, sp->jitter, lost_packets, total_packets, (double)(100.0 * lost_packets / total_packets));
|
||||
safe_strcat(message_final, message);
|
||||
}
|
||||
|
||||
|
||||
if ((test->print_mss != 0) && (test->role == 'c'))
|
||||
{
|
||||
if ((test->print_mss != 0) && (test->role == 'c')) {
|
||||
sprintf(message, "\nThe TCP maximum segment size mss = %d \n", getsock_tcp_mss(sp->socket));
|
||||
strcat(message_final, message);
|
||||
safe_strcat(message_final, message);
|
||||
}
|
||||
free(message);
|
||||
}
|
||||
}
|
||||
free(message);
|
||||
return message_final;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void
|
||||
iperf_free_stream(struct iperf_stream * sp)
|
||||
safe_strcat(char *s1, char *s2)
|
||||
{
|
||||
//printf(" adding string %s to end of string %s \n", s1, s1);
|
||||
if (strlen(s1) + strlen(s2) < MAX_RESULT_STRING)
|
||||
strcat(s1, s2);
|
||||
else {
|
||||
printf("Error: results string too long \n");
|
||||
exit(-1); /* XXX: should return an error instead */
|
||||
//return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void
|
||||
iperf_free_stream(struct iperf_stream *sp)
|
||||
{
|
||||
free(sp->buffer);
|
||||
free(sp->settings);
|
||||
@ -705,25 +689,24 @@ iperf_free_stream(struct iperf_stream * sp)
|
||||
|
||||
/**************************************************************************/
|
||||
struct iperf_stream *
|
||||
iperf_new_stream(struct iperf_test * testp)
|
||||
iperf_new_stream(struct iperf_test *testp)
|
||||
{
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
struct iperf_stream *sp;
|
||||
|
||||
printf("in iperf_new_stream \n");
|
||||
sp = (struct iperf_stream *) malloc(sizeof(struct iperf_stream));
|
||||
if (!sp)
|
||||
{
|
||||
sp = (struct iperf_stream *)malloc(sizeof(struct iperf_stream));
|
||||
if (!sp) {
|
||||
perror("malloc");
|
||||
return (NULL);
|
||||
}
|
||||
memset(sp, 0, sizeof(struct iperf_stream));
|
||||
|
||||
printf("Allocating new stream buffer: size = %d \n", testp->default_settings->blksize);
|
||||
sp->buffer = (char *) malloc(testp->default_settings->blksize);
|
||||
sp->settings = (struct iperf_settings *) malloc(sizeof(struct iperf_settings));
|
||||
sp->buffer = (char *)malloc(testp->default_settings->blksize);
|
||||
sp->settings = (struct iperf_settings *)malloc(sizeof(struct iperf_settings));
|
||||
memcpy(sp->settings, testp->default_settings, sizeof(struct iperf_settings));
|
||||
sp->result = (struct iperf_stream_result *) malloc(sizeof(struct iperf_stream_result));
|
||||
sp->result = (struct iperf_stream_result *)malloc(sizeof(struct iperf_stream_result));
|
||||
|
||||
/* fill in buffer with random stuff */
|
||||
/* XXX: probably better to use something truely random here */
|
||||
@ -733,13 +716,14 @@ iperf_new_stream(struct iperf_test * testp)
|
||||
sp->socket = -1;
|
||||
|
||||
sp->packet_count = 0;
|
||||
sp->stream_id = (int) sp;
|
||||
sp->stream_id = (int)sp;
|
||||
sp->jitter = 0.0;
|
||||
sp->prev_transit = 0.0;
|
||||
sp->outoforder_packets = 0;
|
||||
sp->cnt_error = 0;
|
||||
|
||||
sp->send_timer = NULL;
|
||||
sp->next = NULL;
|
||||
|
||||
sp->result->interval_results = NULL;
|
||||
sp->result->bytes_received = 0;
|
||||
@ -752,23 +736,20 @@ iperf_new_stream(struct iperf_test * testp)
|
||||
|
||||
/**************************************************************************/
|
||||
void
|
||||
iperf_init_stream(struct iperf_stream * sp, struct iperf_test * testp)
|
||||
iperf_init_stream(struct iperf_stream *sp, struct iperf_test *testp)
|
||||
{
|
||||
socklen_t len;
|
||||
socklen_t len;
|
||||
|
||||
len = sizeof(struct sockaddr_in);
|
||||
|
||||
if (getsockname(sp->socket, (struct sockaddr *) & sp->local_addr, &len) < 0)
|
||||
{
|
||||
if (getsockname(sp->socket, (struct sockaddr *)&sp->local_addr, &len) < 0) {
|
||||
perror("getsockname");
|
||||
}
|
||||
if (getpeername(sp->socket, (struct sockaddr *) & sp->remote_addr, &len) < 0)
|
||||
{
|
||||
if (getpeername(sp->socket, (struct sockaddr *)&sp->remote_addr, &len) < 0) {
|
||||
perror("getpeername");
|
||||
}
|
||||
//printf("in init_stream: calling set_tcp_windowsize: %d \n", testp->default_settings->socket_bufsize);
|
||||
if (testp->protocol == Ptcp)
|
||||
{
|
||||
if (testp->protocol == Ptcp) {
|
||||
if (set_tcp_windowsize(sp->socket, testp->default_settings->socket_bufsize,
|
||||
testp->role == 's' ? SO_RCVBUF : SO_SNDBUF) < 0)
|
||||
fprintf(stderr, "unable to set window size\n");
|
||||
@ -780,16 +761,15 @@ iperf_init_stream(struct iperf_stream * sp, struct iperf_test * testp)
|
||||
|
||||
/**************************************************************************/
|
||||
int
|
||||
iperf_add_stream(struct iperf_test * test, struct iperf_stream * sp)
|
||||
iperf_add_stream(struct iperf_test *test, struct iperf_stream *sp)
|
||||
{
|
||||
struct iperf_stream *n;
|
||||
|
||||
if (!test->streams)
|
||||
{
|
||||
if (!test->streams) {
|
||||
test->streams = sp;
|
||||
return 1;
|
||||
} else
|
||||
{
|
||||
}
|
||||
else {
|
||||
n = test->streams;
|
||||
while (n->next)
|
||||
n = n->next;
|
||||
@ -810,14 +790,13 @@ iperf_add_stream(struct iperf_test * test, struct iperf_stream * sp)
|
||||
*/
|
||||
|
||||
struct iperf_stream *
|
||||
find_stream_by_socket(struct iperf_test * test, int sock)
|
||||
find_stream_by_socket(struct iperf_test *test, int sock)
|
||||
{
|
||||
struct iperf_stream *n;
|
||||
|
||||
n = test->streams;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (1) {
|
||||
if (n->socket == sock)
|
||||
break;
|
||||
|
||||
@ -840,16 +819,16 @@ catcher(int sig)
|
||||
|
||||
/**************************************************************************/
|
||||
void
|
||||
iperf_run_client(struct iperf_test * test)
|
||||
iperf_run_client(struct iperf_test *test)
|
||||
{
|
||||
int i, result = 0;
|
||||
int i , result = 0;
|
||||
struct iperf_stream *sp, *np;
|
||||
struct timer *timer, *stats_interval, *reporter_interval;
|
||||
char *result_string = NULL;
|
||||
char *prot = NULL;
|
||||
int64_t delayus, adjustus, dtargus;
|
||||
struct timeval tv;
|
||||
int ret = 0;
|
||||
struct timer *timer, *stats_interval, *reporter_interval;
|
||||
char *result_string = NULL;
|
||||
char *prot = NULL;
|
||||
int64_t delayus, adjustus, dtargus;
|
||||
struct timeval tv;
|
||||
int ret = 0;
|
||||
struct sigaction sact;
|
||||
|
||||
//printf("in iperf_run_client \n");
|
||||
@ -861,8 +840,7 @@ iperf_run_client(struct iperf_test * test)
|
||||
sact.sa_handler = catcher;
|
||||
sigaction(SIGINT, &sact, NULL);
|
||||
|
||||
if (test->protocol == Pudp)
|
||||
{
|
||||
if (test->protocol == Pudp) {
|
||||
dtargus = (int64_t) (test->default_settings->blksize) * SEC_TO_US * 8;
|
||||
dtargus /= test->default_settings->rate;
|
||||
|
||||
@ -873,8 +851,7 @@ iperf_run_client(struct iperf_test * test)
|
||||
printf("iperf_run_client: adjustus: %lld, delayus: %lld \n", adjustus, delayus);
|
||||
|
||||
sp = test->streams;
|
||||
for (i = 0; i < test->num_streams; i++)
|
||||
{
|
||||
for (i = 0; i < test->num_streams; i++) {
|
||||
sp->send_timer = new_timer(0, dtargus);
|
||||
sp = sp->next;
|
||||
}
|
||||
@ -900,11 +877,10 @@ iperf_run_client(struct iperf_test * test)
|
||||
prot, test->num_streams, test->default_settings->blksize, test->duration);
|
||||
else
|
||||
printf("Starting Test: protocol: %s, %d streams, %d byte blocks, %d bytes to send\n",
|
||||
prot, test->num_streams, test->default_settings->blksize, (int) test->default_settings->bytes);
|
||||
prot, test->num_streams, test->default_settings->blksize, (int)test->default_settings->bytes);
|
||||
|
||||
/* send data till the timer expires or bytes sent */
|
||||
while (!all_data_sent(test) && !timer->expired(timer))
|
||||
{
|
||||
while (!all_data_sent(test) && !timer->expired(timer)) {
|
||||
|
||||
#ifdef NEED_THIS /* not sure what this was for, so removed
|
||||
* -blt */
|
||||
@ -916,8 +892,7 @@ iperf_run_client(struct iperf_test * test)
|
||||
#endif
|
||||
|
||||
sp = test->streams;
|
||||
for (i = 0; i < test->num_streams; i++)
|
||||
{
|
||||
for (i = 0; i < test->num_streams; i++) {
|
||||
//printf("sending data to stream %d \n", i);
|
||||
result += sp->snd(sp);
|
||||
|
||||
@ -927,13 +902,11 @@ iperf_run_client(struct iperf_test * test)
|
||||
}
|
||||
|
||||
|
||||
if ((test->stats_interval != 0) && stats_interval->expired(stats_interval))
|
||||
{
|
||||
if ((test->stats_interval != 0) && stats_interval->expired(stats_interval)) {
|
||||
test->stats_callback(test);
|
||||
update_timer(stats_interval, test->stats_interval, 0);
|
||||
}
|
||||
if ((test->reporter_interval != 0) && reporter_interval->expired(reporter_interval))
|
||||
{
|
||||
if ((test->reporter_interval != 0) && reporter_interval->expired(reporter_interval)) {
|
||||
result_string = test->reporter_callback(test);
|
||||
puts(result_string);
|
||||
update_timer(reporter_interval, test->reporter_interval, 0);
|
||||
@ -942,7 +915,7 @@ iperf_run_client(struct iperf_test * test)
|
||||
if (setjmp(env))
|
||||
break;
|
||||
|
||||
} /* while outer timer */
|
||||
} /* while outer timer */
|
||||
/* show last interval if necessary */
|
||||
test->stats_callback(test);
|
||||
result_string = test->reporter_callback(test);
|
||||
@ -952,10 +925,10 @@ iperf_run_client(struct iperf_test * test)
|
||||
printf("Test Complete. \n");
|
||||
/* send STREAM_END packets */
|
||||
np = test->streams;
|
||||
do
|
||||
{ /* send STREAM_END to all sockets */
|
||||
do { /* send STREAM_END to all sockets */
|
||||
sp = np;
|
||||
sp->settings->state = STREAM_END;
|
||||
printf("sending state = STREAM_END to stream %d \n", sp->socket);
|
||||
sp->snd(sp);
|
||||
np = sp->next;
|
||||
} while (np);
|
||||
@ -988,8 +961,7 @@ iperf_run_client(struct iperf_test * test)
|
||||
/* Deleting all streams - CAN CHANGE FREE_STREAM FN */
|
||||
sp = test->streams;
|
||||
np = sp;
|
||||
do
|
||||
{
|
||||
do {
|
||||
sp = np;
|
||||
close(sp->socket);
|
||||
np = sp->next;
|
||||
@ -1002,4 +974,3 @@ iperf_run_client(struct iperf_test * test)
|
||||
free_timer(reporter_interval);
|
||||
free_timer(timer);
|
||||
}
|
||||
|
||||
|
@ -160,6 +160,8 @@ void iperf_free_stream(struct iperf_stream * sp);
|
||||
void get_tcpinfo(struct iperf_test *test, struct iperf_interval_results *rp);
|
||||
void print_tcpinfo(struct iperf_interval_results *);
|
||||
void build_tcpinfo_message(struct iperf_interval_results *r, char *message);
|
||||
void safe_strcat(char *s1, char *s2);
|
||||
|
||||
|
||||
|
||||
#endif /* IPERF_API_H */
|
||||
|
@ -201,15 +201,15 @@ iperf_run_server(struct iperf_test * test)
|
||||
{
|
||||
/* XXX: test this! */
|
||||
close(np->socket);
|
||||
//FD_CLR(np->socket, &test->read_set);
|
||||
FD_CLR(np->socket, &test->read_set);
|
||||
iperf_free_stream(np);
|
||||
}
|
||||
if (message == STREAM_END)
|
||||
{
|
||||
/*
|
||||
* XXX: should I expect one of these per stream. If
|
||||
* so, only timestamp the 1st one??
|
||||
* should get one of these for each stream
|
||||
*/
|
||||
/* XXX: fixme: use this timestamp for all streams */
|
||||
gettimeofday(&np->result->end_time, NULL);
|
||||
}
|
||||
if (message == RESULT_REQUEST)
|
||||
|
@ -129,6 +129,10 @@ iperf_tcp_recv(struct iperf_stream * sp)
|
||||
sp->result->bytes_received += result;
|
||||
break;
|
||||
case STREAM_END:
|
||||
size = sizeof(struct param_exchange);
|
||||
/* XXX: Fixme: neeed to read from all sockets if find a STREAM_END message */
|
||||
result = Nread(sp->socket, sp->buffer, size, Ptcp);
|
||||
break;
|
||||
case ALL_STREAMS_END:
|
||||
size = sizeof(struct param_exchange);
|
||||
result = Nread(sp->socket, sp->buffer, size, Ptcp);
|
||||
|
@ -43,7 +43,7 @@ netdial(int proto, char *client, int port)
|
||||
|
||||
if (connect(s, (struct sockaddr *) & sa, sizeof sa) < 0 && errno != EINPROGRESS)
|
||||
{
|
||||
perror("connect");
|
||||
perror("connect error");
|
||||
return (-1);
|
||||
}
|
||||
sn = sizeof sa;
|
||||
@ -51,7 +51,7 @@ netdial(int proto, char *client, int port)
|
||||
{
|
||||
return (s);
|
||||
}
|
||||
perror("connect");
|
||||
perror("getpeername error");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,8 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
|
||||
#include "iperf.h"
|
||||
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user