📄 myrip.cpp
字号:
{ printf("packet received from %s\n", inet_ntoa(source_addr)); print_rip_packet(); if ((check_rip_packet() == RIP_CHECK_OK)) { pthread_mutex_lock(&rt_mutex); switch(current_rip_packet.command) { case RIP_REQUEST: handle_request(source_addr); break; case RIP_RESPONSE: handle_response(source_addr); break; default: break; } pthread_mutex_unlock(&rt_mutex); } else { print_message("error:", "packet check error"); } }}void handle_request(struct in_addr &source_ip){ if (current_route_count <= 0) { print_message("warnning:", "the route table is empty"); return; } // reset_rip_packet(RIP_RESPONSE); //request for the whole route_table if (current_rip_count == 1 && current_rip_packet.rip_entries[0].family == 0 && current_rip_packet.rip_entries[0].metric == 16) { int route_iterator = 0; int sended_route_entry = 0; for(sended_route_entry = 0; sended_route_entry < current_route_count; sended_route_entry += RIP_MAX_ENTRY) { reset_rip_packet(RIP_RESPONSE); current_rip_count = 0; while((route_iterator < current_route_count)&&(current_rip_count < RIP_MAX_ENTRY)) { //printf("test!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); if (routing_table[route_iterator].dest.s_addr != source_ip.s_addr && routing_table[route_iterator].next.s_addr != source_ip.s_addr && routing_table[route_iterator].valid) { current_rip_packet.rip_entries[current_rip_count].ip.s_addr = routing_table[route_iterator].dest.s_addr; current_rip_packet.rip_entries[current_rip_count].metric = routing_table[route_iterator].metric; current_rip_count++; } route_iterator++; } current_rip_packet.command = RIP_RESPONSE; printf("respond to request----------------------------------\n"); send_rip_packet_to(source_ip); // printf("----------------------------------------------------\n"); } return; } //request for certain route entry for (int i = 0; i < current_rip_count; i++) { int j; for (j = 0; j < current_route_count; j++) { if (routing_table[j].dest.s_addr == current_rip_packet.rip_entries[i].ip.s_addr && routing_table[j].valid) { current_rip_packet.rip_entries[current_rip_count].ip.s_addr = routing_table[j].dest.s_addr; current_rip_packet.rip_entries[current_rip_count].metric = routing_table[j].metric; //current_rip_count++; break; } } if(j == current_rip_count) { current_rip_packet.rip_entries[i].metric = RIP_INFINITY; } } current_rip_packet.command = RIP_RESPONSE; //send_rip_packet_to(source_ip); printf("respond to request----------------------------------\n"); send_rip_packet_to(source_ip); // printf("----------------------------------------------------\n"); return;}void handle_response(struct in_addr &source_ip){ int route_exist = 0; int old_route_count = current_route_count; for (int i = 0; i < current_rip_count; i++) { route_exist = 0; for (int j = 0; j < old_route_count; j++) { if (routing_table[j].dest.s_addr == current_rip_packet.rip_entries[i].ip.s_addr) { route_exist = 1; if((routing_table[j].next.s_addr == current_rip_packet.rip_entries[i].ip.s_addr) ||(routing_table[j].metric > calculate_rip_metric(i))) { routing_table[j].next.s_addr = source_ip.s_addr; routing_table[j].metric = calculate_rip_metric(i); } routing_table[j].timer = time(NULL); routing_table[j].valid = 1; routing_table[j].flag = 1;///to be trigger... break; } } if (route_exist == 0 && calculate_rip_metric(i) != RIP_INFINITY) { routing_table[current_route_count].dest.s_addr = current_rip_packet.rip_entries[i].ip.s_addr; routing_table[current_route_count].next.s_addr = source_ip.s_addr; routing_table[current_route_count].metric = calculate_rip_metric(i); routing_table[current_route_count].timer = time(NULL); routing_table[current_route_count].valid = 1; routing_table[current_route_count].flag = 1;//to be trigger... current_route_count++; } } current_rip_count = 0; reset_rip_packet(RIP_RESPONSE); for (int n = 0; n < current_route_count; n++) { if( routing_table[n].flag == 1 ) { current_rip_packet.rip_entries[current_rip_count].ip.s_addr = routing_table[n].dest.s_addr; current_rip_packet.rip_entries[current_rip_count].metric = routing_table[n].metric; current_rip_count++; current_rip_packet.command = RIP_RESPONSE; routing_table[n].flag = 0; } } printf("update routing table caused by respond--------------\n"); send_rip_packet_to(source_ip); // printf("----------------------------------------------------\n"); //send_rip_packet_to(source_ip);}void * timer_routine(void *){ int broadcasted_rip_count; time_t time_prev; time_t time_after; time_prev = time(NULL); while(1) { sleep(5); time_after = time(NULL); pthread_mutex_lock(&rt_mutex); update_routing_table(); pthread_mutex_unlock(&rt_mutex); if ((time_after - time_prev) >= (time_t)BROADCAST_INTERVAL ) { printf("begin broadcasting...\n"); //pthread_mutex_lock(&crp_mutex); current_rip_packet.command = RIP_RESPONSE; current_rip_packet.version = 1; broadcasted_rip_count = 0; for(broadcasted_rip_count = 0; broadcasted_rip_count < current_route_count; broadcasted_rip_count += RIP_MAX_ENTRY) { reset_rip_packet(RIP_RESPONSE); current_rip_count = 0; for (int i = 0; (i < current_route_count)&&(i < RIP_MAX_ENTRY); i++) { current_rip_packet.rip_entries[current_rip_count].ip = routing_table[i].dest; current_rip_packet.rip_entries[current_rip_count].metric = routing_table[i].metric; current_rip_count++; } broadcast_rip_packet(); //pthread_mutex_unlock(&crp_mutex); //printf("broadcast 25 rip packets...\n"); } printf("broadcast green...\n"); time_prev = time(NULL); } }}void start_rip_daemon(){ pthread_t timer_thread; gen_request_all(); broadcast_rip_packet(); printf("broadcast over in start_rip\n"); //print_route_table(); pthread_create(&timer_thread,NULL,timer_routine,NULL); while(1) { printf("begin receiving...\n"); //pthread_mutex_lock(&crp_mutex); receive_rip_packet(); //pthread_mutex_unlock(&crp_mutex); printf("receive green...\n"); close(sockfd); } pthread_join(timer_thread, NULL);}void update_routing_table(){ time_t time_after = time(NULL); int old_pos = 0, new_pos=0; int old_route_count = current_route_count; //old_pos rember the ending of block that should be removed from routing table //new_pos remver the beginning of block that should be removed frome routing table int count;//number of entries in the block that should stay in routing table int update = 0; while(old_pos < current_route_count) { count = 0; while((time_after-routing_table[old_pos+count].timer) < (time_t)GARBAGE_REMOVE_TIMEOUT && old_pos+count < current_route_count) { //need to be set to invalid if (routing_table[old_pos+count].valid && (time_after-routing_table[old_pos+count].timer) >= (time_t)CLOCK_TIMEOUT) { routing_table[old_pos+count].valid = 0; update++; } count++; } if (old_pos+count < current_route_count && old_pos != new_pos) { //need to remove bad entries from routing table for (int i=0; i < count; i++) { routing_table[new_pos+i].dest.s_addr = routing_table[old_pos+i].dest.s_addr; routing_table[new_pos+i].next.s_addr = routing_table[old_pos+i].next.s_addr; routing_table[new_pos+i].metric = routing_table[old_pos+i].metric; routing_table[new_pos+i].timer = routing_table[old_pos+i].timer; routing_table[new_pos+i].valid = routing_table[old_pos+i].valid; routing_table[new_pos+i].flag = routing_table[old_pos+i].flag; } } new_pos += count; old_pos += count; while((time_after-routing_table[old_pos+count].timer) >= (time_t)GARBAGE_REMOVE_TIMEOUT && old_pos < current_route_count) old_pos ++; } current_route_count = new_pos; if (old_route_count != new_pos || update > 0) { printf("--- Route Table Updated ---\n"); print_routing_table(); }}int main(){ init_all(); printf("init green\n"); start_rip_daemon(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -