📄 aodv_routing.pr.c
字号:
aodv_print_minor(">>> Precursor list is empty: skip to the next destination", TRACE_LEV_1); } } else { // Trace sprintf(msg, "Skipping destination %d", lost_node->dest_ip_addr); aodv_print_minor(msg, TRACE_LEV_1); } // Skip[to next element current_element = current_element->next; } // If at least one destination is still in the list // of unreachable destinations, then rebroadcast RERR // Else, packet is destroyed if(aodv_list_size(new_rerr_lost_node_list) > 0) { // trace sprintf(msg, "%d destinations still in the list: Broadcasting new RERR", aodv_list_size(rerr_lost_node_list)); aodv_print_minor(msg , TRACE_LEV_1); // detroy previous packet op_pk_destroy(rerr_pk_ptr); // Create a new one new_rerr_pk_ptr = op_pk_create_fmt("AODV_RERR"); // Set N field value op_pk_nfd_set(new_rerr_pk_ptr,"N", 0); // Set DestCount field op_pk_nfd_set(new_rerr_pk_ptr,"DestCount", aodv_list_size(new_rerr_lost_node_list)); // Set RERR payload op_pk_nfd_set(new_rerr_pk_ptr,"Payload",new_rerr_lost_node_list,op_prg_mem_copy_create,op_prg_mem_free,sizeof(Aodv_List));
// Set size op_pk_total_size_set(new_rerr_pk_ptr, 32*(1+2*aodv_list_size(new_rerr_lost_node_list))); // Trace aodv_print_minor("New RERR packet has been generated", TRACE_LEV_1);
// Send to mac Layer aodv_pk_send(new_rerr_pk_ptr, BROADCAST); } else { // trace aodv_print_minor("No more destination left: Destroying RERR", TRACE_LEV_1); op_pk_destroy(rerr_pk_ptr); } }/**************************************************/* This routine is called to redirect the received /* RERR packet. In fact, different functions are/* called according the fact that the N flag is set/* or not.**************************************************/void aodv_rerr_pk_receive(Packet* pk_ptr) { int rerr_previous_hop; int rerr_n_flag = 0; // Read packet op_pk_nfd_get(pk_ptr, "N", &rerr_n_flag); op_pk_nfd_get(pk_ptr, "PreviousHop", &rerr_previous_hop); // maintain local connectivity if(CONN_SUPPORT_TYPE == NONE) aodv_maintain_local_conn(rerr_previous_hop); // check the N flag value if(rerr_n_flag) { // trace aodv_print_minor("N flag is set: calling appropriate function", TRACE_LEV_1); // Process non delete RERR aodv_non_delete_rerr_pk_process(pk_ptr); } else { // Process regular RERR aodv_rerr_pk_process(pk_ptr); } }/**************************************************/* This routine receives the RERR packets whose N/* flag is set. When such a packet is received, node/* effectively processes it, only if the previous hop/* is the next hop toward the unreacheable destination/* (the one included in the list of unreachable /* destinations of the RERR packet). If so, the /* current node checks the precursor list of the entry/* corresponding to the unreachable destination./* If it is empty, RERR has reached the source node./* The latter initiates a discovery service in order/* to update its entry for the repaired destination./* Else, if the precursor list is not empty, then node/* simply forwards the RERR./* In all other cases, RERR is destroyed.**************************************************/void aodv_non_delete_rerr_pk_process(Packet* rerr_pk_ptr) { Aodv_Route_Table_Entry * entry; Aodv_List * rerr_lost_node_list; Aodv_Lost_Node * lost_node; int rerr_dest_count; int rerr_previous_hop; // Read previous hop op_pk_nfd_get(rerr_pk_ptr, "PreviousHop", &rerr_previous_hop); // Read the number of unreachable destinations // if it exceeds 1, than stop simulation op_pk_nfd_get(rerr_pk_ptr, "DestCount", &rerr_dest_count); // Check if(rerr_dest_count > 1) { // Error: packet should contain only one unreachable dest op_sim_end("Error @ receive non delete RERR", "More than one destinations are included in the pk","",""); } // Continue processing // read the list of unreachable destinations from pk op_pk_nfd_access(rerr_pk_ptr, "Payload", &rerr_lost_node_list); // If list is not null, then read first (and only) destination if(rerr_lost_node_list != OPC_NIL) { lost_node = (Aodv_Lost_Node*) aodv_list_access_first(rerr_lost_node_list); // read the entry for that destination in the routing table //entry = aodv_rt_access_entry(my_route_table, lost_node->dest_ip_addr); // Proceed, only if active entry exist, and if the next hop field is the previous hop from which // the RERR was received if (my_route_table[lost_node->dest_ip_addr].entry_exist && my_route_table[lost_node->dest_ip_addr].breakage_flag != 1 && my_route_table[lost_node->dest_ip_addr].next_hop == rerr_previous_hop) { // Now, if the precursor_list is not empty, then set // the RERR packet need to be forwarded. if( aodv_list_size(my_route_table[lost_node->dest_ip_addr].list_prec) > 0) { // trace aodv_print_minor("RERR received from next hop toward destination: Forwarding packet", TRACE_LEV_1); // forward rerr pk aodv_pk_send(rerr_pk_ptr, BROADCAST); } else { // Packet has reached its source node. // trace aodv_print_minor("RERR has reached the source node", TRACE_LEV_1); // destroy packet op_pk_destroy(rerr_pk_ptr); // Invalidate entry (this includes the following actions: // 1. Copying hop count value into last hop count field // 2. Setting hop count value to infinity // 3. Incrementing seq nb by one.) // trace if(my_route_table[lost_node->dest_ip_addr].entry_exist) { aodv_print_minor("Invalidating entry", TRACE_LEV_1); aodv_entry_invalidate (&my_route_table[lost_node->dest_ip_addr]); aodv_entry_reschedule_intrpt(&my_route_table[lost_node->dest_ip_addr], op_sim_time()+DELETE_PERIOD); // Set seq nb my_route_table[lost_node->dest_ip_addr].dest_seq_nb = lost_node->dest_seq_nb; // Initiate discovery // trace aodv_print_minor("Buffer not empty: Initiating discovery service", TRACE_LEV_1); aodv_initiate_discovery (lost_node->dest_ip_addr); } else { // trace aodv_print_minor("Entry does not exist: No action taken", TRACE_LEV_1); } } } else { aodv_print_minor("Current node is not concerned: Packet destroyed", TRACE_LEV_1); } } }/**************************************************/* This routine is called whenever a brodcast is /* received (to the exception of Hello messages)./* The idea is to update the previous hop entry in /* the routing table. The previous hop is the node/* that last brodcast the packet.**************************************************/void aodv_maintain_local_conn(int previous_hop) { Aodv_Route_Table_Entry * entry; double lifetime = ALLOWED_HELLO_LOSS * HELLO_INTERVAL; //aodv_prg_print_rt(TRACE_LEV_0); if(!my_route_table[previous_hop].entry_exist) { aodv_print_minor("Maintain local conn: entry was created", TRACE_LEV_1); aodv_rt_create_entry(my_route_table, previous_hop); my_route_table[previous_hop].next_hop = previous_hop; my_route_table[previous_hop].dest_seq_nb = 0; my_route_table[previous_hop].hop_count = 1; aodv_entry_schedule_intrpt(&my_route_table[previous_hop], op_sim_time()+lifetime); // if request was pending, then reset it and serve buffer if(req_sent_rep[previous_hop].pending) { // reset request aodv_cancel_pending_request(previous_hop); // serve buffer aodv_buffer_serve(previous_hop); } } else if(my_route_table[previous_hop].entry_exist) { // read entry //entry = aodv_rt_access_entry(my_route_table, previous_hop); if(my_route_table[previous_hop].next_hop != previous_hop) { // A shorter path was found. Node should may be // generate a RREQ aodv_print_minor("Maintain local conn: a shorter path was found. What next ?", TRACE_LEV_1); } else { // Extend lifetime aodv_print_minor("Maintain local conn: entry already exists", TRACE_LEV_1); aodv_rt_entry_extend_intrpt(my_route_table, previous_hop, op_sim_time()+lifetime); } } // Trace if(DEBUG) aodv_entry_print(&my_route_table[previous_hop], my_node_addr); // serve buffer (debug) //aodv_buffer_serve(previous_hop); } /**************************************************/* This routine is called when an entry is repaired/* with a different length (hop count). In this case,/* generates a RERR packet with the N flag set. The/* RERR packet includes the repaired destination IP/* address and its sequence number.**************************************************/void aodv_generate_non_delete_rerr_pk(int dest_ip_addr) { Aodv_Route_Table_Entry * entry; Aodv_Lost_Node * lost_node; Aodv_List * lost_node_list; Packet * rerr_pk_ptr; char msg[32]; // Trace sprintf(msg,"Generating a non-delete RERR packet: unreachable node is %d",dest_ip_addr); aodv_print_minor(msg,TRACE_LEV_1); aodv_prg_print_entry(dest_ip_addr,TRACE_LEV_3); // Generate RERR only if list of precursor is not empty if( aodv_list_size(my_route_table[dest_ip_addr].list_prec) > 0) { lost_node = (Aodv_Lost_Node *) op_prg_mem_alloc(sizeof(Aodv_Lost_Node)); lost_node_list = aodv_list_create(); // start lost_node->dest_ip_addr = dest_ip_addr; lost_node->dest_seq_nb = my_route_table[dest_ip_addr].dest_seq_nb; // Insert lost node in the list aodv_list_insert(lost_node_list, lost_node, dest_ip_addr); // Create RERR pk rerr_pk_ptr = op_pk_create_fmt("AODV_RERR"); // Set N field value op_pk_nfd_set(rerr_pk_ptr,"N", 1); // Set DestCount field op_pk_nfd_set(rerr_pk_ptr,"DestCount", aodv_list_size(lost_node_list)); // Set RERR payload op_pk_nfd_set(rerr_pk_ptr,"Payload",lost_node_list,op_prg_mem_copy_create,op_prg_mem_free,sizeof(Aodv_List)); // Set size op_pk_total_size_set(rerr_pk_ptr, 32*(1+2*aodv_list_size(lost_node_list))); // Trace aodv_print_minor("RERR packet has been generated", TRACE_LEV_1);
// Send to mac Layer aodv_pk_send(rerr_pk_ptr, BROADCAST); } else aodv_print_minor("No RERR packet has been generated: prec list is empty", TRACE_LEV_1); }/**************************************************/* This routine receives the aodv RREQ packet from/* the lower layer and decides whether the node/* should process the packet, discard it or simply/* forward it.**************************************************/void aodv_rreq_pk_receive(Packet* rreq_pk_ptr)
{
int rreq_destSeqNb;int rreq_dest, rreq_previous_hop, rreq_source, rreq_G, rreq_hopCount;int reverse_entry_exist;Aodv_Route_Table_Entry* entry;// reading packet op_pk_nfd_get (rreq_pk_ptr,"PreviousHop" ,&rreq_previous_hop);op_pk_nfd_get (rreq_pk_ptr,"Source" ,&rreq_source);// if the previous node (the last which broadcast// the RREQ) is not the original source of the packet, // than update local connectivityif(rreq_previous_hop != rreq_source && CONN_SUPPORT_TYPE == NONE) { aodv_maintain_local_conn(rreq_previous_hop); }// if req is not fresh enough (already seen), automatically// discard it. Same if the the current node is the source node// of the present packet.if(aodv_is_req_fresh_enough(rreq_pk_ptr) != OPC_TRUE || rreq_source == my_node_addr)
{ // RREQ discarded if(rreq_source == my_node_addr) aodv_print_minor("Current node is the source of the present request: RREQ discarded", TRACE_LEV_1);
else aodv_print_minor("Request already seen: RREQ discarded", TRACE_LEV_1);
// Destroy packet op_pk_destroy(rreq_pk_ptr);
}else {
// Request NEVER seen OR SEEN more than BROADCAST_RECORD_TIME ago
aodv_print_minor("Request is fresh enough: RREQ processed", TRACE_LEV_1);
// update or create reverse entry aodv_print_minor("Create or update reverse entry",TRACE_LEV_2); aodv_update_or_create_reverse_entry(rreq_pk_ptr); // read RREQ fields op_pk_nfd_get (rreq_pk_ptr,"Dest" ,&rreq_dest);
op_pk_nfd_get (rreq_pk_ptr,"DestSeqNb" ,&rreq_destSeqNb);
op_pk_nfd_get (rreq_pk_ptr,"G" ,&rreq_G);
op_pk_nfd_get (rreq_pk_ptr,"HopCount" ,&rreq_hopCount);
// start processing // If current node is the final destination // it replies immediately if( rreq_dest == my_node_addr) {
// trace aodv_print_minor("Request has reached its destination: Node replies", TRACE_LEV_1);
// generate RREP from destination aodv_rrep_pk_generate_from_destination(rreq_pk_ptr); } else {
// Node is a relay.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -