Ask Question

Name:
Title:
Your Question:

Answer Question

Name:
Your Answer:
User Submitted Source Code!


Description:
  a
Language: C/C++
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <float.h>
#include <time.h>
#include <sys/time.h>

#define BUFFER     5120
#define POLY 0x8408
#define ALPHA     0.8
#define INFINITY 999
#define MAX 10
#define PKTSIZE 64
// initilizations
int server_sock, ftr_sock;
int n;
int *links;
double **adj_mat;
double **G;
double pred[MAX];
unsigned long *prev_alive_seq;
unsigned long *prev_lsa_seq;
unsigned long long *prev_lsa_ts;
unsigned long *alive_check;
unsigned long receiver;
int *blacklist;
int j,k;
char filepath[256];
int hosts[10];


pthread_mutex_t mutexbuf; // mutex to lock the receive buffer.
pthread_mutex_t send_mutexbuf; // mutex for send buffer.
pthread_mutex_t mutexadj; // mutex for changing values of adjescency matrix;


//STRUCTURES

struct data {
     unsigned long my_id;
     char ** ips; //  http://stackoverflow.com/questions/8467469/how-to-assign-value-to-the-double-pointer-in-struct-member
     int *ports;
     int *ftr_sendports;
     int *ftr_receiveports;
}router;


struct header
{
     unsigned long router_id;
     unsigned long dest_id;
     unsigned long pkt_type;
     unsigned long checksum;
     unsigned long len; // length of the info in the packet (not the header. only the info in the packet).
     unsigned long seq;

}*hdr ;

#define RTT  0
#define ALIVE  1
#define LSA  2
#define NACQ  3
#define FILE  4


#define HDR_SIZE sizeof(struct header)

// structure rtt
struct rtt
{
     unsigned short type;
     unsigned long long time;
     double link_cost;
};
// rtt1 corresponds to rtt from the router with a larger id and rtt2 corresponds to rtt from the smaller id.
#define RTT1     0
#define RTT2     1
#define RTT3     2
#define RTT4     3
#define RTT5     4
#define RTT6     5

//structure alive
struct alive
{
     unsigned long type;
     unsigned long seq;
};

#define ALIVE_MSG     0
#define ALIVE_REPLY     1

// structure link state advertisement
struct lsa
{
     unsigned long lsa_id;
     unsigned long lsa_type;
     unsigned long long age;
     unsigned long seq;
     unsigned long ttl;
     double lsa_cost[10];
};

#define TRIGGERED     1 // what to do if triggered?
#define PERODIC     0

// structure neighbour acquisition.
struct nacq
{
     unsigned long type;
};

#define BE_NEIGHBOR_REQUEST     0
#define BE_NEIGHBOR_ACCEPT     1
#define BE_NEIGHBOR_REFUSE     2
#define CEASE_NEIGHBOR          3




// FUNCTIONS

void dijkstra(double **G,int n, unsigned long startnode) // G is adj_mat, n is number of nodes and startnode.
{
//     puts("g matrixn");

//          for(j=0;j<n;j++)
//               {
//                    for(k=0;k<n;k++)
//                    printf("%fn",G[j][k] );
//               }

double cost[MAX][MAX],distance[MAX];

double visited[MAX],count,mindistance;
int i,j,nextnode;

//pred[] stores the predecessor of each node

//count gives the number of nodes seen so far

//create the cost matrix

for(i=0;i<n;i++)

for(j=0;j<n;j++)

if(G[i][j]==0)
                cost[i][j]=INFINITY;

else
                cost[i][j]=G[i][j];


//     puts("cost matrix");
//          for(j=0;j<n;j++)
//                                   {
//                                        for(k=0;k<n;k++)
//                                        printf("%fn",cost[j][k] );
//                                   }


//initialize pred[],distance[] and visited[]


for(i=0;i<n;i++)
{

distance[i]=cost[startnode][i];

pred[i]=startnode;

visited[i]=0;
}

distance[startnode]=0;

visited[startnode]=1;

count=1;

while(count< (n-1))
    {
        mindistance=INFINITY;

//nextnode gives the node at minimum distance

for(i=0;i<n;i++)

if( (distance[i]<mindistance) && (!visited[i]))

{
                mindistance=distance[i];
                nextnode=i;

}

//check if a better path exists through nextnode

visited[nextnode]=1;

for(i=0;i<n;i++)
if(!visited[i])
if((mindistance+cost[nextnode][i]) < distance[i])
                {
                    distance[i]=mindistance+cost[nextnode][i];
                    pred[i]=nextnode;
                }

count++;
    }

//print the path and distance of each node

for(i=0;i<n;i++)

if(i!=startnode)

{
    printf("nDistance of node %d = %f",i,distance[i]);
    printf("nPath = %d",i);
    j=i;
    do
        {
             j=pred[j];

               printf(" <-%d",j);
        }while(j!=startnode);

}
}

// function to change the adjescency matrix.
void changeadj(unsigned long a, unsigned long b, int c, unsigned long long diff, double e)
{
     pthread_mutex_lock (&mutexadj);
     if(c == 0)
     {
     adj_mat[a][b] = 0;
     }
     else if(c==1)
     {
          adj_mat[a][b] = 1;
     }
     else if(c==3)
     {
     adj_mat[a][b] = ALPHA * adj_mat[a][b] + (1 - ALPHA) * diff;
     }
     else if (c==4)
     {
     adj_mat[a][b]= e;
     }
     pthread_mutex_unlock (&mutexadj);


}

//  diep function for errors
void diep(char *s)
{
     perror(s);
     exit(1);
}

// checksum
unsigned long crc16(char *data_p, unsigned long length)
{
      unsigned char i;
      unsigned long data;
      unsigned long crc = 0xffff;

      if (length == 0)
            return (~crc);

      do
      {
            for (i=0, data=(unsigned int)0xff & *data_p++;
                 i < 8;
                 i++, data >>= 1)
            {
                  if ((crc & 0x0001) ^ (data & 0x0001))
                        crc = (crc >> 1) ^ POLY;
                  else  crc >>= 1;
            }
      } while (--length);

      crc = ~crc;
      data = crc;
      crc = (crc << 8) | (data >> 8 & 0xff);

      return (crc);
}


unsigned long long current_timestamp()   //http://stackoverflow.com/questions/3756323/getting-the-current-time-in-milliseconds
{
     struct timeval te;
     gettimeofday(&te, NULL);
     unsigned long long milliseconds = te.tv_sec * 1000LL + te.tv_usec / 1000;
     return milliseconds;
}

//Send a packet. Send as client. No binding required.
int client_send(char *ip, int port, void *send_buf, unsigned long len)
{
     pthread_mutex_lock (&send_mutexbuf);// lock buffer using mutex
     //puts("send buffer locked by mutex");

     struct sockaddr_in si_other;
     int s, slen = sizeof(si_other); // changed sockaddr_in to si_other

     if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
     diep("socket");

     memset((char *) &si_other, 0, sizeof(si_other));
     si_other.sin_family = AF_INET;
    si_other.sin_port = htons(port);
    if(inet_aton(ip, &si_other.sin_addr) == 0) // stores the ip passed as argument to &si_other.sin_addr
    diep("ip address invalid");

     int ret = sendto(s, send_buf, len, 0, (struct sockaddr *)&si_other, slen);
     //puts("message sent");
     close(s);
     //free(send_buf);

     pthread_mutex_unlock (&send_mutexbuf);
     //puts("send buffer unlocked by mutex");

     return ret;
}

// create packet(join header and data)
void create_pkt(void *buf, unsigned long router_id, unsigned long pkt_type, unsigned long len, void *info, unsigned long seq, unsigned long dest_id)
{
     struct header hdr;
     hdr.router_id = router_id;
     hdr.pkt_type = pkt_type;
     hdr.checksum = crc16((char *) info, len);
     hdr.len = len;
     hdr.seq=seq;
     hdr.dest_id=dest_id;

     memcpy(buf, &hdr, HDR_SIZE);
     memcpy(buf + HDR_SIZE, info, len);
}



// server receive(receive from client) function
int server_receive(int sock, void *buf, unsigned long len, struct sockaddr *si_other) //  returns a pointer to buffer.
{
     pthread_mutex_lock (&mutexbuf);// lock receive buffer using mutex
     //puts("buffer locked by mutex");

     struct sockaddr_in si_me;
     int slen = sizeof(struct sockaddr_in);

    int rets = recvfrom(sock, buf, len, 0, si_other, &slen);/* invalid conversion from 'int*' to 'socklen_t*  */

   pthread_mutex_unlock (&mutexbuf); // unlock receive buffer using mutex
          //puts("buffer unlocked by mutex");

    return rets;
}
// THREAD FUNCTIONS

void *filetransfer(void *ptr)
{
     int fd;
     unsigned long seq = 0;
     char readbuf[PKTSIZE];

     usleep(5000000);
     printf("Please choose a file.n>> ");
     scanf("%s",filepath);
     printf("filepath: %s", filepath);
     fd = open(filepath, O_RDONLY);
      if(fd==-1)
     puts("nerror reading file");
     else
     puts("file opened");

     void *buf = malloc(HDR_SIZE + PKTSIZE);
     struct header hdr;
          while(1)
     {
          usleep(500000);
          int len = read(fd, readbuf, PKTSIZE);
          //printf("n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!the size of packet is %lu", len);
          seq++;

          create_pkt(buf, router.my_id, FILE, len, (void *) readbuf,seq,receiver);
          int i;
          for(i=0;i<n;i++)
          {
               printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!the next node to reach  node %d is %f",i, pred[i]);
          }
     //     client_send()


     }


     //printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!sender and receiver are");

return NULL;
}

void *dij(void *ptr)
{
     int i,j;

     while(1)
     {

          usleep(5000000);
          for(i=0;i<n;i++)
          {
               for(j=0;j<n;j++)
               {
                    printf("n The cost matrix is : %f",adj_mat[i][j]);
               }
          }

          dijkstra(adj_mat, n, router.my_id);
     }

     return NULL;
}

void *adperodic(void *ptr)
{
     //puts("aperodic link started");
     int i, j;
     unsigned long k,l;
     unsigned long long seq = 0;
     struct lsa msg;
     while(1)
     {
          //if(terminate) break;
          usleep(5000000);
          seq = seq+ 1;
          void *buf = malloc(HDR_SIZE + sizeof(struct lsa));
          for(i = 0; i < n; i++)
          {
               if(i == router.my_id) continue;
               if(hosts[i]==1) continue;
               if(blacklist[i]==1) continue;
               if(links[i] == 0) continue;
               //     printf("aperodic link %f",adj_mat[router.my_id][i] );

               if(adj_mat[router.my_id][i] == 0) continue;
               printf("aperodic link %f",adj_mat[router.my_id][i] );

               bzero(buf, HDR_SIZE + sizeof(struct lsa));
               msg.lsa_id = router.my_id;
               msg.seq = seq;
               msg.lsa_type = PERODIC;
               msg.ttl = 5;
               msg.age = current_timestamp();
          //     memcpy(msg.lsa_cost, adj_mat[router.my_id], n * sizeof(double));
          //     for(k=0;k<n;k++)
          //     printf("the message that is beiing advertised is %f",msg.lsa_cost[i]);
//               for(k=0;k<n;k++)
//               {
//                    for(l=0;l<n;l++)
//                    {
//                         printf("nThe adjesency matrix is: %f", adj_mat[k][l]) ;
//                    }
//               }
//               printf("n my id is: %lu", router.my_id);
               for(k=0;k<n;k++)
               {
                    msg.lsa_cost[k]= adj_mat[router.my_id][k];
               //     printf("nmessage that is advertised to router %d is : %f",i, adj_mat[router.my_id][k]);
               //     printf("nlsa.link_cost is : %f", msg.lsa_cost[k]);

               }

               //printf("message that is advertised %f", adj_mat[router.my_id]);
               create_pkt(buf, router.my_id, LSA, sizeof(struct lsa), (void *)&msg,0,0);
               client_send(router.ips[i], router.ports[i], buf, HDR_SIZE + sizeof(struct lsa));
//               puts("lsa advertised");


          }
          free(buf);


     }
     return NULL;
}



// rtt thread
void *rtt(void *ptr)
{
     usleep(5000000);
     int i;
     struct rtt msg;
     while(1)
     {
          //if(terminate) break;
          usleep(15000000);

          void *buf = malloc(HDR_SIZE + sizeof(struct rtt));
          for(i = 0; i < n; i++)
          {
               if(i == router.my_id) continue;
               if(links[i] == 0) continue;
               //printf("!!!!!!!!!!!!!!!rtt links%fn",adj_mat[router.my_id][i]);
               if(router.my_id < i) continue;
               if(adj_mat[router.my_id][i] == 0) continue;

               bzero(buf, HDR_SIZE + sizeof(struct rtt));
               msg.type = RTT1;
               msg.time = current_timestamp();
               create_pkt(buf, router.my_id, RTT, sizeof(struct rtt), (void *)&msg,0,0);
          //     usleep(1564 * (rand() % (i + 2)));
               client_send(router.ips[i], router.ports[i], buf, HDR_SIZE + sizeof(struct rtt));
          }
          free(buf);
     }
     return NULL;
}

// neighbouur acquisition thread
void *nacq(void *ptr)
{
     //printf("before nacq %f: ", adj_mat[1][2]);
     int i;
     struct nacq msg;
     while(1)
     {


          void *buf = malloc(HDR_SIZE + sizeof(struct nacq));
          for(i = 0; i < n; i++)
          {
               //printf("blacklist of %d = %dn", i, blacklist[i]);
               if(blacklist[i]==1) continue;
               //printf("blacklist of %d = %dn", i, blacklist[i]);
               if(i == router.my_id) continue;
               if(links[i] == 0)
               continue;
               //printf("link value 2: %fn",adj_mat[router.my_id][i] );
               if(hosts[i]==1) continue;
               if(adj_mat[router.my_id][i] > 0)
               continue;
               bzero(buf, HDR_SIZE + sizeof(struct nacq));
               msg.type = BE_NEIGHBOR_REQUEST;
               create_pkt(buf, router.my_id, NACQ, sizeof(struct nacq), (void *)&msg,0,0);
               client_send(router.ips[i], router.ports[i], buf, HDR_SIZE + sizeof(struct nacq));
               //printf("nacq sent to routerid %dn", i);
               //adj_mat[router.my_id][i] =1; // change

          }
          free(buf);

               usleep(10000000);

     }
     return NULL;
}

// alive
void *alive(void *ptr)
{

          //printf("before alive %f: ", adj_mat[1][2]);
     struct alive msg;
     unsigned long seq = 0;
     usleep(10000000);

     int i;
     while(1)
     {


          void *buf = malloc(HDR_SIZE + sizeof(struct alive));

          for(i = 0; i < n; i++)

          {
               seq=i;
               if(i == router.my_id) continue;
               if(hosts[i]==1) continue;
               if(links[i] == 0) continue;
               if(blacklist[i]==1) continue;
               //printf("!!!!!!!!!!!!!!!!!!!!!!!!alive link %fn",adj_mat[router.my_id][i]);
               if(adj_mat[router.my_id][i]==0) continue;
               (memset((buf), '', (HDR_SIZE + sizeof(struct alive))), (void) 0);
                msg.seq= seq;
                msg.type = ALIVE_MSG;
                alive_check[i]=0;
               create_pkt(buf, router.my_id, ALIVE, sizeof(struct alive), (void *)&msg,0,0);
               client_send(router.ips[i], router.ports[i], buf, HDR_SIZE+sizeof(struct alive));
               //puts("alive message sentn");
               prev_alive_seq[i] == seq;
          }
          free(buf);

               usleep(5000000);
               for(i=0;i<n;i++)
               {
                    if(hosts[i]==1) continue;
                    if(i == router.my_id) continue;
                    if(links[i] == 0) continue;
                    if(blacklist[i]==1) continue;
                    if(alive_check[i]==0)
                    {
                         changeadj(router.my_id,i,0,0,0);
                         printf("link to router id %d: failed...n",i);
                    }
               }



          // if I do not receive a reply of message type RTT2 with the
          //same sequence number within the retransmission timeout, I disable the link.
//          for(i = 0; i < n; i++)
//          {
//               if(prev_alive_seq[i] == seq) continue;
//
//
//               else{
//                    printf("link to router id %d:%s failed...n",i, router.ips[i]);
//                    adj_mat[router.my_id][i] = changeadj(router.my_id,i,0,0,0);
//                    }
//          }
     }
     return NULL;
}
// server listen

void *server_listen(void *ptr)
{
      char buf[BUFFER];

     while(1)
     {

          (memset((buf), (BUFFER)), (void) 0);
          //puts("memset of buffer in serverlisten done");


          if(server_receive(server_sock, buf, BUFFER, NULL) > 0)// returns a pointer to the buffer.
          {
               //puts("something in buffern");
               struct header *hdr = (struct header *)buf;
               // check if checksum is correct.
               if(hdr->checksum != crc16((void *)(buf + HDR_SIZE), hdr->len)) // get checksum users argument as a buffer pointer and length of the buffer. not sure if void *
               {
               puts("corrupted packet");
               continue;
               // send nack.
               }
               //printf("message from router id %lun", hdr->router_id );

               switch(hdr->pkt_type)
               {
                    case ALIVE:
                    if(((struct alive *) (buf + HDR_SIZE))->type == ALIVE_MSG)
                    {
                         struct alive reply;
                         reply.type = ALIVE_REPLY;
                         reply.seq = ((struct alive *) (buf + HDR_SIZE))->seq;
                         void *send_buf = malloc(HDR_SIZE + sizeof(struct alive));
                         create_pkt(send_buf, router.my_id, ALIVE, sizeof(struct alive), (void *)&reply,0,0);
                         client_send(router.ips[hdr->router_id], router.ports[hdr->router_id], send_buf, HDR_SIZE + sizeof(struct alive));
                    //     puts("Alive reply sentn");
                         free(send_buf);
                    }
                    else if(((struct alive *) (buf + HDR_SIZE))->type == ALIVE_REPLY)
                    {
                         if(((struct alive *) (buf + HDR_SIZE))->seq== hdr->router_id)
                         {
                         //     printf("nRouter %lu is alive",hdr->router_id);
                              alive_check[hdr->router_id]=1;
                         //     puts("101");
                         }

                    }
                    break;

                    case NACQ:
                    if(((struct nacq *) (buf + HDR_SIZE))->type == BE_NEIGHBOR_REQUEST)
                    {
                         if(blacklist[hdr->router_id]==0)
                         {

                         struct nacq reply;
                         reply.type = BE_NEIGHBOR_ACCEPT;
                         void *send_buf = malloc(HDR_SIZE + sizeof(struct nacq));
                         create_pkt(send_buf, router.my_id, NACQ, sizeof(struct nacq), (void *)&reply,0,0);
                         client_send(router.ips[hdr->router_id], router.ports[hdr->router_id], send_buf, HDR_SIZE + sizeof(struct nacq));
                         free(send_buf);
                         alive_check[hdr->router_id]=1;
                         changeadj(router.my_id,hdr->router_id,1,0,0);
                         //printf("link value 1: %fn",adj_mat[router.my_id][hdr->router_id] );
                         //puts("be neighbour request acceptedn");
                         //printf("connected to router %d:%s...n", hdr->router_id, router.ips[hdr->router_id]);

                         }
                         else
                         {

                         struct nacq reply;
                         reply.type = BE_NEIGHBOR_REFUSE;
                         void *send_buf = malloc(HDR_SIZE + sizeof(struct nacq));
                         create_pkt(send_buf, router.my_id, NACQ, sizeof(struct nacq), (void *)&reply,0,0);
                         client_send(router.ips[hdr->router_id], router.ports[hdr->router_id], send_buf, HDR_SIZE + sizeof(struct nacq));
                         free(send_buf);


                    //     printf("link value 1: %fn",adj_mat[router.my_id][hdr->router_id] );
                         printf("be neighbour request refused. router blacklisted: %dn", hdr->router_id);

                         }
                    }

                    else if(((struct nacq *) (buf + HDR_SIZE))->type == BE_NEIGHBOR_ACCEPT)
                    {
                         changeadj(router.my_id,hdr->router_id,1,0,0);
                         //int a =1;
                    //     printf("nlink value after NACQ ACCEPT: %f", adj_mat[router.my_id][hdr->router_id]);
                    //     puts("neighbour accept received. now neighbors");
                         printf("connected to router %d:%s...n", hdr->router_id, router.ips[hdr->router_id]);
                    }

                    else if(((struct nacq *) (buf + HDR_SIZE))->type == BE_NEIGHBOR_REFUSE)
                    {
                         changeadj(router.my_id,hdr->router_id,0,0,0);
                    }
                    break;

                    case RTT:
                    if(((struct rtt *) (buf + HDR_SIZE))->type == RTT1)
                    {
                         struct rtt reply;
                         reply.type = RTT2;
                         reply.time = ((struct rtt *) (buf + HDR_SIZE))->time;
                         void *send_buf = malloc(HDR_SIZE + sizeof(struct rtt));
                         create_pkt(send_buf, router.my_id, RTT, sizeof(struct rtt), (void *)&reply,0,0);
                         client_send(router.ips[hdr->router_id], router.ports[hdr->router_id], send_buf, HDR_SIZE + sizeof(struct rtt));
                    //     puts("RTT2 sent");
                         free(send_buf);
                    }
                     else if(((struct rtt *) (buf + HDR_SIZE))->type == RTT2)
                     {
                         unsigned long long diff = (current_timestamp() - ((struct rtt *) (buf + HDR_SIZE))->time);

                         changeadj(router.my_id,hdr->router_id,3,diff,0);
                         changeadj(hdr->router_id,router.my_id,3,diff,0);
                    //     printf("nlink value connecting  %d: %f",hdr->router_id,adj_mat[router.my_id][hdr->router_id] );

                         // send rtt3
                         struct rtt reply;
                         reply.type = RTT3;
                         reply.link_cost= adj_mat[router.my_id][hdr->router_id];
                    //     printf("nlink cost being sent in rtt3:%f",adj_mat[router.my_id][hdr->router_id]);
                         //reply.time = ((struct rtt *) (buf + HDR_SIZE))->time;
                         void *send_buf = malloc(HDR_SIZE + sizeof(struct rtt));
                         create_pkt(send_buf, router.my_id, RTT, sizeof(struct rtt), (void *)&reply,0,0);
                         client_send(router.ips[hdr->router_id], router.ports[hdr->router_id], send_buf, HDR_SIZE + sizeof(struct rtt));
                    //     puts("RTT2 sent");
                         free(send_buf);
                    }
                    else if(((struct rtt *) (buf + HDR_SIZE))->type == RTT3)
                    {

                    changeadj(router.my_id,hdr->router_id,4,0,((struct rtt *) (buf + HDR_SIZE))->link_cost);
                    changeadj(hdr->router_id,router.my_id,4,0,((struct rtt *) (buf + HDR_SIZE))->link_cost);
               //     printf("nnow my new cost from rtt3:%f",adj_mat[router.my_id][hdr->router_id]);
                    }
                    else if(((struct rtt *) (buf + HDR_SIZE))->type == RTT4)
                    {
                         hosts[hdr->router_id]=1;
                         changeadj(router.my_id,hdr->router_id,1,0,0);
                         changeadj(hdr->router_id,router.my_id,1,0,0);
                         struct rtt reply;
                         reply.type = RTT5;
                         reply.time = ((struct rtt *) (buf + HDR_SIZE))->time;
                         void *send_buf = malloc(HDR_SIZE + sizeof(struct rtt));
                         create_pkt(send_buf, router.my_id, RTT, sizeof(struct rtt), (void *)&reply,0,0);
                         client_send(router.ips[hdr->router_id], router.ports[hdr->router_id], send_buf, HDR_SIZE + sizeof(struct rtt));
                    //     puts("RTT2 sent");
                         free(send_buf);
                    }
                    else if(((struct rtt *) (buf + HDR_SIZE))->type == RTT6)
                    {

                    changeadj(router.my_id,hdr->router_id,4,0,((struct rtt *) (buf + HDR_SIZE))->link_cost);
                    changeadj(hdr->router_id,router.my_id,4,0,((struct rtt *) (buf + HDR_SIZE))->link_cost);
               //     printf("nnow my new cost from rtt3:%f",adj_mat[router.my_id][hdr->router_id]);
                    }


                    break;

                    case LSA:

                         if(((struct lsa *)(buf + HDR_SIZE))->lsa_type == PERODIC)
                         {
                              int i;
                              int j;
                              int p;
                              if(((struct lsa *)(buf + HDR_SIZE))->lsa_id == router.my_id)
                              {
                                   break;
                              }
                              if(prev_lsa_seq[((struct lsa *)(buf + HDR_SIZE))->lsa_id] >= ((struct lsa *)(buf + HDR_SIZE))->seq)
                              {
                                   if(prev_lsa_ts[((struct lsa *)(buf + HDR_SIZE))->lsa_id] > ((struct lsa *)(buf + HDR_SIZE))->age)
                                   {
                                        break;
                                   }
                              }

                              prev_lsa_seq[((struct lsa *)(buf + HDR_SIZE))->lsa_id] = ((struct lsa *)(buf + HDR_SIZE))->seq;
                              prev_lsa_ts[((struct lsa *)(buf + HDR_SIZE))->lsa_id] = current_timestamp();


//                              pthread_mutex_lock (&mutexadj);
//                              memcpy(adj_mat[((struct lsa *)(buf + HDR_SIZE))->lsa_id], ((struct lsa *)(buf + HDR_SIZE))->lsa_cost, n * sizeof(double));
//                              pthread_mutex_unlock (&mutexadj);
                              pthread_mutex_lock (&mutexadj);
                              for(p=0;p<n;p++)
                              {
                                   adj_mat[((struct lsa *)(buf + HDR_SIZE))->lsa_id][p]= ((struct lsa *)(buf + HDR_SIZE))->lsa_cost[p];
                                   adj_mat[p][((struct lsa *)(buf + HDR_SIZE))->lsa_id]= ((struct lsa *)(buf + HDR_SIZE))->lsa_cost[p];
                              //     printf("nLSA received : %f", adj_mat[((struct lsa *)(buf + HDR_SIZE))->lsa_id][p]);
                              }
                              pthread_mutex_unlock (&mutexadj);
                              //((struct lsa *)(buf + HDR_SIZE))->ttl--;
                              if(((struct lsa *)(buf + HDR_SIZE))->ttl == 0)
                              {
                                   break;
                              }

                              void *send_buf = malloc(HDR_SIZE + sizeof(struct lsa));
                              create_pkt(send_buf, router.my_id, LSA, sizeof(struct lsa), (void *)((struct lsa *)(buf + HDR_SIZE)),0,0);
                              struct lsa readd;
                              for(i = 0; i < n; i++)
                              {
                                   if(i==hdr->router_id) continue;
                                   if(i==router.my_id) continue;
                                   if(links[i] == 0) continue;
                                   if(adj_mat[router.my_id][i] == 0) continue;

                                   readd.lsa_id = ((struct lsa *)(buf + HDR_SIZE))->lsa_id;
                                   readd.seq = ((struct lsa *)(buf + HDR_SIZE))-> seq;
                                   readd.age = ((struct lsa *)(buf + HDR_SIZE))->age;
                                   readd.lsa_type = ((struct lsa *)(buf + HDR_SIZE))->lsa_type;
                                   readd.ttl = ((struct lsa *)(buf + HDR_SIZE))->ttl--;
                                   for(k=0;k<n;k++)
                                   {
                                        readd.lsa_cost[k] = ((struct lsa *)(buf + HDR_SIZE))->lsa_cost[k];
                                   }

                                   create_pkt(send_buf, router.my_id, LSA, sizeof(struct lsa), (void *)&readd,0,0);
                                   client_send(router.ips[i], router.ports[i], send_buf, HDR_SIZE + sizeof(struct lsa));
                              //     puts("lsa readvertised");
//                                   for(j=0;j<n;j++)
//                                   {
//                                        for(k=0;k<n;k++)
//                                        printf("%fn",adj_mat[j][k] );
//                                   }

                              }
                              free(send_buf);
                         }
                         break;

               }
          }


          //puts("done");
     }




}

//  creating a socket and binding
int socket_bind(int port)     // bind to a particular address? instead of any
{
     struct sockaddr_in si_me;
     int set, s, slen = sizeof(struct sockaddr_in);

     if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
     diep("socket");

     puts("socket created");
     bzero((char *) &si_me, slen);
     si_me.sin_family = AF_INET;
     si_me.sin_port = htons(port);
     si_me.sin_addr.s_addr = htonl(INADDR_ANY);
     if(bind(s, (struct sockaddr *)&si_me, slen) == -1)
     diep("bind");

     printf("bound to %d...n", port);

     //     The SO_RCVTIMEO value is used for socket API calls that are waiting for data to arrive.
          //     SO_RCVTIMEO value for a socket is 5 seconds. If a read API call is issued for the socket and no data arrives in 5 seconds,
          //      control will be passed back to the application with a return code indicating that the operation timed out.
               struct timeval tv;
               tv.tv_sec = 5;          // 5s
               tv.tv_usec = 0;
              set =setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
              if(set == -1)
               perror("setsock");
     return s;
}




// MAIN
int main(int argc, char **argv)
{
     int i;
     n = 7;
     router.ips = (char **)malloc(sizeof(char *) * n);
     router.ports = malloc(sizeof(int) * n);
     router.ftr_sendports = malloc(sizeof(int) * n);
     router.ftr_receiveports = malloc(sizeof(int) * n);
     adj_mat = malloc(sizeof(double *) * n);
     alive_check=malloc(sizeof(unsigned long)*n);
     G=  malloc(sizeof(double *) * n);
     links = malloc(sizeof(int) * n);
     blacklist= malloc(sizeof(int) * n);
     prev_alive_seq =  malloc(sizeof(unsigned long)*n);
     prev_lsa_seq = malloc(sizeof(unsigned long) * n);;
     prev_lsa_ts = malloc(sizeof(unsigned long long) * n);

     bzero(prev_alive_seq, sizeof(unsigned long ) * n);
     bzero(prev_lsa_seq, sizeof(unsigned long ) * n);
     bzero(prev_lsa_ts, sizeof(unsigned long long ) * n);
     bzero(blacklist, sizeof(int ) * n);
     bzero(alive_check, sizeof(unsigned long ) * n);

     puts("1");

     for( i = 0; i < n; i++)
     {
          router.ips[i] = (char *)malloc(256);
          adj_mat[i] = malloc(sizeof(double) * n);
          G[i] = malloc(sizeof(double) * n);
          bzero(adj_mat[i], sizeof(double) * n);
          bzero(G[i], sizeof(double) * n);
          bzero(router.ips[i], sizeof(char) * 256);


     }

     //puts("2");

     router.ips[0]=("127.0.0.4");
     router.ips[1]=("127.0.0.1");
     router.ips[2]=("127.0.0.2");
     router.ips[3]=("127.0.0.3");
     router.ips[4]=("127.0.0.5");
     router.ips[5] =("127.0.0.6");// 5 and 6 used as cloent and server. // 5 client. 6 server.
     router.ips[6] =("127.0.0.7");
     //puts("3");
     router.ports[0]=8981;
     router.ports[1]=8982;
     router.ports[2]=8983;
     router.ports[3]=9984;
     router.ports[4]=9985;
     router.ports[5]=9986; // 5 is client
     router.ports[6]=9987; // 6 is server.
     //puts("4");
     router.ftr_sendports[0]=6741;
     router.ftr_sendports[1]=6742;
     router.ftr_sendports[2]=6743;
     router.ftr_sendports[3]=6744;
     router.ftr_sendports[4]=6745;
     router.ftr_sendports[5]=6746;
     router.ftr_sendports[6]=6747;
     //puts("5");
     links[0]=0;
     links[1]=1;
     links[2]=0;
     links[3]=1;
     links[4]=0;
     links[5]=0;
     links[6]=0;
     //puts("6");
     blacklist[0]=0;
     blacklist[1]=0;
     blacklist[2]=0;
     blacklist[3]=0;
     blacklist[4]=0;
     blacklist[5]=0;
     blacklist[6]=0;
     //puts("7");




     if(argc != 2)
     {
          printf("Provide a router id. Usage <filename.exe> <routerid>");
     //     exit(-1);
     }
     //puts("8");

     router.my_id = atol(argv[1]);  // The C library function long int atol(const char *str) converts the string argument str to a long integer (type long int).
     puts("9");
     printf("starting router %lu at %s:%d...n", router.my_id, router.ips[router.my_id], router.ports[router.my_id]);
     puts("10");

     server_sock = socket_bind(router.ports[router.my_id]);
     ftr_sock = socket_bind(router.ftr_sendports[router.my_id]);

     //puts("8");

     pthread_mutex_init(&mutexbuf, NULL);  // mutex initialization for receive buffer.
      pthread_mutex_init(&send_mutexbuf, NULL); // mutex initilization for send buffer.// mutex initilization for send buffer.
      pthread_mutex_init(&mutexadj, NULL);

     pthread_t t_server_listen;
     pthread_create(&t_server_listen, NULL, server_listen, NULL);

     //puts("9");

     pthread_t t_nacq;
     pthread_create(&t_nacq, NULL, nacq, NULL);

     pthread_t t_alive;
     pthread_create(&t_alive, NULL, alive, NULL);


     pthread_t t_rtt;
     pthread_create(&t_rtt, NULL, rtt, NULL);

     pthread_t t_adperodic;
     pthread_create(&t_adperodic, NULL, adperodic, NULL);

     pthread_t t_dij;
     pthread_create(&t_dij, NULL, dij, NULL);









//     printf("Enter the receiver id for file transfern");
//     scanf("%lu", &receiver);
//     printf("receiver id %lu",receiver);

//     pthread_t t_filetransfer;
//     pthread_create(&t_filetransfer, NULL, filetransfer, NULL);

     pthread_join(t_server_listen, NULL);
     pthread_join(t_nacq, NULL);
     pthread_join(t_rtt, NULL);
     pthread_join(t_adperodic, NULL);
     pthread_join(t_alive, NULL);
     pthread_join(t_dij, NULL);
//     pthread_join(t_filetransfer, NULL);







     return 0;
}
          
          
Comments: