示例#1
0
文件: router.c 项目: siddarth/router
/*
 * void
 * handle_stdin
 *
 * Handle the standard input from the user and call the appropriate
 * functions
 */
void handle_stdin(char buff[80]) {  
  char c;
  int i;

  /* If only one character is present */
  if(sscanf(buff, "%c", &c) == 1) {
    switch(buff[0]) {
      case 'N':
        print_neighbors();
        return;
      case 'T':
        print_routing_table();
        return;
      case 'p':
        print_router();
        return;
    }
  }

  /* To send messages */
  if(sscanf(buff, "%d", &i) == 1) {
    if(i >= 0 && i<=19)
      send_msg(i);
      return;
  }

  /* Reject policy */
 	if(sscanf(buff, "R %d", &i) == 1) {
    if(i < 0 || i > 19)
      printf("Invalid router ID specified.");
		else if(router.is_border_router == FALSE) {
			printf("Reject commands can be run only on border routers.\n");
		}
		else {
			printf("Router rejected: %d.", i);
      reject(i);
    }
    printf("\n\n");
		fflush(stdout);
		return;
	}

  /* Prefer policy */
  if(buff[0] == 'P') {
		if(router.is_border_router == FALSE) {
			printf("Commands to set preferred paths can be run only on \
              border routers.\n\n");
      fflush(stdout);
      return;
		}

    set_prefer_policy(buff);

    return;
  }
int main(int argc, char *argv[])
{
	/* check command line args. */
	if(argc < 4){
		printf("usage : %s <RouterID> <LogFileName> <Initialization file> \n", argv[0]);
		exit(1);
	}
	
	char *router_id;
	char *log_filename;
	char *init_file;
	FILE *log_file;
	
	int nbytes;
	
	// Extract arguments
	router_id = argv[1];
	log_filename = argv[2];
	init_file = argv[3];

    Router router;
    router = router_init(*router_id,init_file);
    //printf("Router init:\n");
    //print_router(router);
    
    
    
    // Open log file
    log_file = fopen(log_filename, "wb");
    if (!log_file)
    {
        printf("Failed open log file %s for router %s.\n", argv[2], argv[1]);
        exit(1);
    }
    
    router = initSock(router);
    //printf("Router after initSock:\n");
    //print_router(router);
    
    // Initialize LSP of this router
    LSP_init(&router);
	print_LSP(&router.self_packet,log_filename);
	
	LSP lsp = router.self_packet;
	// Each router has an array of recently received packets
	// Receive buffer
    //LSP buffer_packet;
    LSP templsp; 
    //LSP checklsp;
    
    char* buffer = malloc(sizeof(LSP));
    //bzero(buffer,sizeof(buffer));
    //memcpy(buffer,(char*) &lsp, sizeof(LSP));
    //memcpy((char*) &checklsp, buffer, sizeof(LSP));
    //print_LSP(&checklsp, log_file);
    //printf("router id: %c\nsequence number: %d\n sizeof: %d\n",checklsp.router.ID,checklsp.seq_num, (int) sizeof(lsp));
    
    // initialize router routing table
    routing_table_init(&router);
    print_routing_table(&router, log_filename);
    
    fclose(log_file);
    // ??    
        int i, j;
    fd_set readSet;
    fd_set tempReadSet; 
    
    FD_ZERO(&readSet);
    FD_ZERO(&tempReadSet);
    
    //first try to connect to neighbors 
    for(i = 0; i< router.nbrs_count; i++) 
    {
		if(TCPconnect(router.nbrs[i]) < 0)
			router.nbrs[i].connectedR = 0;
		else 
			router.nbrs[i].connectedR = 1;
     } 
	
	
     //then listen 
     for(i = 0; i<  router.nbrs_count; i++) 
     {
		 TCPlisten(router.nbrs[i]);
		 FD_SET(router.nbrs[i].localSock,&readSet);
      }
    
    int highSock;

    highSock = router.nbrs[0].localSock; 
    for(i = 0; i < router.nbrs_count-1; i++ )
    {
		highSock = router.nbrs[i].localSock > router.nbrs[i+1].localSock? router.nbrs[i].localSock: router.nbrs[i+1].localSock; 
    }
    
    int counter = 0; 
    struct timeval tv; 
    tv.tv_sec = 5;         
    tv.tv_usec = 0; 
    
    // Select: while router is listening, it waits for one or more neighbors
    // to connect.            
    for(;;)
    {
		tv.tv_sec = 5;         
        tv.tv_usec = 0;
                        
        tempReadSet = readSet; 
        printf("- %d\n", counter);
                                
        if(select(highSock+1, &tempReadSet, 0, 0, &tv) < 0) 
        {
			printf("select error!\n");
		}
		
		//CHECK FD
		for(i = 0; i< router.nbrs_count; i++) 
		{
			// for select: Check if there's a connection or not
            if(FD_ISSET(router.nbrs[i].localSock, &tempReadSet))
            {
				// Accept connections
				if( router.nbrs[i].connectedS == 0) 
				{
					int newSock;
					if ((newSock = TCPaccept(router.nbrs[i])) > -1)
					{
						router.nbrs[i].connectedS= 1;
						router.nbrs[i].localSock = newSock;
						
						printf("sock: %d\n",router.nbrs[i].localSock);
						printf("connectedS: %d\n",router.nbrs[i].connectedS);
						
						FD_SET(router.nbrs[i].localSock,&readSet);
						if(highSock < newSock)
							highSock = newSock; 
					}
				}
				
				// Receive LSPs
				else
				{
					bzero(buffer,sizeof(LSP));
					socklen_t size = sizeof(&router.nbrs[i].localAddr);
					
					if(recvfrom(router.nbrs[i].localSock, buffer, sizeof(LSP), 0, (struct sockaddr *) &router.nbrs[i].localAddr, &size) <0)
					{
						printf("error receiving from node %s\n", router.nbrs[i].ID);
					}
					else
					{
						printf("LSP received from %s \n",router.nbrs[i].ID);
						memcpy((char *)&templsp, buffer, sizeof(LSP));
						//print_LSP(&templsp,log_file);
						
						// Check if received lsp is new
						int check_lsp_flag = check_LSP(&router, &templsp);
						if (check_lsp_flag == 1 || check_lsp_flag == 2)
						{
							// Log if LSP caused change in routing table.
							if(check_lsp_flag == 2)
							{
								print_LSP(&templsp, log_filename);
								print_routing_table(&router,log_filename);
							}
							
							// 2. Flood to all links, except where it came from
							for(j = 0; j<router.nbrs_count; j++)
							{
								if((j != i) && router.nbrs[i].connectedR == 1)
								{
									//buffer = malloc(sizeof(LSP));
									//bzero(buffer, sizeof(LSP));
									//memcpy(buffer, (char*) &lsp, sizeof(LSP));
									//memcpy((char *)&templsp, buffer, sizeof(LSP)); 
									
									nbytes = sendto(router.nbrs[j].remoteSock, buffer, LSPSIZE, MSG_NOSIGNAL, (struct sockaddr*)&router.nbrs[j].remoteAddr, sizeof(router.nbrs[j].remoteAddr));
									if (nbytes == -1)
									{
										printf("Failed to send on link: %s, %d, %s, %d\n",
										router.nbrs[i].src_ID, router.nbrs[i].send_port,
										router.nbrs[i].ID, router.nbrs[i].recv_port);
									}
									
									else
									{
										printf("Forward LSP from %s to %s\n", templsp.routerID, router.nbrs[j].ID);
										//print_LSP(&templsp, log_file);
									}
								}
													
													
							}
																			 
						}
					}
                                
                                
                }
            }
		}
                
            sleep(5);
                
            // Try to connect again.        
            for(i = 0; i< router.nbrs_count; i++) 
            {
				if(router.nbrs[i].connectedS == 1 &&router.nbrs[i].connectedR == 0)
				{
					if(TCPconnect(router.nbrs[i]) < 0)
					{
						printf("failed to connect to %s \n", router.nbrs[i].ID); 
						router.nbrs[i].connectedR = 0;
					}
					else
						router.nbrs[i].connectedR = 1;
				}
			}
			
			// initial and periodic flooding: Send LSP to connected links.
			lsp.seq_num++;
			for(i = 0; i<router.nbrs_count; i++)
			{
				if(router.nbrs[i].connectedR == 1)
				{
					buffer = malloc(sizeof(LSP));
					bzero(buffer, sizeof(LSP));
					memcpy(buffer, (char*) &lsp, sizeof(LSP));
					memcpy((char *)&templsp, buffer, sizeof(LSP)); 
					
					nbytes = sendto(router.nbrs[i].remoteSock, buffer, sizeof(LSP), 0, (struct sockaddr*)&router.nbrs[i].remoteAddr, sizeof(router.nbrs[i].remoteAddr));
					if (nbytes == -1)
					{
						printf("Failed to send on link: %s, %d, %s, %d\n",
						router.nbrs[i].src_ID, router.nbrs[i].send_port,
						router.nbrs[i].ID, router.nbrs[i].recv_port);
					}
					
					else
					{
						printf("Send LSP to: %s\n", router.nbrs[i].ID);
						//print_LSP(&templsp, log_file);
					}
				}
			}
			
			counter ++;  
        
        
	}
	fclose(log_file);
	return 0;      
    
     // Set router timer
    //time_t curr_time;
    //time(&router.timestamp);
    
    
    // some connection shit
    /*
     // check time, send self lsp on all ports with established link
     time(&curr_time);
     if (difftime(curr_time, router.timestamp) >= (double)5.0)
     {
		 router.timestamp = curr_time;
		 // update lsp seq
		 router.self_packet.seq++;
		 for (i=0 ; i<router.nbrs_count ; i++)
		 {
                if (router.nbrs[i].connected)
                {
                    nbytes = send(socket?, router.self_pakcet, sizeof(LSP), 0);
                    if (nbytes == -1)
                    {
                        printf("Failed to send on link: %s, %d, %s, %d\n",
                        router.nbrs[i].src_ID, router.nbrs[i].send_port,
                        router.nbrs[i].ID, router.nbrs[i].recv_port);
                    }
                    else
                    {
                        printf("Send LSP to: %s\n", router.nbrs[i].ID);
                    }
                }
            }
        }
        
     int lsp_update_flag;  
     // Receive LSP from all ports with "connected" neighbors
     for (i=0 ; i<router.nbrs_count ; i++)
     {
		 if (router.nbrs[i].connected)
		 {
			 nbytes = recv(router.nbrs[i].connect_fd, &buffer_packet, sizeof(LSP), 0);
			 if (nbytes > 0)
			 {
				 printf("LSP received from ID %s, seq %d\n", buffer_packet.router.ID, buffer_lsp.seq_num);
				 // store recvd lsp into database and determine if need forwarding
				 // also determine if need update topology and recompute
				 lsp_update_flag = update_LSP_list(&router, &buffer_lsp);
				 if (lsp_update_flag == 1)
				 {
					 // 1. Run Dijkstra!
					 printf("Update routing table...\n");
					 if (update_routing_table(&(router), &buffer_packet))
					 {
						 time(&curr_time);
                         sprintf(tmp_char_buffer, "UTC:\t%s", asctime(gmtime(&curr_time)));
                         printf("%s",tmp_char_buffer);
                         fwrite(tmp_char_buffer, sizeof(char), strlen(tmp_char_buffer), log_file);
                         print_lsp(&buffer_packet, log_file);
                         log_routing_table(&router, log_file);
                     }
					 
					 // 2. Flood LSP to all outgoing links, except where it came from
                     buffer_pacekt.ttl--;
                     int j;
                     for (j=0; j<router.nbrs_count; j++)
                     {
						 if ((j != i) && (router.nbrs[j].connected))
                         {
							 nbytes = send(router.nbrs[j].connect_fd, &buffer_packet, sizeof(LSP), 0);
							 if (nbytes == -1)
                             {
								printf("Failed to send on link: %s, %d, %s, %d\n",
								router.nbrs[i].src_ID, router.nbrs[i].send_port,
								router.nbrs[i].ID, router.nbrs[i].recv_port);
                             }
                             else
                             {
                                 printf("Forward LSP from %s to %s\n", buffer_packet.routerID, router.nbrs[j].ID);
                             }
                         }
                     }
                 }
                 
                 if(lsp_update_flag == 2)
                 {
					 // run dijkstra's algorithm
					 printf("Update routing table...\n");
					 if (update_routing_table(&(router), &buffer_packet))
					 {
						 time(&curr_time);
                         sprintf(tmp_char_buffer, "UTC:\t%s", asctime(gmtime(&curr_time)));
                         printf("%s",tmp_char_buffer);
                         fwrite(tmp_char_buffer, sizeof(char), strlen(tmp_char_buffer), log_file);
                         print_lsp(&buffer_packet, log_file);
                         log_routing_table(&router, log_file);
                     }
                 }*/
             //}
         //}

     //}      
         
        
// end if
	
}
void bellmanford()
{
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
	printf("bellmanford\n");
	int i, j, k;
	uint16_t distof_jtoi, costof_metoj;
	int index;


	print_routing_table();
	print_next_hops();

	//bellman ford algorithm start
	for (i =0; i<NUMSERVERS; i++)
	{	
		printf("i =%d \n", i);

		if (i == MYID-1)
		{
			// i dont not want to change my entry, as it will always be 0
			printf("%d...", i);
			continue;
		}

		int min_val = 9999999;
		int min_index = 0;
		int changed =0;

		for (j=0; j<NUMSERVERS; j++)
		{
			printf("j =%d ", j);
			
			if (j == MYID-1 || (SERVERLIST[j].isneighbour!= 1) )
			{
				// i dont not want to route through myself
				printf("%d...\n", j);
				continue;
			}

			costof_metoj = 	SERVERLIST[j].cost;
			distof_jtoi = ROUTINGTABLE[j][i];
			printf("costof_metoj = %d\n", costof_metoj);
			printf("distof_jtoi = %d\n", distof_jtoi);
			

			if ( (min_val > (costof_metoj + distof_jtoi)) && (costof_metoj != 65535) && (distof_jtoi != 65535) )
			{
				min_val = costof_metoj + distof_jtoi;
				min_index = j;	
				changed = 1;			
			}
			
		}		
		
		printf("min_val = %d\n", min_val);
		printf("min_index = %d\n", min_index );		
		
		if (changed ==1 )
		{
			ROUTINGTABLE[MYID-1][i] = min_val;
			SERVERLIST[i].nexthop = SERVERLIST[min_index].id;			
		}	
	}

	print_routing_table();
	print_next_hops();

	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
}
示例#4
0
int
route_calculate(struct ccn_schedule *sched, void *clienth, struct ccn_scheduled_event *ev, int flags)
{

	if(flags == CCN_SCHEDULE_CANCEL)
	{
 	 	return -1;
	}

	nlsr_lock();

	if ( nlsr->debugging )
		printf("route_calculate called\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"route_calculate called\n");

	if( ! nlsr->is_build_adj_lsa_sheduled )
	{
		/* Calculate Route here */
		print_routing_table();
		print_npt();		

		//struct hashtb_param param_me = {0};
		nlsr->map = hashtb_create(sizeof(struct map_entry), NULL);
		nlsr->rev_map = hashtb_create(sizeof(struct map_entry), NULL);
		make_map();
		assign_mapping_number();		
		print_map();
		print_rev_map();

		do_old_routing_table_updates();
		clear_old_routing_table();	
		print_routing_table();
		print_npt();

		int i;
		int **adj_matrix;
		int map_element=hashtb_n(nlsr->map);
		adj_matrix=malloc(map_element * sizeof(int *));
		for(i = 0; i < map_element; i++)
		{
			adj_matrix[i] = malloc(map_element * sizeof(int));
		}
		make_adj_matrix(adj_matrix,map_element);
		if ( nlsr->debugging )
			print_adj_matrix(adj_matrix,map_element);

		long int source=get_mapping_no(nlsr->router_name);
		int num_link=get_no_link_from_adj_matrix(adj_matrix, map_element ,source);

		if ( nlsr->is_hyperbolic_calc == 1)
		{
			long int *links=(long int *)malloc(num_link*sizeof(long int));
			long int *link_costs=(long int *)malloc(num_link*sizeof(long int));
			get_links_from_adj_matrix(adj_matrix, map_element , links, link_costs, source);

			struct hashtb_enumerator ee;
			struct hashtb_enumerator *e = &ee;
			for (hashtb_start(nlsr->rev_map, e); e->key != NULL; hashtb_next(e)) 
			{
				struct map_entry *me=e->data;
				if ( me->mapping != source )
				{
					long int *faces=(long int *)calloc(num_link,sizeof(long int));
					double *nbr_dist=(double *)calloc(num_link,sizeof(double));
					double *nbr_to_dest=(double *)calloc(num_link,sizeof(double));
					for ( i=0 ; i < num_link; i++)
					{
						int face=get_next_hop_face_from_adl(get_router_from_rev_map(links[i]));
						double dist_to_nbr=get_hyperbolic_distance(source,links[i]);
						double dist_to_dest_from_nbr=get_hyperbolic_distance(links[i],me->mapping);
						faces[i]=face;
						nbr_dist[i]=dist_to_nbr;
						nbr_to_dest[i]=	dist_to_dest_from_nbr;	

						
					}
					sort_hyperbolic_route(nbr_to_dest,nbr_dist, faces,0,num_link);
					if (nlsr->max_faces_per_prefix == 0 )
					{
						for ( i=0 ; i < num_link; i++)
						{
							update_routing_table_with_new_hyperbolic_route(me->mapping,faces[i],nbr_to_dest[i]);
						}				
					}
					else if ( nlsr->max_faces_per_prefix > 0 )
					{
						if ( num_link <= nlsr->max_faces_per_prefix )
						{
							for ( i=0 ; i < num_link; i++)
							{
								update_routing_table_with_new_hyperbolic_route(me->mapping,faces[i],nbr_to_dest[i]);
							}
						}
						else if (num_link > nlsr->max_faces_per_prefix)
						{
							for ( i=0 ; i < nlsr->max_faces_per_prefix; i++)
							{
								update_routing_table_with_new_hyperbolic_route(me->mapping,faces[i],nbr_to_dest[i]);
							}
						}

					}
					free(faces);
					free(nbr_dist);
					free(nbr_to_dest);
				}
			}
			hashtb_end(e);

			
			free(links);
			free(link_costs);
		}
		else if (nlsr->is_hyperbolic_calc == 0 )
		{

			long int *parent=(long int *)malloc(map_element * sizeof(long int));
			long int *dist=(long int *)malloc(map_element * sizeof(long int));
			
		
			if ( (num_link == 0) || (nlsr->max_faces_per_prefix == 1 ) )
			{	
				calculate_path(adj_matrix,parent,dist, map_element, source);		
				print_all_path_from_source(parent,source);
				print_all_next_hop(parent,source);		
				update_routing_table_with_new_route(parent, dist,source);
			}
			else if ( (num_link != 0) && (nlsr->max_faces_per_prefix == 0 || nlsr->max_faces_per_prefix > 1 ) )
			{
				long int *links=(long int *)malloc(num_link*sizeof(long int));
				long int *link_costs=(long int *)malloc(num_link*sizeof(long int));
				get_links_from_adj_matrix(adj_matrix, map_element , links, link_costs, source);
				for ( i=0 ; i < num_link; i++)
				{
					adjust_adj_matrix(adj_matrix, map_element,source,links[i],link_costs[i]);
					calculate_path(adj_matrix,parent,dist, map_element, source);		
					print_all_path_from_source(parent,source);
					print_all_next_hop(parent,source);		
					update_routing_table_with_new_route(parent, dist,source);
				}

				free(links);
				free(link_costs);
			}
			free(parent);
			free(dist);
		}
		
		print_routing_table();
		print_npt();

		update_npt_with_new_route();

		print_routing_table();
		print_npt();


		for(i = 0; i < map_element; i++)
		{
			free(adj_matrix[i]);
		}
		
		free(adj_matrix);
		destroy_map();
		destroy_rev_map();
		//hashtb_destroy(&nlsr->map);
		//hashtb_destroy(&nlsr->rev_map);
		
	}
	nlsr->is_route_calculation_scheduled=0;

	nlsr_unlock();

	return 0;
}