Added more APIs for iperf_api.c and changed main.c for comments and log
Этот коммит содержится в:
родитель
061af7d9aa
Коммит
6c6757c6f8
330
src/iperf_api.c
330
src/iperf_api.c
@ -42,8 +42,6 @@ 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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static struct option longopts[] =
|
static struct option longopts[] =
|
||||||
{
|
{
|
||||||
{ "client", required_argument, NULL, 'c' },
|
{ "client", required_argument, NULL, 'c' },
|
||||||
@ -60,7 +58,6 @@ static struct option longopts[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct iperf_test *iperf_create_test()
|
struct iperf_test *iperf_create_test()
|
||||||
{
|
{
|
||||||
struct iperf_test * test;
|
struct iperf_test * test;
|
||||||
@ -96,11 +93,63 @@ struct iperf_test *iperf_create_test()
|
|||||||
|
|
||||||
void iperf_init_test(struct iperf_test *test)
|
void iperf_init_test(struct iperf_test *test)
|
||||||
{
|
{
|
||||||
|
char ubuf[UNIT_LEN];
|
||||||
|
struct iperf_stream *sp;
|
||||||
|
int i;
|
||||||
|
|
||||||
// should call internally init_stream - may be add_stream
|
if(test->role == 's')
|
||||||
|
{
|
||||||
|
test->streams->socket = netannounce(test->proto, NULL, test->streams->local_port);
|
||||||
|
if( test->streams->socket < 0)
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
//initiate for Server
|
||||||
|
iperf_init_stream(test->streams);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if(set_tcp_windowsize( test->streams->socket, (test->streams->settings->window_size, SO_RCVBUF) < 0)
|
||||||
|
{
|
||||||
|
perror("unable to set window");
|
||||||
|
return -1;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
printf("-----------------------------------------------------------\n");
|
||||||
|
printf("Server listening on %d\n", test->streams->local_port);
|
||||||
|
int x;
|
||||||
|
if((x = getsock_tcp_windowsize( test->streams->socket, SO_RCVBUF)) < 0)
|
||||||
|
perror("SO_RCVBUF");
|
||||||
|
|
||||||
|
|
||||||
|
unit_snprintf(ubuf, UNIT_LEN, (double) x, 'A');
|
||||||
|
printf("%s: %s\n",
|
||||||
|
test->proto == Ptcp ? "TCP window size" : "UDP buffer size", ubuf);
|
||||||
|
printf("-----------------------------------------------------------\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( test->role == 'c')
|
||||||
|
{
|
||||||
|
sp = test->streams;
|
||||||
|
|
||||||
|
// initiate for each client stream
|
||||||
|
for(i = 0; i < test->num_streams; i++)
|
||||||
|
{
|
||||||
|
// need to pass the client ip address currently HARDCODED - kprabhu
|
||||||
|
sp->socket = netdial(test->proto, "127.0.0.1", sp->local_port);
|
||||||
|
if(sp->socket < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "netdial failed\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
printf("The socket created for client at %d\n", sp->socket);
|
||||||
|
|
||||||
|
iperf_init_stream(sp);
|
||||||
|
|
||||||
|
if(sp->next == NULL)
|
||||||
|
break;
|
||||||
|
sp=sp->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,18 +173,26 @@ struct iperf_stream * iperf_create_stream(struct iperf_sock_opts *sockopt)
|
|||||||
sp->settings = (struct iperf_settings *)malloc(sizeof(struct iperf_settings));
|
sp->settings = (struct iperf_settings *)malloc(sizeof(struct iperf_settings));
|
||||||
settings = (struct iperf_settings *)malloc(sizeof(struct iperf_settings));
|
settings = (struct iperf_settings *)malloc(sizeof(struct iperf_settings));
|
||||||
|
|
||||||
|
sp->result = (struct iperf_stream_result *)malloc(sizeof(struct iperf_stream_result));
|
||||||
|
|
||||||
//initialise sp with 0
|
//initialise sp with 0
|
||||||
memset(sp, 0, sizeof(struct iperf_stream));
|
memset(sp, 0, sizeof(struct iperf_stream));
|
||||||
|
|
||||||
|
memset(&sp->result, 0, sizeof(struct iperf_stream_result));
|
||||||
|
|
||||||
sp->local_port = 5001;
|
sp->local_port = 5001;
|
||||||
sp->remote_port = 5001;
|
sp->remote_port = 5001;
|
||||||
|
|
||||||
memset(&sp->remote_addr, 0, sizeof(struct sockaddr_storage));
|
memset(&sp->remote_addr, 0, sizeof(struct sockaddr_storage));
|
||||||
memset(&sp->local_addr, 0, sizeof(struct sockaddr_storage));
|
memset(&sp->local_addr, 0, sizeof(struct sockaddr_storage));
|
||||||
|
|
||||||
|
|
||||||
((struct iperf_settings *)(sp->settings))->options = sockopt;
|
((struct iperf_settings *)(sp->settings))->options = sockopt;
|
||||||
|
|
||||||
|
sp->socket = -1;
|
||||||
|
|
||||||
|
sp->result->bytes_received = 0;
|
||||||
|
sp->result->bytes_sent = 0;
|
||||||
|
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,9 +210,13 @@ struct iperf_stream * iperf_create_tcp_stream(int window, struct iperf_sock_opts
|
|||||||
sp->settings = (struct iperf_tcp_settings *)malloc(sizeof(struct iperf_tcp_settings));
|
sp->settings = (struct iperf_tcp_settings *)malloc(sizeof(struct iperf_tcp_settings));
|
||||||
tcp_settings = (struct iperf_tcp_settings *)malloc(sizeof(struct iperf_tcp_settings));
|
tcp_settings = (struct iperf_tcp_settings *)malloc(sizeof(struct iperf_tcp_settings));
|
||||||
|
|
||||||
|
sp->result = (struct iperf_stream_result *)malloc(sizeof(struct iperf_stream_result));
|
||||||
|
|
||||||
//initialise sp with 0
|
//initialise sp with 0
|
||||||
memset(sp, 0, sizeof(struct iperf_stream));
|
memset(sp, 0, sizeof(struct iperf_stream));
|
||||||
|
|
||||||
|
memset(&sp->result, 0, sizeof(struct iperf_stream_result));
|
||||||
|
|
||||||
sp->local_port = 5001;
|
sp->local_port = 5001;
|
||||||
sp->remote_port = 5001;
|
sp->remote_port = 5001;
|
||||||
|
|
||||||
@ -164,9 +225,11 @@ struct iperf_stream * iperf_create_tcp_stream(int window, struct iperf_sock_opts
|
|||||||
|
|
||||||
tcp_settings->options = sockopt;
|
tcp_settings->options = sockopt;
|
||||||
tcp_settings->window_size =window;
|
tcp_settings->window_size =window;
|
||||||
|
|
||||||
sp->settings = tcp_settings;
|
sp->settings = tcp_settings;
|
||||||
printf("memory allocated - TCP\n");
|
|
||||||
|
sp->socket = -1;
|
||||||
|
|
||||||
|
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,9 +245,13 @@ struct iperf_stream * iperf_create_udp_stream(int rate, int size, struct iperf_s
|
|||||||
|
|
||||||
sp->settings = (struct iperf_udp_settings *)malloc(sizeof(struct iperf_udp_settings));
|
sp->settings = (struct iperf_udp_settings *)malloc(sizeof(struct iperf_udp_settings));
|
||||||
udp_settings = (struct iperf_udp_settings *)malloc(sizeof(struct iperf_udp_settings));
|
udp_settings = (struct iperf_udp_settings *)malloc(sizeof(struct iperf_udp_settings));
|
||||||
|
|
||||||
|
sp->result = (struct iperf_stream_result *)malloc(sizeof(struct iperf_stream_result));
|
||||||
//initialise sp with 0
|
//initialise sp with 0
|
||||||
memset(sp, 0, sizeof(struct iperf_stream));
|
memset(sp, 0, sizeof(struct iperf_stream));
|
||||||
|
|
||||||
|
memset(&sp->result, 0, sizeof(struct iperf_stream_result));
|
||||||
|
|
||||||
sp->local_port = 5001;
|
sp->local_port = 5001;
|
||||||
sp->remote_port = 5001;
|
sp->remote_port = 5001;
|
||||||
|
|
||||||
@ -195,9 +262,47 @@ struct iperf_stream * iperf_create_udp_stream(int rate, int size, struct iperf_s
|
|||||||
udp_settings->rate = rate;
|
udp_settings->rate = rate;
|
||||||
udp_settings->packet_size = size;
|
udp_settings->packet_size = size;
|
||||||
|
|
||||||
|
sp->settings = udp_settings;
|
||||||
|
|
||||||
|
sp->socket = -1;
|
||||||
|
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iperf_init_stream(struct iperf_stream *sp)
|
||||||
|
{
|
||||||
|
socklen_t len;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
len = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
|
if(getsockname(sp->socket, (struct sockaddr *) &sp->local_addr, &len) < 0)
|
||||||
|
{
|
||||||
|
perror("getsockname");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//stores the socket id.
|
||||||
|
if(getpeername(sp->socket, (struct sockaddr *) &sp->remote_addr, &len) < 0)
|
||||||
|
{
|
||||||
|
perror("getpeername");
|
||||||
|
free(sp);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
x = getsock_tcp_windowsize(sp->socket, SO_RCVBUF);
|
||||||
|
if(x < 0)
|
||||||
|
perror("SO_RCVBUF");
|
||||||
|
|
||||||
|
printf("RCV: %d\n", x);
|
||||||
|
|
||||||
|
x = getsock_tcp_windowsize(sp->socket, SO_SNDBUF);
|
||||||
|
if(x < 0)
|
||||||
|
perror("SO_SNDBUF");
|
||||||
|
|
||||||
|
printf("SND: %d\n", x);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int iperf_add_stream(struct iperf_test *test, struct iperf_stream *sp)
|
int iperf_add_stream(struct iperf_test *test, struct iperf_stream *sp)
|
||||||
{
|
{
|
||||||
@ -219,18 +324,190 @@ int iperf_add_stream(struct iperf_test *test, struct iperf_stream *sp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int *recv_stream(struct iperf_stream *sp)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
struct timeval tv;
|
||||||
|
char ubuf[UNIT_LEN];
|
||||||
|
fd_set read_set, temp_set;
|
||||||
|
int maxfd,result;
|
||||||
|
|
||||||
|
FD_ZERO(&read_set);
|
||||||
|
FD_SET(sp->socket, &read_set);
|
||||||
|
maxfd = sp->socket;
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
memcpy(&temp_set, &read_set,sizeof(temp_set));
|
||||||
|
tv.tv_sec = 50; // timeout interval in seconds
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
// using select to check on multiple descriptors.
|
||||||
|
result = select(maxfd + 1, &temp_set, NULL, NULL, &tv);
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
printf("select() timed out!\n");
|
||||||
|
|
||||||
|
else if (result < 0 && errno != EINTR)
|
||||||
|
printf("Error in select(): %s\n", strerror(errno));
|
||||||
|
|
||||||
|
else if (result > 0)
|
||||||
|
{
|
||||||
|
if (FD_ISSET(sp->socket, &temp_set))
|
||||||
|
{
|
||||||
|
if(sp->protocol == Ptcp)
|
||||||
|
maxfd = tcp_server_accept(&sp, maxfd, &read_set); // need to change the arguements
|
||||||
|
|
||||||
|
else if(sp->protocol == Pudp)
|
||||||
|
maxfd = udp_server_accept(&sp, maxfd, &read_set); // need to change the arguements
|
||||||
|
|
||||||
|
FD_CLR(sp->socket, &temp_set);
|
||||||
|
|
||||||
|
Display();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sp->protocol == Ptcp)
|
||||||
|
tcp_server_thread(maxfd, &temp_set, &read_set, sp); // need to change the arguements
|
||||||
|
|
||||||
|
else if( sp->protocol == Pudp)
|
||||||
|
udp_server_thread(maxfd, &temp_set, &read_set, sp); // need to change the arguements
|
||||||
|
|
||||||
|
} // end else if (result > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// return ?
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int *send_stream( struct iperf_stream *sp)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
int s, i;
|
||||||
|
struct iperf_stream *sp;
|
||||||
|
char *buf;
|
||||||
|
int64_t delayns, adjustns, dtargns;
|
||||||
|
struct timeval before, after;
|
||||||
|
fd_set write_set;
|
||||||
|
struct timeval tv;
|
||||||
|
int maxfd,ret=0;
|
||||||
|
|
||||||
|
if (test->proto == Pudp)
|
||||||
|
{
|
||||||
|
dtargns = (int64_t)settings->bufsize * SEC_TO_NS * 8;
|
||||||
|
dtargns /= settings->bw;
|
||||||
|
|
||||||
|
assert(dtargns != 0);
|
||||||
|
|
||||||
|
if(gettimeofday(&before, 0) < 0) {
|
||||||
|
perror("gettimeofday");
|
||||||
|
}
|
||||||
|
|
||||||
|
delayns = dtargns;
|
||||||
|
adjustns = 0;
|
||||||
|
printf("%lld adj %lld delay\n", adjustns, delayns);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// most of the current Client function goes here.
|
||||||
|
ret = select(maxfd+1, NULL, &write_set, NULL, &tv);
|
||||||
|
|
||||||
|
if(ret<0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sp = test->streams;
|
||||||
|
for(i=0;i<settings->threads;i++)
|
||||||
|
{
|
||||||
|
if(FD_ISSET(sp->sock, &write_set))
|
||||||
|
{
|
||||||
|
send(sp->sock, buf, sp->settings->bufsize, 0);
|
||||||
|
sp->result->bytes_out += sp->settings->bufsize;
|
||||||
|
|
||||||
|
if (test->proto == Pudp)
|
||||||
|
{
|
||||||
|
if(delayns > 0)
|
||||||
|
delay(delayns);
|
||||||
|
|
||||||
|
if(gettimeofday(&after, 0) < 0) {
|
||||||
|
perror("gettimeofday");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
adjustns = dtargns;
|
||||||
|
adjustns += (before.tv_sec - after.tv_sec) * SEC_TO_NS;
|
||||||
|
adjustns += (before.tv_usec - after.tv_usec) * uS_TO_NS;
|
||||||
|
|
||||||
|
if( adjustns > 0 || delayns > 0) {
|
||||||
|
printf("%lld adj %lld delay\n", adjustns, delayns);
|
||||||
|
delayns += adjustns;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&before, &after, sizeof before);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sp->next==NULL)
|
||||||
|
break;
|
||||||
|
sp=sp->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function would be big.
|
||||||
|
int iperf_run(struct iperf_test *test)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
int rc;
|
||||||
|
struct *timer timer;
|
||||||
|
|
||||||
|
// don't see any other way of assigning this anywhere
|
||||||
|
test->streams->protocol = test->proto;
|
||||||
|
|
||||||
|
if(test->role == 's')
|
||||||
|
{
|
||||||
|
init(test->streams, test);
|
||||||
|
|
||||||
|
rc = recv_stream(test->streams);
|
||||||
|
|
||||||
|
}
|
||||||
|
else (if test->role == 'c')
|
||||||
|
{
|
||||||
|
timer = new_timer(test->duration, 0);
|
||||||
|
|
||||||
|
while(!timer->expired(timer))
|
||||||
|
{
|
||||||
|
|
||||||
|
init(test->streams, test);
|
||||||
|
|
||||||
|
// need change the send_Stream() arguements to accept test/ only test
|
||||||
|
rc = send_stream(test->streams,test);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int rc;
|
|
||||||
char ch;
|
char ch;
|
||||||
struct iperf_test *test;
|
struct iperf_test *test;
|
||||||
struct iperf_stream *sp;
|
struct iperf_stream *sp, temp;
|
||||||
struct iperf_sock_opts *sockopt=NULL;
|
struct iperf_sock_opts *sockopt=NULL;
|
||||||
int window= 1024,rate,size;
|
int window= 1024*1024, size;
|
||||||
int i,bw, buffer_size;
|
int i, bw = 100000, buffer_size;
|
||||||
|
|
||||||
|
|
||||||
sockopt = (struct iperf_sock_opts *)malloc(sizeof(struct iperf_sock_opts));
|
sockopt = (struct iperf_sock_opts *)malloc(sizeof(struct iperf_sock_opts));
|
||||||
@ -242,11 +519,12 @@ main(int argc, char **argv)
|
|||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'c':
|
case 'c':
|
||||||
test->role = 'c';
|
test->role = 'c';
|
||||||
//test->remote_ip_addr->ss_len =(int) malloc(strlen(optarg));
|
// remote_ip_addr
|
||||||
//(struct sockaddr_in)(test->remote_ip_addr), (struct sockaddr_in)optarg;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
test->streams->remote_port = atoi(optarg);
|
temp.remote_port = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
test->role = 's';
|
test->role = 's';
|
||||||
@ -279,6 +557,7 @@ main(int argc, char **argv)
|
|||||||
for(i=0;i<test->num_streams;i++)
|
for(i=0;i<test->num_streams;i++)
|
||||||
{
|
{
|
||||||
sp = iperf_create_tcp_stream(window, sockopt);
|
sp = iperf_create_tcp_stream(window, sockopt);
|
||||||
|
sp->remote_port = temp.remote_port;
|
||||||
iperf_add_stream(test,sp);
|
iperf_add_stream(test,sp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -286,7 +565,8 @@ main(int argc, char **argv)
|
|||||||
case Pudp:
|
case Pudp:
|
||||||
for(i=0;i<test->num_streams;i++)
|
for(i=0;i<test->num_streams;i++)
|
||||||
{
|
{
|
||||||
sp = iperf_create_udp_stream(rate, size, sockopt);
|
sp = iperf_create_udp_stream(bw, size, sockopt);
|
||||||
|
sp->remote_port = temp.remote_port;
|
||||||
iperf_add_stream(test,sp);
|
iperf_add_stream(test,sp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -295,6 +575,7 @@ main(int argc, char **argv)
|
|||||||
for(i=0;i<test->num_streams;i++)
|
for(i=0;i<test->num_streams;i++)
|
||||||
{
|
{
|
||||||
sp = iperf_create_stream(sockopt);
|
sp = iperf_create_stream(sockopt);
|
||||||
|
sp->remote_port = temp.remote_port;
|
||||||
iperf_add_stream(test,sp);
|
iperf_add_stream(test,sp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -304,10 +585,29 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
for(i=0;i<test->num_streams;i++)
|
for(i=0;i<test->num_streams;i++)
|
||||||
{
|
{
|
||||||
|
if(test->proto == Ptcp)
|
||||||
printf(" %d is the windowsize for tcp\n",((struct iperf_tcp_settings *)(sp->settings))->window_size );
|
printf(" %d is the windowsize for tcp\n",((struct iperf_tcp_settings *)(sp->settings))->window_size );
|
||||||
|
|
||||||
|
else
|
||||||
|
printf(" %d is the rate for udp\n",((struct iperf_udp_settings *)(sp->settings))->rate );
|
||||||
if(sp->next!= NULL)
|
if(sp->next!= NULL)
|
||||||
sp = sp->next;
|
sp = sp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printf("role = %s\n", (test->role == 's')?"Server":"Client");
|
||||||
|
printf("duration = %d\n", test->duration);
|
||||||
|
printf("protocol = %s\n", (test->proto == Ptcp)?"TCP":"UDP");
|
||||||
|
printf("interval = %d\n", test->stats_interval);
|
||||||
|
printf("Local port = %d\n", test->streams->local_port);
|
||||||
|
printf("Remote port = %d\n", test->streams->remote_port);
|
||||||
|
printf("Parallel streams = %d\n", test->num_streams);
|
||||||
|
|
||||||
|
// depending whether client or server, we would call function ?
|
||||||
|
iperf_init_test(test);
|
||||||
|
// init_test and init_stream functions
|
||||||
|
//run function
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -55,7 +55,6 @@ struct iperf_stream
|
|||||||
void *settings; // pointer to structure settings
|
void *settings; // pointer to structure settings
|
||||||
int protocol; // protocol- TCP/UDP
|
int protocol; // protocol- TCP/UDP
|
||||||
|
|
||||||
|
|
||||||
/* non configurable members */
|
/* non configurable members */
|
||||||
struct iperf_stream_result *result; //structure pointer to result
|
struct iperf_stream_result *result; //structure pointer to result
|
||||||
|
|
||||||
@ -65,8 +64,8 @@ struct iperf_stream
|
|||||||
struct sockaddr_storage remote_addr;
|
struct sockaddr_storage remote_addr;
|
||||||
|
|
||||||
int *(*init)(struct iperf_stream *stream);
|
int *(*init)(struct iperf_stream *stream);
|
||||||
int *(*recv)(struct iperf_stream *stream);
|
int *(*recv_stream)(struct iperf_stream *stream);
|
||||||
int *(*send)(struct iperf_stream *stream);
|
int *(*send_stream)(struct iperf_stream *stream);
|
||||||
int *(*update_stats)(struct iperf_stream *stream);
|
int *(*update_stats)(struct iperf_stream *stream);
|
||||||
|
|
||||||
struct iperf_stream *next;
|
struct iperf_stream *next;
|
||||||
|
93
src/main.c
93
src/main.c
@ -1,10 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* iperfjd -- greatly simplified version of iperf with the same interface
|
* iperf3
|
||||||
* semantics
|
|
||||||
* kprabhu - 2nd june 2009 - server side code with select
|
|
||||||
* with updated linked list functions.
|
|
||||||
*kprabhu - 3rd June 2009 - client side code with select
|
|
||||||
*kprabhu - 5th June 2009 - created functions for Server TCP/UDP connections
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -45,7 +40,7 @@ enum {
|
|||||||
uS_TO_NS = 1000,
|
uS_TO_NS = 1000,
|
||||||
|
|
||||||
MAX_BUFFER_SIZE =10,
|
MAX_BUFFER_SIZE =10,
|
||||||
DEFAULT_UDP_BUFSIZE = 1,
|
DEFAULT_UDP_BUFSIZE = 1470,
|
||||||
DEFAULT_TCP_BUFSIZE = 8192
|
DEFAULT_TCP_BUFSIZE = 8192
|
||||||
};
|
};
|
||||||
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
|
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
|
||||||
@ -73,7 +68,6 @@ struct iperf_stream
|
|||||||
struct iperf_stream *next;
|
struct iperf_stream *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Run routines for TCP and UDP- will be called by pthread_create() indirectly
|
|
||||||
void *udp_client_thread(struct iperf_stream *sp);
|
void *udp_client_thread(struct iperf_stream *sp);
|
||||||
void *udp_server_thread(int maxfd, fd_set *temp_set, fd_set *read_set);
|
void *udp_server_thread(int maxfd, fd_set *temp_set, fd_set *read_set);
|
||||||
int udp_server_accept(int *s, int maxfd, fd_set *read_set, struct iperf_settings *settings);
|
int udp_server_accept(int *s, int maxfd, fd_set *read_set, struct iperf_settings *settings);
|
||||||
@ -176,10 +170,8 @@ new_stream(int s, struct iperf_settings *settings)
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//initialise sp with 0
|
|
||||||
memset(sp, 0, sizeof(struct iperf_stream));
|
memset(sp, 0, sizeof(struct iperf_stream));
|
||||||
|
|
||||||
// copy settings and passed socket into stream
|
|
||||||
sp->settings = settings;
|
sp->settings = settings;
|
||||||
sp->sock = s;
|
sp->sock = s;
|
||||||
|
|
||||||
@ -210,7 +202,7 @@ new_stream(int s, struct iperf_settings *settings)
|
|||||||
perror("inet_pton");
|
perror("inet_pton");
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets appropriate function pointer
|
//not needed now
|
||||||
switch (settings->proto) {
|
switch (settings->proto) {
|
||||||
case Ptcp:
|
case Ptcp:
|
||||||
sp->client = (void *) tcp_client_thread;
|
sp->client = (void *) tcp_client_thread;
|
||||||
@ -274,8 +266,8 @@ free_stream(struct iperf_stream *sp)
|
|||||||
prev = streams;
|
prev = streams;
|
||||||
start = streams;
|
start = streams;
|
||||||
|
|
||||||
if(streams->sock==sp->sock)
|
if(streams->sock==sp->sock){
|
||||||
{
|
|
||||||
streams=streams->next;
|
streams=streams->next;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -285,15 +277,15 @@ free_stream(struct iperf_stream *sp)
|
|||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
if(start->sock==sp->sock)
|
if(start->sock==sp->sock){
|
||||||
{
|
|
||||||
prev->next = sp->next;
|
prev->next = sp->next;
|
||||||
free(sp);
|
free(sp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(start->next!=NULL)
|
if(start->next!=NULL){
|
||||||
{
|
|
||||||
start=start->next;
|
start=start->next;
|
||||||
prev=prev->next;
|
prev=prev->next;
|
||||||
}
|
}
|
||||||
@ -312,18 +304,19 @@ update_stream(int j, int result)
|
|||||||
{
|
{
|
||||||
struct iperf_stream *n;
|
struct iperf_stream *n;
|
||||||
n=streams;
|
n=streams;
|
||||||
|
|
||||||
//find the correct stream for update
|
//find the correct stream for update
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
if(n->sock == j)
|
if(n->sock == j)
|
||||||
{
|
{
|
||||||
|
n->bytes_in= n->bytes_in + result;
|
||||||
n->bytes_in+= result; //update the byte count
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n->next==NULL)
|
if(n->next==NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
n = n->next;
|
n = n->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,6 +339,30 @@ void connect_msg(struct iperf_stream *sp)
|
|||||||
sp->peer_addr, htons(sp->peer.sin_port));
|
sp->peer_addr, htons(sp->peer.sin_port));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------
|
||||||
|
* Make socket non-blocking
|
||||||
|
* -------------------------------------------------------*/
|
||||||
|
|
||||||
|
void setnonblocking(int sock)
|
||||||
|
{
|
||||||
|
int opts;
|
||||||
|
/*
|
||||||
|
opts = fcntl(sock,F_GETFL);
|
||||||
|
if (opts < 0) {
|
||||||
|
perror("fcntl(F_GETFL)");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
opts = (opts | O_NONBLOCK);
|
||||||
|
if (fcntl(sock,F_SETFL,opts) < 0)
|
||||||
|
{
|
||||||
|
perror("fcntl(F_SETFL)");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------
|
/*--------------------------------------------------------
|
||||||
* UDP client functionality. - NOT USED
|
* UDP client functionality. - NOT USED
|
||||||
-------------------------------------------------------*/
|
-------------------------------------------------------*/
|
||||||
@ -424,8 +441,10 @@ udp_server_thread(int maxfd, fd_set *temp_set, fd_set *read_set)
|
|||||||
int j,result;
|
int j,result;
|
||||||
struct iperf_stream *n;
|
struct iperf_stream *n;
|
||||||
|
|
||||||
|
|
||||||
for (j=0; j<maxfd+1; j++){
|
for (j=0; j<maxfd+1; j++){
|
||||||
|
|
||||||
|
n = streams;
|
||||||
if (FD_ISSET(j, temp_set)){
|
if (FD_ISSET(j, temp_set)){
|
||||||
|
|
||||||
do{
|
do{
|
||||||
@ -490,7 +509,6 @@ int udp_server_accept(int *s, int maxfd, fd_set *read_set, struct iperf_settings
|
|||||||
sp->bytes_in += sz;
|
sp->bytes_in += sz;
|
||||||
add_stream(sp);
|
add_stream(sp);
|
||||||
|
|
||||||
printf("calling netannounce within function \n");
|
|
||||||
*s = netannounce(settings->proto, NULL, settings->port);
|
*s = netannounce(settings->proto, NULL, settings->port);
|
||||||
if(*s < 0)
|
if(*s < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -517,29 +535,6 @@ void
|
|||||||
tcp_report(int final)
|
tcp_report(int final)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------
|
|
||||||
* Make socket non-blocking
|
|
||||||
* -------------------------------------------------------*/
|
|
||||||
|
|
||||||
void setnonblocking(int sock)
|
|
||||||
{
|
|
||||||
int opts;
|
|
||||||
/*
|
|
||||||
opts = fcntl(sock,F_GETFL);
|
|
||||||
if (opts < 0) {
|
|
||||||
perror("fcntl(F_GETFL)");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
opts = (opts | O_NONBLOCK);
|
|
||||||
if (fcntl(sock,F_SETFL,opts) < 0)
|
|
||||||
{
|
|
||||||
perror("fcntl(F_SETFL)");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------
|
/*--------------------------------------------------------
|
||||||
* TCP client functionality
|
* TCP client functionality
|
||||||
@ -645,12 +640,11 @@ tcp_server_accept(int s, int maxfd, fd_set *read_set, struct iperf_settings *set
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//make socket non blocking
|
|
||||||
setnonblocking(peersock);
|
setnonblocking(peersock);
|
||||||
|
|
||||||
FD_SET(peersock, read_set);
|
FD_SET(peersock, read_set);
|
||||||
maxfd = (maxfd < peersock)?peersock:maxfd;
|
maxfd = (maxfd < peersock)?peersock:maxfd;
|
||||||
// creating a new stream
|
|
||||||
sp = new_stream(peersock, settings);
|
sp = new_stream(peersock, settings);
|
||||||
add_stream(sp);
|
add_stream(sp);
|
||||||
connect_msg(sp);
|
connect_msg(sp);
|
||||||
@ -707,7 +701,6 @@ client(struct iperf_settings *settings)
|
|||||||
connect_msg(sp);
|
connect_msg(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sety necessary parameters for TCP/UDP
|
|
||||||
buf = (char *) malloc(sp->settings->bufsize);
|
buf = (char *) malloc(sp->settings->bufsize);
|
||||||
if(!buf)
|
if(!buf)
|
||||||
{
|
{
|
||||||
@ -769,13 +762,13 @@ client(struct iperf_settings *settings)
|
|||||||
perror("gettimeofday");
|
perror("gettimeofday");
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to create this separate for each stream
|
|
||||||
adjustns = dtargns;
|
adjustns = dtargns;
|
||||||
adjustns += (before.tv_sec - after.tv_sec) * SEC_TO_NS;
|
adjustns += (before.tv_sec - after.tv_sec) * SEC_TO_NS;
|
||||||
adjustns += (before.tv_usec - after.tv_usec) * uS_TO_NS;
|
adjustns += (before.tv_usec - after.tv_usec) * uS_TO_NS;
|
||||||
|
|
||||||
if( adjustns > 0 || delayns > 0) {
|
if( adjustns > 0 || delayns > 0) {
|
||||||
//printf("%lld adj %lld delay\n", adjustns, delayns);
|
printf("%lld adj %lld delay\n", adjustns, delayns);
|
||||||
delayns += adjustns;
|
delayns += adjustns;
|
||||||
}
|
}
|
||||||
memcpy(&before, &after, sizeof before);
|
memcpy(&before, &after, sizeof before);
|
||||||
@ -868,12 +861,10 @@ server(struct iperf_settings *settings)
|
|||||||
Display();
|
Display();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Monitor the sockets for TCP
|
|
||||||
if(settings->proto== Ptcp)
|
if(settings->proto== Ptcp)
|
||||||
tcp_server_thread(maxfd, &temp_set, &read_set);
|
tcp_server_thread(maxfd, &temp_set, &read_set);
|
||||||
|
|
||||||
// Monitor the sockets for TCP
|
else if(settings->proto == Pudp)
|
||||||
else if(settings->proto== Pudp)
|
|
||||||
udp_server_thread(maxfd, &temp_set, &read_set);
|
udp_server_thread(maxfd, &temp_set, &read_set);
|
||||||
|
|
||||||
} // end else if (result > 0)
|
} // end else if (result > 0)
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user