Added more APIs for iperf_api.c and changed main.c for comments and log

This commit is contained in:
kaustubhprabhu 2009-06-10 00:23:21 +00:00
parent 061af7d9aa
commit 6c6757c6f8
3 changed files with 374 additions and 84 deletions

View File

@ -42,8 +42,6 @@ enum {
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
static struct option longopts[] =
{
{ "client", required_argument, NULL, 'c' },
@ -60,7 +58,6 @@ static struct option longopts[] =
};
struct iperf_test *iperf_create_test()
{
struct iperf_test * test;
@ -86,7 +83,7 @@ struct iperf_test *iperf_create_test()
test->stats_interval = 1;
test->reporter_interval = 1;
test->num_streams = 1;
// return an empty iperf_test* with memory alloted.
@ -96,11 +93,63 @@ struct iperf_test *iperf_create_test()
void iperf_init_test(struct iperf_test *test)
{
// should call internally init_stream - may be add_stream
char ubuf[UNIT_LEN];
struct iperf_stream *sp;
int i;
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));
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
memset(sp, 0, sizeof(struct iperf_stream));
memset(&sp->result, 0, sizeof(struct iperf_stream_result));
sp->local_port = 5001;
sp->remote_port = 5001;
memset(&sp->remote_addr, 0, sizeof(struct sockaddr_storage));
memset(&sp->local_addr, 0, sizeof(struct sockaddr_storage));
((struct iperf_settings *)(sp->settings))->options = sockopt;
sp->socket = -1;
sp->result->bytes_received = 0;
sp->result->bytes_sent = 0;
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));
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
memset(sp, 0, sizeof(struct iperf_stream));
memset(&sp->result, 0, sizeof(struct iperf_stream_result));
sp->local_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->window_size =window;
sp->settings = tcp_settings;
printf("memory allocated - TCP\n");
sp->socket = -1;
return sp;
}
@ -181,10 +244,14 @@ 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));
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
memset(sp, 0, sizeof(struct iperf_stream));
memset(&sp->result, 0, sizeof(struct iperf_stream_result));
sp->local_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->packet_size = size;
sp->settings = udp_settings;
sp->socket = -1;
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)
{
@ -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
main(int argc, char **argv)
{
int rc;
char ch;
char ch;
struct iperf_test *test;
struct iperf_stream *sp;
struct iperf_stream *sp, temp;
struct iperf_sock_opts *sockopt=NULL;
int window= 1024,rate,size;
int i,bw, buffer_size;
int window= 1024*1024, size;
int i, bw = 100000, buffer_size;
sockopt = (struct iperf_sock_opts *)malloc(sizeof(struct iperf_sock_opts));
@ -241,12 +518,13 @@ main(int argc, char **argv)
while( (ch = getopt_long(argc, argv, "c:p:st:uP:b:l:w:", longopts, NULL)) != -1 )
switch (ch) {
case 'c':
test->role = 'c';
//test->remote_ip_addr->ss_len =(int) malloc(strlen(optarg));
//(struct sockaddr_in)(test->remote_ip_addr), (struct sockaddr_in)optarg;
test->role = 'c';
// remote_ip_addr
break;
case 'p':
test->streams->remote_port = atoi(optarg);
temp.remote_port = atoi(optarg);
break;
case 's':
test->role = 's';
@ -279,6 +557,7 @@ main(int argc, char **argv)
for(i=0;i<test->num_streams;i++)
{
sp = iperf_create_tcp_stream(window, sockopt);
sp->remote_port = temp.remote_port;
iperf_add_stream(test,sp);
}
break;
@ -286,7 +565,8 @@ main(int argc, char **argv)
case Pudp:
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);
}
break;
@ -295,6 +575,7 @@ main(int argc, char **argv)
for(i=0;i<test->num_streams;i++)
{
sp = iperf_create_stream(sockopt);
sp->remote_port = temp.remote_port;
iperf_add_stream(test,sp);
}
break;
@ -304,10 +585,29 @@ main(int argc, char **argv)
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 );
else
printf(" %d is the rate for udp\n",((struct iperf_udp_settings *)(sp->settings))->rate );
if(sp->next!= NULL)
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;
}

View File

@ -54,8 +54,7 @@ struct iperf_stream
int remote_port; // remote machine port
void *settings; // pointer to structure settings
int protocol; // protocol- TCP/UDP
/* non configurable members */
struct iperf_stream_result *result; //structure pointer to result
@ -65,8 +64,8 @@ struct iperf_stream
struct sockaddr_storage remote_addr;
int *(*init)(struct iperf_stream *stream);
int *(*recv)(struct iperf_stream *stream);
int *(*send)(struct iperf_stream *stream);
int *(*recv_stream)(struct iperf_stream *stream);
int *(*send_stream)(struct iperf_stream *stream);
int *(*update_stats)(struct iperf_stream *stream);
struct iperf_stream *next;

View File

@ -1,10 +1,5 @@
/*
* iperfjd -- greatly simplified version of iperf with the same interface
* 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
* iperf3
*/
#include <stdio.h>
@ -23,7 +18,7 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <pthread.h>
#include <pthread.h>
#include <stdint.h>
#include <sys/time.h>
@ -45,7 +40,7 @@ enum {
uS_TO_NS = 1000,
MAX_BUFFER_SIZE =10,
DEFAULT_UDP_BUFSIZE = 1,
DEFAULT_UDP_BUFSIZE = 1470,
DEFAULT_TCP_BUFSIZE = 8192
};
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
@ -73,7 +68,6 @@ struct iperf_stream
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_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);
@ -176,11 +170,9 @@ new_stream(int s, struct iperf_settings *settings)
return(NULL);
}
//initialise sp with 0
memset(sp, 0, sizeof(struct iperf_stream));
// copy settings and passed socket into stream
sp->settings = settings;
sp->settings = settings;
sp->sock = s;
@ -210,7 +202,7 @@ new_stream(int s, struct iperf_settings *settings)
perror("inet_pton");
}
// sets appropriate function pointer
//not needed now
switch (settings->proto) {
case Ptcp:
sp->client = (void *) tcp_client_thread;
@ -274,8 +266,8 @@ free_stream(struct iperf_stream *sp)
prev = streams;
start = streams;
if(streams->sock==sp->sock)
{
if(streams->sock==sp->sock){
streams=streams->next;
return 0;
}
@ -285,15 +277,15 @@ free_stream(struct iperf_stream *sp)
while(1)
{
if(start->sock==sp->sock)
{
if(start->sock==sp->sock){
prev->next = sp->next;
free(sp);
return 0;
}
if(start->next!=NULL)
{
if(start->next!=NULL){
start=start->next;
prev=prev->next;
}
@ -312,18 +304,19 @@ update_stream(int j, int result)
{
struct iperf_stream *n;
n=streams;
//find the correct stream for update
while(1)
{
if(n->sock == j)
{
n->bytes_in+= result; //update the byte count
n->bytes_in= n->bytes_in + result;
break;
}
if(n->next==NULL)
break;
n = n->next;
}
@ -346,6 +339,30 @@ void connect_msg(struct iperf_stream *sp)
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
-------------------------------------------------------*/
@ -424,11 +441,13 @@ udp_server_thread(int maxfd, fd_set *temp_set, fd_set *read_set)
int j,result;
struct iperf_stream *n;
for (j=0; j<maxfd+1; j++){
n = streams;
if (FD_ISSET(j, temp_set)){
do{
do{
result = recv(j, buffer,DEFAULT_UDP_BUFSIZE, 0);
} while (result == -1 && errno == EINTR);
@ -490,7 +509,6 @@ int udp_server_accept(int *s, int maxfd, fd_set *read_set, struct iperf_settings
sp->bytes_in += sz;
add_stream(sp);
printf("calling netannounce within function \n");
*s = netannounce(settings->proto, NULL, settings->port);
if(*s < 0)
return -1;
@ -517,29 +535,6 @@ void
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
@ -644,13 +639,12 @@ tcp_server_accept(int s, int maxfd, fd_set *read_set, struct iperf_settings *set
return 0;
}
else
{
//make socket non blocking
{
setnonblocking(peersock);
FD_SET(peersock, read_set);
maxfd = (maxfd < peersock)?peersock:maxfd;
// creating a new stream
sp = new_stream(peersock, settings);
add_stream(sp);
connect_msg(sp);
@ -707,7 +701,6 @@ client(struct iperf_settings *settings)
connect_msg(sp);
}
// sety necessary parameters for TCP/UDP
buf = (char *) malloc(sp->settings->bufsize);
if(!buf)
{
@ -769,13 +762,13 @@ client(struct iperf_settings *settings)
perror("gettimeofday");
}
// need to create this separate for each stream
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);
printf("%lld adj %lld delay\n", adjustns, delayns);
delayns += adjustns;
}
memcpy(&before, &after, sizeof before);
@ -866,14 +859,12 @@ server(struct iperf_settings *settings)
FD_CLR(s, &temp_set);
Display();
}
}
// Monitor the sockets for TCP
if(settings->proto== Ptcp)
tcp_server_thread(maxfd, &temp_set, &read_set);
// Monitor the sockets for TCP
else if(settings->proto== Pudp)
tcp_server_thread(maxfd, &temp_set, &read_set);
else if(settings->proto == Pudp)
udp_server_thread(maxfd, &temp_set, &read_set);
} // end else if (result > 0)