added PARAM_Exchange messages and cookies to prevent test collisions
Этот коммит содержится в:
родитель
7b63081921
Коммит
89fe565493
160
src/iperf_api.c
160
src/iperf_api.c
@ -16,6 +16,7 @@
|
||||
#include <stdint.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/time.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include "iperf_api.h"
|
||||
#include "timer.h"
|
||||
@ -43,6 +44,59 @@ static struct option longopts[] =
|
||||
};
|
||||
|
||||
|
||||
void exchange_parameters(struct iperf_test *test)
|
||||
{
|
||||
int result, size = DEFAULT_TCP_BLKSIZE;
|
||||
char *buf = (char *) malloc(size);
|
||||
|
||||
struct iperf_test *temp;
|
||||
struct iperf_stream *sp;
|
||||
struct param_exchange *param = (struct param_exchange *) buf;
|
||||
|
||||
//setting up exchange parameters
|
||||
uuid_generate(test->default_settings->cookie);
|
||||
uuid_copy(param->cookie, test->default_settings->cookie);
|
||||
param->state = PARAM_EXCHANGE;
|
||||
param->blksize = test->default_settings->blksize;
|
||||
param->recv_window = test->default_settings->socket_rcv_bufsize;
|
||||
param->send_window = test->default_settings->socket_snd_bufsize;
|
||||
param->format = test->default_settings->unit_format;
|
||||
|
||||
temp = iperf_new_test();
|
||||
iperf_defaults(temp);
|
||||
temp->role = 'c';
|
||||
temp->new_stream = iperf_new_tcp_stream;
|
||||
temp->server_hostname = test->server_hostname;
|
||||
temp->server_port = test->server_port;
|
||||
|
||||
|
||||
iperf_init_test(temp);
|
||||
|
||||
sp = temp->streams;
|
||||
sp->settings->state = PARAM_EXCHANGE;
|
||||
|
||||
printf("Sending EXCHNG Request \n");
|
||||
result = send(sp->socket, buf, size , 0);
|
||||
|
||||
do{
|
||||
result = recv(sp->socket, buf, size, 0);
|
||||
} while (result == -1 && errno == EINTR);
|
||||
|
||||
if (result > 0 && buf[0] == -1)
|
||||
{
|
||||
printf("Busy server Detected\n");
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("New connection started \n");
|
||||
}
|
||||
|
||||
iperf_free_stream(temp, sp);
|
||||
iperf_free_test(temp);
|
||||
free(buf);
|
||||
|
||||
}
|
||||
|
||||
void setnonblocking(int sock)
|
||||
{
|
||||
@ -132,7 +186,6 @@ void receive_result_from_server(struct iperf_test *test)
|
||||
//Overriding actual Test parameters for result exchange
|
||||
test->protocol = Ptcp;
|
||||
test->new_stream = iperf_new_tcp_stream;
|
||||
test->default_settings->blksize = DEFAULT_TCP_BLKSIZE;
|
||||
test->num_streams= 1;
|
||||
|
||||
iperf_init_test(test);
|
||||
@ -207,7 +260,7 @@ int set_socket_options(struct iperf_stream *sp, struct iperf_test *tp)
|
||||
len = sizeof( new_mss );
|
||||
rc = setsockopt( sp->socket, IPPROTO_TCP, TCP_MAXSEG, (char*) &new_mss, len);
|
||||
if ( rc == -1) {
|
||||
perror("setsockopt");
|
||||
perror("setsockoptBING");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -271,6 +324,7 @@ int iperf_tcp_recv(struct iperf_stream *sp)
|
||||
char ch;
|
||||
int size = sp->settings->blksize;
|
||||
char *buf = (char *) malloc(size);
|
||||
struct param_exchange *param = (struct param_exchange *) buf;
|
||||
if(!buf)
|
||||
{
|
||||
perror("malloc: unable to allocate receive buffer");
|
||||
@ -282,6 +336,7 @@ int iperf_tcp_recv(struct iperf_stream *sp)
|
||||
} while (result == -1 && errno == EINTR);
|
||||
|
||||
//interprete the type of message in packet
|
||||
//-TODO = change this for Cookie implementation
|
||||
if(result > 0)
|
||||
{
|
||||
ch = buf[0];
|
||||
@ -291,6 +346,33 @@ int iperf_tcp_recv(struct iperf_stream *sp)
|
||||
// printf("result = %d state = %d\n",result, buf[0]);
|
||||
}
|
||||
|
||||
if(param->state == PARAM_EXCHANGE)
|
||||
{
|
||||
printf("PARAM_EXHANGE caught\n");
|
||||
message = param->state;
|
||||
// setting the parameters
|
||||
if(uuid_is_null(sp->settings->cookie))
|
||||
{
|
||||
uuid_copy(sp->settings->cookie, param->cookie);
|
||||
sp->settings->blksize = param->blksize;
|
||||
sp->settings->socket_rcv_bufsize = param->recv_window;
|
||||
sp->settings->unit_format = param->format;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("New connection denied\n");
|
||||
// send NO to client
|
||||
int size = DEFAULT_TCP_BLKSIZE;
|
||||
buf = (char *) malloc(size);
|
||||
buf[0] = -1;
|
||||
result = send(sp->socket, buf, size, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(message == 6)
|
||||
printf("the blksize = %d\n", sp->settings->blksize);
|
||||
|
||||
if(message == 3 || message == 8 || message == 9 )
|
||||
{
|
||||
// printf("count = %ld result = %d\n", strlen(buf), result);
|
||||
@ -382,6 +464,8 @@ int iperf_tcp_send(struct iperf_stream *sp)
|
||||
int size = sp->settings->blksize;
|
||||
|
||||
char *buf = (char *) malloc(size);
|
||||
|
||||
|
||||
if(!buf)
|
||||
{
|
||||
perror("malloc: unable to allocate transmit buffer");
|
||||
@ -389,6 +473,7 @@ int iperf_tcp_send(struct iperf_stream *sp)
|
||||
|
||||
switch(sp->settings->state)
|
||||
{
|
||||
|
||||
case STREAM_BEGIN:
|
||||
buf[0]= (STREAM_BEGIN);
|
||||
for(i=1; i < size; i++)
|
||||
@ -423,8 +508,6 @@ int iperf_tcp_send(struct iperf_stream *sp)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//applicable for 1st packet sent
|
||||
if(sp->settings->state == STREAM_BEGIN)
|
||||
{
|
||||
@ -453,6 +536,7 @@ int iperf_udp_send(struct iperf_stream *sp)
|
||||
char *buf = (char *) malloc(size);
|
||||
// this is for udp packet/jitter/lost packet measurements
|
||||
struct udp_datagram *udp = (struct udp_datagram *) buf;
|
||||
struct param_exchange *param =NULL;
|
||||
|
||||
if(!buf)
|
||||
{
|
||||
@ -497,7 +581,7 @@ int iperf_udp_send(struct iperf_stream *sp)
|
||||
break;
|
||||
}
|
||||
|
||||
// applicable for 1st packet sent
|
||||
// applicable for 1st packet sent for each stream
|
||||
if(sp->settings->state == STREAM_BEGIN)
|
||||
{
|
||||
sp->settings->state = STREAM_RUNNING;
|
||||
@ -533,6 +617,7 @@ int iperf_udp_send(struct iperf_stream *sp)
|
||||
// RESET THE TIMER
|
||||
update_timer(sp->send_timer, 0, dtargus);
|
||||
free(buf);
|
||||
param = NULL;
|
||||
|
||||
} // timer_expired_micro
|
||||
|
||||
@ -567,7 +652,7 @@ void iperf_defaults(struct iperf_test *testp)
|
||||
testp->duration = 10;
|
||||
testp->server_port = 5001;
|
||||
|
||||
testp->unit_format = 'a';
|
||||
testp->default_settings->unit_format = 'a';
|
||||
|
||||
testp->stats_interval = 0;
|
||||
testp->reporter_interval = 0;
|
||||
@ -576,6 +661,7 @@ void iperf_defaults(struct iperf_test *testp)
|
||||
testp->default_settings->blksize = DEFAULT_TCP_BLKSIZE;
|
||||
testp->default_settings->rate = RATE;
|
||||
testp->default_settings->state = TEST_START;
|
||||
testp->default_settings->mss = 0;
|
||||
}
|
||||
|
||||
void iperf_init_test(struct iperf_test *test)
|
||||
@ -626,7 +712,6 @@ void iperf_init_test(struct iperf_test *test)
|
||||
for(i = 0; i < test->num_streams; i++)
|
||||
{
|
||||
s = netdial(test->protocol, test->server_hostname, test->server_port);
|
||||
|
||||
if(s < 0)
|
||||
{
|
||||
fprintf(stderr, "netdial failed\n");
|
||||
@ -648,6 +733,8 @@ void iperf_init_test(struct iperf_test *test)
|
||||
iperf_init_stream(sp, test);
|
||||
iperf_add_stream(test, sp);
|
||||
|
||||
|
||||
|
||||
if(test->default_settings->state != RESULT_REQUEST)
|
||||
connect_msg(sp);
|
||||
|
||||
@ -746,7 +833,8 @@ char *iperf_reporter_callback(struct iperf_test *test)
|
||||
sp = sp->next;
|
||||
}
|
||||
|
||||
char *message_final = (char *) malloc((count+1) * (strlen(report_bw_jitter_loss_header) + strlen(report_bw_jitter_loss_format) + strlen(report_sum_bw_jitter_loss_format)));
|
||||
char *message_final = (char *) malloc((count+1) * (strlen(report_bw_jitter_loss_header)
|
||||
+ strlen(report_bw_jitter_loss_format) + strlen(report_sum_bw_jitter_loss_format)));
|
||||
memset(message_final,0, strlen(message_final));
|
||||
|
||||
struct iperf_interval_results *ip = test->streams->result->interval_results;
|
||||
@ -778,12 +866,12 @@ char *iperf_reporter_callback(struct iperf_test *test)
|
||||
if(test->streams->result->interval_results->next != NULL)
|
||||
{
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) (ip->bytes_transferred / (ip->interval_duration -ip_prev->interval_duration)),
|
||||
test->unit_format);
|
||||
test->default_settings->unit_format);
|
||||
sprintf(message, report_bw_format, sp->socket,ip_prev->interval_duration, ip->interval_duration, ubuf, nbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) (ip->bytes_transferred /ip->interval_duration), test->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);
|
||||
@ -795,12 +883,12 @@ char *iperf_reporter_callback(struct iperf_test *test)
|
||||
if(test->streams->result->interval_results->next != NULL)
|
||||
{
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) (ip->bytes_transferred / (ip->interval_duration -ip_prev->interval_duration)),
|
||||
test->unit_format);
|
||||
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) (ip->bytes_transferred /ip->interval_duration), test->unit_format);
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) (ip->bytes_transferred /ip->interval_duration), test->default_settings->unit_format);
|
||||
sprintf(message, report_sum_bw_format, 0.0, ip->interval_duration, ubuf, nbuf);
|
||||
}
|
||||
|
||||
@ -845,13 +933,13 @@ char *iperf_reporter_callback(struct iperf_test *test)
|
||||
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->unit_format);
|
||||
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->unit_format);
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) (sp->result->bytes_received / end_time), test->default_settings->unit_format);
|
||||
}
|
||||
|
||||
if( test->protocol == Ptcp)
|
||||
@ -884,7 +972,7 @@ char *iperf_reporter_callback(struct iperf_test *test)
|
||||
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->unit_format);
|
||||
unit_snprintf(nbuf, UNIT_LEN, (double) bytes / end_time, test->default_settings->unit_format);
|
||||
|
||||
if(test->protocol == Ptcp)
|
||||
{
|
||||
@ -957,6 +1045,7 @@ struct iperf_stream *iperf_new_stream(struct iperf_test *testp)
|
||||
|
||||
memset(sp, 0, sizeof(struct iperf_stream));
|
||||
|
||||
|
||||
sp->settings = (struct iperf_settings *) malloc(sizeof(struct iperf_settings));
|
||||
memcpy(sp->settings, testp->default_settings, sizeof(struct iperf_settings));
|
||||
|
||||
@ -1043,7 +1132,7 @@ int iperf_udp_accept(struct iperf_test *test)
|
||||
sp->socket = test->listener_sock_udp;
|
||||
|
||||
//setting noblock doesn't report back to client
|
||||
//setnonblocking( sp->socket);
|
||||
setnonblocking( sp->socket);
|
||||
|
||||
iperf_init_stream(sp, test);
|
||||
iperf_add_stream(test, sp);
|
||||
@ -1101,7 +1190,7 @@ int iperf_tcp_accept(struct iperf_test *test)
|
||||
sp = test->new_stream(test);
|
||||
|
||||
//setting noblock doesn't report back to client
|
||||
//setnonblocking(peersock);
|
||||
setnonblocking(peersock);
|
||||
|
||||
FD_SET(peersock, &test->read_set);
|
||||
test->max_fd = (test->max_fd < peersock) ? peersock : test->max_fd;
|
||||
@ -1219,7 +1308,7 @@ void iperf_run_server(struct iperf_test *test)
|
||||
while(test->default_settings->state != TEST_END)
|
||||
{
|
||||
FD_COPY(&test->read_set, &test->temp_set);
|
||||
tv.tv_sec = 50;
|
||||
tv.tv_sec = 15;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
// using select to check on multiple descriptors.
|
||||
@ -1228,6 +1317,7 @@ void iperf_run_server(struct iperf_test *test)
|
||||
if (result == 0)
|
||||
printf("SERVER IDLE : %d sec\n", (int)tv.tv_sec);
|
||||
|
||||
|
||||
else if (result < 0 && errno != EINTR)
|
||||
{
|
||||
printf("Error in select(): %s\n", strerror(errno));
|
||||
@ -1240,7 +1330,6 @@ void iperf_run_server(struct iperf_test *test)
|
||||
if (FD_ISSET(test->listener_sock_tcp, &test->temp_set))
|
||||
{
|
||||
test->protocol = Ptcp;
|
||||
test->default_settings->blksize = DEFAULT_TCP_BLKSIZE;
|
||||
test->accept = iperf_tcp_accept;
|
||||
test->new_stream = iperf_new_tcp_stream;
|
||||
test->accept(test);
|
||||
@ -1252,7 +1341,6 @@ void iperf_run_server(struct iperf_test *test)
|
||||
else if (FD_ISSET(test->listener_sock_udp, &test->temp_set) )
|
||||
{
|
||||
test->protocol = Pudp;
|
||||
test->default_settings->blksize = DEFAULT_UDP_BLKSIZE;
|
||||
test->accept = iperf_udp_accept;
|
||||
test->new_stream = iperf_new_udp_stream;
|
||||
test->accept(test);
|
||||
@ -1270,6 +1358,17 @@ void iperf_run_server(struct iperf_test *test)
|
||||
np = find_stream_by_socket(test,j);
|
||||
message = np->rcv(np);
|
||||
|
||||
if(message == PARAM_EXCHANGE || message == -1)
|
||||
{
|
||||
//copy the received settings into test
|
||||
if(message != -1)
|
||||
memcpy(test->default_settings, test->streams->settings, sizeof(struct iperf_settings));
|
||||
// FREE ALL STREAMS
|
||||
close(np->socket);
|
||||
FD_CLR(np->socket, &test->read_set);
|
||||
iperf_free_stream(test, np);
|
||||
}
|
||||
|
||||
if(message == STREAM_END)
|
||||
{
|
||||
np->settings->state = STREAM_END;
|
||||
@ -1378,7 +1477,7 @@ void iperf_run_client(struct iperf_test *test)
|
||||
while(!timer->expired(timer))
|
||||
{
|
||||
FD_COPY(&test->write_set, &test->temp_set);
|
||||
ret = select(test->max_fd+1, NULL, &test->temp_set, NULL, &tv);
|
||||
ret = select(test->max_fd+1, NULL, &test->write_set, NULL, &tv);
|
||||
if(ret < 0)
|
||||
continue;
|
||||
|
||||
@ -1440,6 +1539,7 @@ void iperf_run_client(struct iperf_test *test)
|
||||
{
|
||||
sp = np;
|
||||
sp->settings->state = STREAM_END;
|
||||
printf("sp blksize = %d \n", sp->settings->blksize);
|
||||
sp->snd(sp);
|
||||
np = sp->next;
|
||||
} while (np);
|
||||
@ -1463,7 +1563,9 @@ void iperf_run_client(struct iperf_test *test)
|
||||
// Requesting for result from Server
|
||||
receive_result_from_server(test);
|
||||
|
||||
if(test->stats_interval!= 0)
|
||||
free_timer(stats_interval);
|
||||
if(test->reporter_interval!= 0)
|
||||
free_timer(reporter_interval);
|
||||
free_timer(timer);
|
||||
}
|
||||
@ -1493,6 +1595,7 @@ main(int argc, char **argv)
|
||||
{
|
||||
char ch, role;
|
||||
struct iperf_test *test;
|
||||
int port= -1;
|
||||
|
||||
test = iperf_new_test();
|
||||
iperf_defaults(test);
|
||||
@ -1507,6 +1610,8 @@ main(int argc, char **argv)
|
||||
break;
|
||||
case 'p':
|
||||
test->server_port = atoi(optarg);
|
||||
port = test->server_port;
|
||||
|
||||
break;
|
||||
case 's':
|
||||
test->role = 's';
|
||||
@ -1527,7 +1632,7 @@ main(int argc, char **argv)
|
||||
break;
|
||||
case 'l':
|
||||
test->default_settings->blksize = unit_atoi(optarg);
|
||||
printf("%lld is the blksize\n", unit_atoi(optarg));
|
||||
printf("%d is the blksize\n", test->default_settings->blksize);
|
||||
break;
|
||||
case 'w':
|
||||
test->default_settings->socket_bufsize = unit_atof(optarg);
|
||||
@ -1545,8 +1650,7 @@ main(int argc, char **argv)
|
||||
test->default_settings->mss = atoi(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
test->unit_format = *optarg;
|
||||
printf("%c is format \n", test->unit_format);
|
||||
test->default_settings->unit_format = *optarg;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1564,8 +1668,13 @@ main(int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
|
||||
// param exchange
|
||||
if(test->role == 'c')
|
||||
exchange_parameters(test);
|
||||
|
||||
// actual test begins
|
||||
iperf_init_test(test);
|
||||
fflush(stdout);
|
||||
iperf_run(test);
|
||||
iperf_free_test(test);
|
||||
|
||||
@ -1591,6 +1700,9 @@ main(int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
|
||||
if(port != -1)
|
||||
test->server_port = port;
|
||||
|
||||
iperf_init_test(test);
|
||||
iperf_run(test);
|
||||
iperf_free_test(test);
|
||||
|
@ -31,7 +31,9 @@ struct iperf_settings
|
||||
int mss; //for TCP MSS
|
||||
int ttl;
|
||||
int tos;
|
||||
int state; // This is state of a stream/test - can use Union for this
|
||||
char unit_format; // -f
|
||||
int state; // This is state of a stream/test
|
||||
uuid_t cookie; // cookie for a stream/test
|
||||
};
|
||||
|
||||
struct iperf_stream
|
||||
@ -84,7 +86,6 @@ struct iperf_test
|
||||
int no_delay; // -N
|
||||
int print_mss; // -m
|
||||
int domain; // -V
|
||||
char unit_format; // -f
|
||||
|
||||
/* Select related parameters */
|
||||
int max_fd;
|
||||
@ -107,7 +108,6 @@ struct iperf_test
|
||||
struct iperf_settings *default_settings;
|
||||
};
|
||||
|
||||
|
||||
struct udp_datagram
|
||||
{
|
||||
int state;
|
||||
@ -117,13 +117,20 @@ struct udp_datagram
|
||||
};
|
||||
|
||||
|
||||
struct tcp_datagram
|
||||
struct param_exchange
|
||||
{
|
||||
uuid_t cookie;
|
||||
int state;
|
||||
int stream_id;
|
||||
int blksize;
|
||||
int recv_window;
|
||||
int send_window;
|
||||
int mss;
|
||||
char format;
|
||||
};
|
||||
|
||||
|
||||
void exchange_parameters(struct iperf_test *test);
|
||||
void add_interval_list(struct iperf_stream_result *rp, struct iperf_interval_results temp);
|
||||
void display_interval_list(struct iperf_stream_result *rp);
|
||||
void send_result_to_client(struct iperf_stream *sp);
|
||||
@ -148,7 +155,6 @@ int iperf_run(struct iperf_test *test);
|
||||
enum {
|
||||
Ptcp = SOCK_STREAM,
|
||||
Pudp = SOCK_DGRAM,
|
||||
|
||||
uS_TO_NS = 1000,
|
||||
RATE = 1000000,
|
||||
MAX_BUFFER_SIZE =10,
|
||||
@ -163,6 +169,7 @@ enum {
|
||||
STREAM_RUNNING = 7,
|
||||
STREAM_END = 8,
|
||||
ALL_STREAMS_END = 9,
|
||||
PARAM_EXCHANGE = 10,
|
||||
SEC_TO_US = 1000000
|
||||
|
||||
};
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user