changed the linked list functions

This commit is contained in:
kaustubhprabhu 2009-06-02 22:06:49 +00:00
parent beec2717ab
commit db1760105f

View File

@ -38,12 +38,12 @@ enum {
Mundef = 0,
Mclient,
Mserver,
Ptcp = SOCK_STREAM,
Pudp = SOCK_DGRAM,
uS_TO_NS = 1000,
MAX_BUFFER_SIZE =10,
DEFAULT_UDP_BUFSIZE = 1470,
DEFAULT_TCP_BUFSIZE = 8192
@ -55,21 +55,21 @@ struct iperf_stream
int sock; /* local socket */
struct sockaddr_in local; /* local address */
struct sockaddr_in peer; /* peer address */
uint64_t bytes_in;
uint64_t bytes_out;
pthread_t thread;
char local_addr[512], peer_addr[512];
void *stats; /* ptr to protocol specific stats */
void *(*server)(void *sp);
void *(*client)(void *sp);
struct iperf_settings *settings;
struct iperf_stream *next;
};
@ -81,16 +81,16 @@ void *tcp_server_thread(struct iperf_stream *sp);
static struct option longopts[] =
{
{ "client", required_argument, NULL, 'c' },
{ "server", no_argument, NULL, 's' },
{ "time", required_argument, NULL, 't' },
{ "port", required_argument, NULL, 'p' },
{ "parallel", required_argument, NULL, 'P' },
{ "udp", no_argument, NULL, 'u' },
{ "bandwidth", required_argument, NULL, 'b' },
{ "length", required_argument, NULL, 'l' },
{ "window", required_argument, NULL, 'w' },
{ NULL, 0, NULL, 0 }
{ "client", required_argument, NULL, 'c' },
{ "server", no_argument, NULL, 's' },
{ "time", required_argument, NULL, 't' },
{ "port", required_argument, NULL, 'p' },
{ "parallel", required_argument, NULL, 'P' },
{ "udp", no_argument, NULL, 'u' },
{ "bandwidth", required_argument, NULL, 'b' },
{ "length", required_argument, NULL, 'l' },
{ "window", required_argument, NULL, 'w' },
{ NULL, 0, NULL, 0 }
};
struct iperf_settings
@ -135,15 +135,31 @@ int done = 0;
-------------------------------------------------------*/
void Display()
{
struct iperf_stream * n;
struct iperf_stream *n;
n= streams;
int count=1;
while(n->next!=NULL)
{
printf("position-%d\tsp=%d\tsocket=%d\n",count++,(int)n,n->sock);
n=n->next;
}
printf("===============DISPLAY==================\n");
while(1)
{
if(n->next==NULL)
{
printf("position-%d\tsp=%d\tsocket=%d\n",count++,(int)n,n->sock);
break;
}
else
{
printf("position-%d\tsp=%d\tsocket=%d\n",count++,(int)n,n->sock);
if(n->next==NULL)
{
printf("=================END====================\n");
break;
}
n=n->next;
}
}
}
@ -156,20 +172,20 @@ new_stream(int s, struct iperf_settings *settings)
{
struct iperf_stream *sp;
socklen_t len;
sp = (struct iperf_stream *) malloc(sizeof(struct iperf_stream));
if(!sp) {
perror("malloc");
return(NULL);
}
//initialise sp with 0
memset(sp, 0, sizeof(struct iperf_stream));
// copy settings and passed socket into stream
sp->settings = settings;
sp->sock = s;
len = sizeof sp->local;
if(getsockname(sp->sock, (struct sockaddr *) &sp->local, &len) < 0) {
@ -180,20 +196,20 @@ new_stream(int s, struct iperf_settings *settings)
//converts the local ip into string address
if(inet_ntop(AF_INET, (void *) &sp->local.sin_addr,
(void *) &sp->local_addr, 512) == NULL) {
(void *) &sp->local_addr, 512) == NULL) {
perror("inet_pton");
}
//stores the socket id.
if(getpeername(sp->sock, (struct sockaddr *) &sp->peer, &len) < 0) {
perror("getpeername");
free(sp);
return(NULL);
}
// converts the remote ip into string address
if(inet_ntop(AF_INET, (void *) &sp->peer.sin_addr,
(void *) &sp->peer_addr, 512) == NULL) {
(void *) &sp->peer_addr, 512) == NULL) {
perror("inet_pton");
}
@ -211,24 +227,24 @@ new_stream(int s, struct iperf_settings *settings)
assert(0);
break;
}
if(set_tcp_windowsize(sp->sock, settings->window,
settings->mode == Mserver ? SO_RCVBUF : SO_SNDBUF) < 0)
settings->mode == Mserver ? SO_RCVBUF : SO_SNDBUF) < 0)
fprintf(stderr, "unable to set window size\n");
int x;
x = getsock_tcp_windowsize(sp->sock, SO_RCVBUF);
if(x < 0)
perror("SO_RCVBUF");
printf("RCV: %d\n", x);
x = getsock_tcp_windowsize(sp->sock, SO_SNDBUF);
if(x < 0)
perror("SO_SNDBUF");
printf("SND: %d\n", x);
return(sp);
}
@ -241,7 +257,7 @@ void
add_stream(struct iperf_stream *sp)
{
struct iperf_stream *n;
if(!streams)
streams = sp;
else {
@ -259,7 +275,6 @@ add_stream(struct iperf_stream *sp)
int
free_stream(struct iperf_stream *sp)
{
printf("I am in free_stream \n");
struct iperf_stream *prev,*start;
prev = streams;
@ -267,27 +282,28 @@ free_stream(struct iperf_stream *sp)
if(streams->sock==sp->sock)
{
printf("in 1 -Deleted\n\n\n");
streams=streams->next;
return 0;
}
else
{
do
{
start= streams->next;
while(1)
{
start= streams->next;
if(start->sock==sp->sock)
{
printf("Deleting socket %d \t",sp->sock);
{
prev->next = sp->next;
printf("Deleted\n\n\n");
free(sp);
return 0;
}
prev=prev->next;
}while(start->next!=NULL);
if(start->next!=NULL)
{
start=start->next;
prev=prev->next;
}
}
return -1;
}
@ -304,16 +320,18 @@ find_update_stream(int j, int result)
struct iperf_stream *n;
n=streams;
//find the correct stream for update
do
while(1)
{
if(n->sock==j)
{
n->bytes_in+= result; //update the byte count
n->bytes_in+= result; //update the byte count
break;
}
n = n->next;
}while(n->next!=NULL);
if(n->next==NULL)
break;
n = n->next;
}
return n;
}
@ -324,14 +342,14 @@ find_update_stream(int j, int result)
void connect_msg(struct iperf_stream *sp)
{
char *ipl, *ipr;
ipl = (char *) &sp->local.sin_addr;
ipr = (char *) &sp->peer.sin_addr;
printf("[%3d] local %s port %d connected with %s port %d\n",
sp->sock,
sp->local_addr, htons(sp->local.sin_port),
sp->peer_addr, htons(sp->peer.sin_port));
sp->sock,
sp->local_addr, htons(sp->local.sin_port),
sp->peer_addr, htons(sp->peer.sin_port));
}
@ -345,58 +363,58 @@ udp_client_thread(struct iperf_stream *sp)
int64_t delayns, adjustns, dtargns;
char *buf;
struct timeval before, after;
buf = (char *) malloc(sp->settings->bufsize);
if(!buf) {
perror("malloc: unable to allocate transmit buffer");
pthread_exit(NULL);
}
for(i=0; i < sp->settings->bufsize; i++)
buf[i] = i % 37;
dtargns = (int64_t) sp->settings->bufsize * SEC_TO_NS * 8;
dtargns /= sp->settings->bw;
assert(dtargns != 0);
if(gettimeofday(&before, 0) < 0) {
perror("gettimeofday");
}
delayns = dtargns;
adjustns = 0;
printf("%lld adj %lld delay\n", adjustns, delayns);
while(!done) {
send(sp->sock, buf, sp->settings->bufsize, 0);
sp->bytes_out += sp->settings->bufsize;
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);
}
/* a 0 byte packet is the server's cue that we're done */
send(sp->sock, buf, 0, 0);
/* XXX: wait for response with server counts */
printf("%llu bytes sent\n", sp->bytes_out);
close(sp->sock);
pthread_exit(NULL);
}
@ -410,17 +428,17 @@ udp_server_thread(struct iperf_stream *sp)
{
char *buf, ubuf[UNIT_LEN];
ssize_t sz;
buf = (char *) malloc(sp->settings->bufsize);
if(!buf) {
perror("malloc: unable to allocate receive buffer");
pthread_exit(NULL);
}
while((sz = recv(sp->sock, buf, sp->settings->bufsize, 0)) > 0) {
sp->bytes_in += sz;
}
close(sp->sock);
unit_snprintf(ubuf, UNIT_LEN, (double) sp->bytes_in / sp->settings->duration, 'a');
printf("%llu bytes received %s/sec\n", sp->bytes_in, ubuf);
@ -456,30 +474,30 @@ tcp_client_thread(struct iperf_stream *sp)
{
int i;
char *buf;
buf = (char *) malloc(sp->settings->bufsize);
if(!buf) {
perror("malloc: unable to allocate transmit buffer");
pthread_exit(NULL);
}
printf("window: %d\n", getsock_tcp_windowsize(sp->sock, SO_SNDBUF));
for(i=0; i < sp->settings->bufsize; i++)
buf[i] = i % 37;
while(!done) {
send(sp->sock, buf, sp->settings->bufsize, 0);
sp->bytes_out += sp->settings->bufsize;
}
/* a 0 byte packet is the server's cue that we're done */
send(sp->sock, buf, 0, 0);
/* XXX: wait for response with server counts */
printf("%llu bytes sent\n", sp->bytes_out);
close(sp->sock);
pthread_exit(NULL);
}
@ -492,19 +510,19 @@ tcp_server_thread(struct iperf_stream *sp)
{
char *buf, ubuf[UNIT_LEN];
ssize_t sz;
buf = (char *) malloc(sp->settings->bufsize);
if(!buf) {
perror("malloc: unable to allocate receive buffer");
pthread_exit(NULL);
}
printf("window: %d\n", getsock_tcp_windowsize(sp->sock, SO_RCVBUF));
while( (sz = recv(sp->sock, buf, sp->settings->bufsize, 0)) > 0) {
sp->bytes_in += sz;
}
close(sp->sock);
unit_snprintf(ubuf, UNIT_LEN, (double) sp->bytes_in / sp->settings->duration, 'a');
printf("%llu bytes received %s/sec\n", sp->bytes_in, ubuf);
@ -521,43 +539,43 @@ client(struct iperf_settings *settings)
int s, i;
struct iperf_stream *sp;
struct timer *timer;
for(i = 0; i < settings->threads; i++) {
s = netdial(settings->proto, settings->client, settings->port);
if(s < 0) {
fprintf(stderr, "netdial failed\n");
return -1;
}
set_tcp_windowsize(s, settings->window, SO_SNDBUF);
if(s < 0)
return -1;
sp = new_stream(s, settings);
add_stream(sp);
connect_msg(sp);
// need to replace this with Select
pthread_create(&sp->thread, NULL, sp->client, (void *) sp);
}
timer = new_timer(settings->duration, 0);
// wait till the timer expires
while(!timer->expired(timer))
sleep(settings->duration);
// this is checked in UDP/TCP while loop
// to stop sending packets. Global member
done = 1;
/* XXX: report */
sp = streams;
do {
pthread_join(sp->thread, NULL);
sp = sp->next;
} while (sp);
return 0;
}
@ -567,24 +585,24 @@ client(struct iperf_settings *settings)
int
server(struct iperf_settings *settings)
{
int s, cs, sz;
struct iperf_stream *sp,*temp;
int s,sz;
struct iperf_stream *sp;
struct sockaddr_in sa_peer;
socklen_t len;
char buf[settings->bufsize], ubuf[UNIT_LEN];
fd_set readset, tempset;
int maxfd, flags;
int peersock, j, result, result1, sent;
int maxfd;
int peersock, j, result;
struct timeval tv;
char buffer[DEFAULT_TCP_BUFSIZE];
struct sockaddr_in addr;
s = netannounce(settings->proto, NULL, settings->port);
if(s < 0)
return -1;
if(set_tcp_windowsize(s, settings->window, SO_RCVBUF) < 0) {
perror("unable to set window");
return -1;
@ -595,14 +613,14 @@ server(struct iperf_settings *settings)
int x;
if((x = getsock_tcp_windowsize(s, SO_RCVBUF)) < 0)
perror("SO_RCVBUF");
/*
unit_snprintf(ubuf, UNIT_LEN, (double) x, 'A');
printf("%s: %s\n",
settings->proto == Ptcp ? "TCP window size" : "UDP buffer size", ubuf);
*/
settings->proto == Ptcp ? "TCP window size" : "UDP buffer size", ubuf);
printf("-----------------------------------------------------------\n");
len = sizeof sa_peer;
FD_ZERO(&readset);
@ -640,19 +658,14 @@ server(struct iperf_settings *settings)
printf("Error in accept(): %s\n", strerror(errno));
}
else
{
printf("=========================\n");
printf("%d is the socket number\n",peersock);
{
FD_SET(peersock, &readset);
maxfd = (maxfd < peersock)?peersock:maxfd;
// creating a new stream
sp = new_stream(peersock, settings);
printf(" new stream is %d \n", (int)sp);
// need to manage the linked list of streams
add_stream(sp);
connect_msg(sp);
Display();
}
}
@ -663,28 +676,25 @@ server(struct iperf_settings *settings)
sz = recvfrom(s, buf, settings->bufsize, 0, (struct sockaddr *) &sa_peer, &len);
if(!sz)
break;
if(connect(s, (struct sockaddr *) &sa_peer, len) < 0)
{
perror("connect");
return -1;
}
// get a new socket to connect to client
printf("=========================\n");
sp = new_stream(s, settings);
sp->bytes_in += sz;
printf(" new stream is %d \n", (int)sp);
// need to manage the linked list of streams
add_stream(sp);
s = netannounce(settings->proto, NULL, settings->port);
if(s < 0)
return -1;
// same as TCP -repetation
printf("%d is the socket number\n",s);
FD_SET(s, &readset);
maxfd = (maxfd < s)?s:maxfd;
@ -692,6 +702,7 @@ server(struct iperf_settings *settings)
FD_CLR(s, &tempset);
Display();
}
@ -704,36 +715,35 @@ server(struct iperf_settings *settings)
{
if(settings->proto==Ptcp)
result = recv(j, buffer,DEFAULT_TCP_BUFSIZE, 0);
else
result = recv(j, buffer,DEFAULT_UDP_BUFSIZE, 0);
else
result = recv(j, buffer,DEFAULT_UDP_BUFSIZE, 0);
} while (result == -1 && errno == EINTR);
if (result > 0)
{
sp=find_update_stream(j,result);
}
else if (result == 0)
{
Display();
//just find the stream with zero update
sp = find_update_stream(j,0);
if(settings->proto == Ptcp)
{
//printf("window: %d\n", getsock_tcp_windowsize(sp->sock, SO_RCVBUF));
printf("window: %d\n", getsock_tcp_windowsize(sp->sock, SO_RCVBUF));
}
unit_snprintf(ubuf, UNIT_LEN, (double) sp->bytes_in / sp->settings->duration, 'a');
printf("%llu bytes received %s/sec for stream %d\n\n", sp->bytes_in, ubuf,(int)sp);
close(j);
FD_CLR(j, &readset);
free_stream(sp); // this needs to be a linked list delete
//break;
}
else
{
@ -744,8 +754,8 @@ server(struct iperf_settings *settings)
} // end else if (result > 0)
} while (1);
return 0;
}
@ -755,9 +765,9 @@ main(int argc, char **argv)
int rc;
char ch;
struct iperf_settings settings;
default_settings(&settings);
while( (ch = getopt_long(argc, argv, "c:p:st:uP:b:l:w:", longopts, NULL)) != -1 )
switch (ch) {
case 'c':
@ -790,10 +800,10 @@ main(int argc, char **argv)
settings.window = unit_atoi(optarg);
break;
}
if (settings.proto == Ptcp && settings.bufsize == DEFAULT_UDP_BUFSIZE)
settings.bufsize = DEFAULT_TCP_BUFSIZE; /* XXX: this might be evil */
switch (settings.mode) {
case Mclient:
rc = client(&settings);
@ -808,6 +818,6 @@ main(int argc, char **argv)
rc = -1;
break;
}
return rc;
}