📄 aodv_routing.pr.c
字号:
aodv_print_minor("Request has reached an intermediate node: Checking for entry", TRACE_LEV_1);
// if node has a fresh enough (with regards to rreq_seqNb) active entry // it replies IMMEDIATELY if(aodv_rt_lookup_fresh_enough_active_entry(my_route_table, rreq_dest, rreq_destSeqNb) == OPC_TRUE) { // node has a fresh enough route
aodv_print_minor("A fresh enough entry was found: Checking gratuitous flag", TRACE_LEV_1); aodv_prg_print_entry(rreq_dest,TRACE_LEV_1);
// if gratuitous mode requested, generate gratuitous RREP for destination if(rreq_G) { // Trace aodv_print_minor("Gratuitous mode was requested: Generating gratuitous RREP for destination node", TRACE_LEV_1);
// Check if route's lifetime is long enough if(my_route_table[rreq_dest].expi_time < (op_sim_time() + (2*rreq_hopCount+1)*NODE_TRAVERSAL_TIME)) { aodv_print_minor("ACHTUNG ! route is not valid enough (grat requested)", TRACE_LEV_1); } aodv_gratuitous_rrep_pk_generate(rreq_pk_ptr); } else { // Check if route's lifetime is long enough if(my_route_table[rreq_dest].expi_time < (op_sim_time() + (2*rreq_hopCount+1)*NODE_TRAVERSAL_TIME)) { aodv_print_minor("ACHTUNG ! route is not valid enough", TRACE_LEV_1); } } // Generate rrep for source
aodv_print_minor("Generating RREP for source node", TRACE_LEV_1);
aodv_rrep_pk_generate_from_relay(rreq_pk_ptr); }
else // node doesn't have any active entry for the requested
route
// node forwards RREQ {
// Trace aodv_print_minor("No active route was found: Forwarding RREQ to neighbors", TRACE_LEV_1);
// Forward packet aodv_rreq_pk_forward(rreq_pk_ptr); } } }
}/*************************************************/* Check whether the BroadcastID of the request /* is greater than the last seen. If so, RREQ is /* automatically processed, and the RREQ is /* recorded in the req_seen_rep. Else, node checks/* whether RREQ packet was seen less than/* RECORD_BROADCAST_TIME seconds ago. If so, RREQ/* must be discarded. Else, it is processed.**************************************************/Boolean aodv_is_req_fresh_enough(Packet* rreq_pk_ptr) { // var Boolean result = OPC_FALSE; int source, dest; double broadcastID; // Read RREQ fields op_pk_nfd_get (rreq_pk_ptr,"BroadcastID",&broadcastID);
op_pk_nfd_get (rreq_pk_ptr,"Source" ,&source);
op_pk_nfd_get (rreq_pk_ptr,"Dest" ,&dest);
if( (req_seen_rep[source][dest].broadcast_id < broadcastID) || ((req_seen_rep[source][dest].broadcast_id == broadcastID) && (op_sim_time()>= req_seen_rep[source][dest].expi_time))) { result = OPC_TRUE; // update RequestSeen repository
req_seen_rep[source][ dest].broadcast_id = broadcastID;
req_seen_rep[source][ dest].expi_time = op_sim_time()+BROADCAST_RECORD_TIME;
}
return result; }/************************************************************/* This routine decides whether to create or update a reverse/* entry following the reception of a RREQ packet./* A special treatment is reserved to RREQs which turn out to/* be hello messages (RREQ.dest = RREQ.source).*************************************************************/void aodv_update_or_create_reverse_entry(Packet* rreq_pk_ptr) { Aodv_Route_Table_Entry *entry; int rreq_src_ip_addr, rreq_dest_ip_addr, rreq_previous_hop_ip_addr; int rreq_src_seq_nb, rreq_dest_seq_nb; double reverse_route_lifetime = REV_ROUTE_LIFE; int rreq_hop_count; int create_entry = 0; int update_entry = 0; int repair_entry = 0; int generate_rerr = 0; int result = 0; char msg[64]; Boolean is_reverse_route_valid; // Read RREQ packet op_pk_nfd_get (rreq_pk_ptr,"Source" ,&rreq_src_ip_addr); op_pk_nfd_get (rreq_pk_ptr,"PreviousHop" ,&rreq_previous_hop_ip_addr);
op_pk_nfd_get (rreq_pk_ptr,"SrcSeqNb" ,&rreq_src_seq_nb);
op_pk_nfd_get (rreq_pk_ptr,"Dest" ,&rreq_dest_ip_addr); op_pk_nfd_get (rreq_pk_ptr,"HopCount" ,&rreq_hop_count);
op_pk_nfd_get (rreq_pk_ptr,"DestSeqNb" ,&rreq_dest_seq_nb); // DEBUG aodv_prg_print_entry(rreq_src_ip_addr,TRACE_LEV_2); // if RREQ.src = RREQ.dest, then node is a hello message if(rreq_src_ip_addr == rreq_dest_ip_addr) { // trace aodv_print_minor("RREQ turns out to be a Hello message",TRACE_LEV_1); // Set dest field to current node addr rreq_dest_ip_addr = my_node_addr; op_pk_nfd_set (rreq_pk_ptr,"Dest" ,my_node_addr); // Set destSeqNb feld to current node source seq nb rreq_dest_seq_nb = my_seq_nb; op_pk_nfd_set (rreq_pk_ptr,"DestSeqNb" ,rreq_dest_seq_nb); // Set reverse_route_lifetime to ALLOWED_HELLO_LOSS * HELLO_INTERVAL reverse_route_lifetime = ALLOWED_HELLO_LOSS * HELLO_INTERVAL; } // Check if route is valid is_reverse_route_valid = aodv_prg_print_path(rreq_previous_hop_ip_addr,rreq_src_ip_addr, TRACE_LEV_1,light); if(is_reverse_route_valid == OPC_FALSE) aodv_prg_print_path(rreq_previous_hop_ip_addr,rreq_src_ip_addr, TRACE_LEV_1,full); // if route is valid, then proceed if(is_reverse_route_valid == OPC_TRUE) { // Begin // Node update or create its entry for the source node // only if one of the following conditions is true: // 1. Entry does not exist // 2. Entry active + entry.dest_seq_nb > rreq.src_seq_nb // 3. entry active + entry.dest_seq_nb = rreq.src_seq_nb + entry.hop_count < rreq.hop_count +1 // 4. entry invalid + entry.dest_seq_nb >= rreq.src_seq_nb. if(!my_route_table[rreq_src_ip_addr].entry_exist) { // Trace aodv_print_minor("Entry does not exist: create it",TRACE_LEV_1); // set create_entry flag create_entry = 1; // create entry aodv_rt_create_entry(my_route_table, rreq_src_ip_addr); } else // entry exists { // Trace aodv_print_minor("Entry exists",TRACE_LEV_1); // If entry is not under repair if(!my_route_table[rreq_src_ip_addr].repair_flag) { // Trace aodv_print_minor("Entry not under repair",TRACE_LEV_1); // if entry active if(aodv_rt_lookup_active_entry(my_route_table, rreq_src_ip_addr) == OPC_TRUE) { // Trace aodv_print_minor("Entry is active",TRACE_LEV_1); aodv_prg_print_entry_x(rreq_src_ip_addr,TRACE_LEV_2); // update only if: if(my_route_table[rreq_src_ip_addr].dest_seq_nb < rreq_src_seq_nb) { // Trace aodv_print_minor("New route is fresher: update entry",TRACE_LEV_1); update_entry = 1; } else if( (my_route_table[rreq_src_ip_addr].dest_seq_nb == rreq_src_seq_nb) && (my_route_table[rreq_src_ip_addr].hop_count > (rreq_hop_count +1)) ) { // Trace aodv_print_minor("New route is shorter: update entry",TRACE_LEV_1); update_entry = 1; } } else // entry is either invalid or marked as broken { // if entry invalid (equals to "not broken") if(!my_route_table[rreq_src_ip_addr].breakage_flag) { // Trace aodv_print_minor("Entry is invalid",TRACE_LEV_1); // update only if dest seq nb is greater if(my_route_table[rreq_src_ip_addr].dest_seq_nb <= rreq_src_seq_nb)//> -1) //<= rreq_src_seq_nb { // Trace aodv_print_minor("New route is fresher: update entry",TRACE_LEV_1); update_entry = 1; } } else // entry is broken { // Trace aodv_print_minor("Entry is broken",TRACE_LEV_1); // update only if dest seq nb is greater if(my_route_table[rreq_src_ip_addr].dest_seq_nb <= rreq_src_seq_nb) { // Trace aodv_print_minor("New route is fresher: update entry",TRACE_LEV_1); // reset breakage flag my_route_table[rreq_src_ip_addr].breakage_flag = 0; // Update entry update_entry = 1; } } } } else // entry is under repair { // Trace aodv_print_minor("Entry is under repair",TRACE_LEV_1); // Repair only if rrep_dest_seq_nb >= entry->dest_seq_nb if(my_route_table[rreq_src_ip_addr].dest_seq_nb <= rreq_src_seq_nb) { // Trace aodv_print_minor("New route is fresher: repair entry",TRACE_LEV_1); repair_entry = 1; // Check if new hop count is different from the former // In such case, generate RERR with N flag set if(my_route_table[rreq_src_ip_addr].last_hop_count != (rreq_hop_count+1)) { generate_rerr = 1; } } } } } else { // Trace aodv_print_minor("New route is not valid: let flow",TRACE_LEV_1); loops++; } // If the flag "update_entry" or "create_entry" // was set, than proceed as follows. if(create_entry || update_entry || repair_entry) { // set result to TRUE result = 1; // read entry //entry = aodv_rt_access_entry(my_route_table, rreq_src_ip_addr); // entry should not be null if(!my_route_table[rreq_src_ip_addr].entry_exist) { // Entry is nil: stop the simulation and print an error message op_sim_end("Error @ receive rreq: trying to update an entry that does not exist","","",""); } else { // schedule interruption when timeout // this is slightly different in the // case of a new entry. if(create_entry) { // Schedule a new intrpt aodv_rt_entry_schedule_intrpt(my_route_table, rreq_src_ip_addr, op_sim_time() + reverse_route_lifetime); // Trace sprintf(msg,"Reverse route was created: Source node is %d",rreq_src_ip_addr); aodv_print_minor(msg, TRACE_LEV_1); } else if(update_entry) { // Reschedule intrpt aodv_rt_entry_extend_intrpt(my_route_table, rreq_src_ip_addr, op_sim_time() + reverse_route_lifetime); // N.B: function extend updates the expiration time of an entry, only // if the new value is greater thant the current one. // Trace sprintf(msg,"Reverse route was updated: Source node is %d",rreq_src_ip_addr); aodv_print_minor(msg, TRACE_LEV_1); } else if(repair_entry) { // Reset entry flags my_route_table[rreq_src_ip_addr].breakage_flag = 0; my_route_table[rreq_src_ip_addr].repair_flag = 0; // Reschedule intrpt aodv_rt_entry_extend_intrpt(my_route_table, rreq_src_ip_addr, op_sim_time() + reverse_route_lifetime); // Trace sprintf(msg,"Reverse route was repaired: Source node is %d",rreq_src_ip_addr); aodv_print_minor(msg, TRACE_LEV_1); } // Update or create entry my_route_table[rreq_src_ip_addr].next_hop = rreq_previous_hop_ip_addr; my_route_table[rreq_src_ip_addr].hop_count = rreq_hop_count +1; my_route_table[rreq_src_ip_addr].dest_seq_nb = rreq_src_seq_nb; // Add -1 to the precursor list aodv_prg_add_prec(BROADCAST, rreq_src_ip_addr); } } else if(my_route_table[rreq_src_ip_addr].entry_exist) { // Although entry was not updated, we still // have to extend its lifetime // Reschedule intrpt aodv_rt_entry_extend_intrpt(my_route_table, rreq_src_ip_addr, op_sim_time() + reverse_route_lifetime); // Set flag update_entry = 1; // Trace sprintf(msg,"Reverse route lifetime was extended: Source node is %d",rreq_src_ip_addr); aodv_print_minor(msg, TRACE_LEV_1); } // Print entry aodv_prg_print_entry(rreq_src_ip_addr, TRACE_LEV_2); // In case, the entry's been repaired with a different hop count // node should generate a non delete RERR packet if(generate_rerr) { // trace aodv_print_minor("New hop count is different: Generate a non delete RERR", TRACE_LEV_1); // Generate non delete RERR pk aodv_generate_non_delete_rerr_pk(rreq_src_ip_addr); } // Serve buffer in case a route has been created, updated, or repaired if(create_entry || update_entry || repair_entry) { if(req_sent_rep[rreq_src_ip_addr].pending) { aodv_print_minor("A request was pending: cancel it, then serve buffer", TRACE_LEV_1); // cancel pending request aodv_cancel_pending_request(rreq_src_ip_addr); // Print path aodv_prg_print_path(my_node_addr,rreq_src_ip_addr, TRACE_LEV_2,light); // Serve buffer //aodv_buffer_serve(rreq_src_ip_addr); } } // serve buffer (debug) aodv_buffer_serve(rreq_src_ip_addr); // Return result //return result; }/**********************************************************/* This function is called when a RREQ has reached its /* destination and node wants to reply./* Once the RREQ packet is g
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -