📄 aodv_routing.pr.c
字号:
RequestSent[destination].nbOfRetries++; } }
/////////////////////////////////////////////////////////////////
/*********************** HANDLE REQUEST ************************//////////////////////////////////////////////////////////////////
void aodv_rreq_pk_receive(Packet* rreq_pk_ptr)
{
int dest, destSeqNb, source,G;/*/* Process the received RREQ. This procedure decides /* whether node should generate a RREP packet for the /* requested destination or simply forward it to the /* neighbouring nodes./* Note that RREQ is automatically discarded if seen /* less than BROADCAST_RECORD_TIME seconds ago*/if(DEBUG > 1) printf(" - Function aodv_rreq_pk_receive()\n");
// reading packet op_pk_nfd_get (rreq_pk_ptr,"DEST",&dest);
op_pk_nfd_get (rreq_pk_ptr,"SRC",&source);op_pk_nfd_get (rreq_pk_ptr,"DestSeqNb",&destSeqNb);
op_pk_nfd_get (rreq_pk_ptr,"G",&G);
// check if RREQ has already been seen
if(aodv_rreq_pk_is_fresh_enough(rreq_pk_ptr) == OPC_TRUE)
{ //request NEVER seen OR SEEN more than BROADCAST_RECORD_TIME ago
if(DEBUG > 1 ) printf(" > RREQ is fresh enough: request handled \n");
// update or create reverse entry aodv_entry_update_or_create_from_rreq(rreq_pk_ptr); // handle request
if(node_addr == dest) // the current node is the destination
{
if(DEBUG > 1 ) printf(" > RREQ has reached its destination: node replies\n");
aodv_rrep_pk_generate_from_destination(rreq_pk_ptr); } else // the node is an intermediate node
{
if(DEBUG > 1 ) printf(" > Node is a relay\n");
if(aodv_fresh_enough_entry_is_available(dest,destSeqNb)== OPC_TRUE) { if(DEBUG > 1) aodv_entry_print(dest); // node has a fresh enough route
if(DEBUG > 1 ) printf(" > Node has active fresh enough entry: node replies\n");
// if gratuitous mode requested, generate gratuitous RREP for destination if(G) { if(DEBUG > 1 ) printf(" > Gratuitous reply requested: generate reply for destination\n"); aodv_gratuitous_rrep_pk_generate(rreq_pk_ptr); } // generate rrep for source
if(DEBUG > 1 ) printf(" > Generate reply for the source node\n");
aodv_rrep_pk_generate_from_relay(rreq_pk_ptr); }
else // node doesn't have any active entry for the requested
route
{
if(DEBUG > 1 ) printf(" > No active entry for requested route: RREQ should be forwarded\n"); aodv_rreq_pk_forward(rreq_pk_ptr); } } // print reverse entry if any if(DEBUG > 1) printf(" > Print reverse entry if any available\n"); if(DEBUG > 1) aodv_entry_print(source); // print forward entry if any if(DEBUG > 1) printf(" > Print forward entry if any available\n"); if(DEBUG > 1) aodv_entry_print(dest);
}else //request seen less than BROADCAST_RECORD_TIME ago
{
// RREQ discarded
if(DEBUG > 1 ) printf(" > Request seen less than BRODCAST_RECORD_TIME ago: RREQ discarded\n");
op_pk_destroy(rreq_pk_ptr);
}
if(DEBUG > 1 ) printf(" - Function aodv_rreq_pk_receive() done\n");
}//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// void aodv_rrep_pk_generate_from_destination(Packet* rreq_pk_ptr) ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//void aodv_rrep_pk_generate_from_destination(Packet* rreq_pk_ptr) { Packet* rrep_pk_ptr; int previousHop, source, dest, destSeqNb; /* /* This function is called when a RREQ has reached its /* destination and node wants to reply. /* Once the RREQ packet is generated, the procedure unicat /* it back to the node upstream (node from which RREQ was /* received) (PreviousHop field). */ // Read the received RREQ packet op_pk_nfd_get (rreq_pk_ptr,"SRC",&source);
op_pk_nfd_get (rreq_pk_ptr,"DEST",&dest); op_pk_nfd_get (rreq_pk_ptr,"PreviousHop",&previousHop); op_pk_nfd_get (rreq_pk_ptr,"DestSeqNb",&destSeqNb); // Create reply packet rrep_pk_ptr = op_pk_create_fmt("AODV_RREP"); // Assign source and dest to the reply packet op_pk_nfd_set(rrep_pk_ptr,"SRC",source);
op_pk_nfd_set(rrep_pk_ptr,"DEST",dest);
op_pk_nfd_set(rrep_pk_ptr,"HopCount",0);
op_pk_nfd_set(rrep_pk_ptr,"Lifetime",MY_ROUTE_TIMEOUT);
// Assign seq number mySeqNb = max(destSeqNb, mySeqNb);
op_pk_nfd_set(rrep_pk_ptr,"DestSeqNb",mySeqNb);
if(DEBUG > 1 ) printf(" > RREP has been generated from destination: unicast it to source node [next hop is %d]\n", previousHop);
// send reply packet aodv_pk_send_to_mac_layer(rrep_pk_ptr,previousHop);
// Refresh timeout aodv_entry_expirationTime_set(source,op_sim_time()+ACTIVE_ROUTE_TIMEOUT); // Destroy rreq op_pk_destroy(rreq_pk_ptr); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// void aodv_gratuitous_rrep_pk_generate(rreq_pk_ptr) ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//void aodv_gratuitous_rrep_pk_generate(rreq_pk_ptr) { Packet* grat_rrep_pk_ptr; RoutingTableEntry * forwardEntryPtr; int dest, source, srcSeqNb, hopCount; double lifetime; /* /* Generate a gratuitous RREP and unicast it to /* the destination node (node for which RREQ was /* originally generated). */ // Read RREQ packet op_pk_nfd_get (rreq_pk_ptr,"SRC",&source); op_pk_nfd_get (rreq_pk_ptr,"DEST",&dest);
op_pk_nfd_get (rreq_pk_ptr,"SrcSeqNb",&srcSeqNb);
op_pk_nfd_get (rreq_pk_ptr,"HopCount",&hopCount);
// read forward entry forwardEntryPtr = aodv_routingTable_entry_get(dest); // create a gratuitous rrep packet and unicast it to the next hop toward the Destination grat_rrep_pk_ptr= op_pk_create_fmt("AODV_RREP"); op_pk_nfd_set(grat_rrep_pk_ptr,"SRC",dest);
op_pk_nfd_set(grat_rrep_pk_ptr,"DEST",source);
op_pk_nfd_set(grat_rrep_pk_ptr,"DestSeqNb",srcSeqNb); op_pk_nfd_set(grat_rrep_pk_ptr,"HopCount",hopCount+1);
lifetime = forwardEntryPtr->expirationTime - op_sim_time(); if(lifetime <= 0) lifetime = ACTIVE_ROUTE_TIMEOUT; op_pk_nfd_set(grat_rrep_pk_ptr,"Lifetime",lifetime); // send to MAC Layer aodv_pk_send_to_mac_layer(grat_rrep_pk_ptr,aodv_entry_nextHop_get(dest)); // Refresh timeout aodv_entry_expirationTime_set(dest,op_sim_time()+ACTIVE_ROUTE_TIMEOUT); if (DEBUG > 1) printf(" > Gratuitous RREP has been generated: unicast it to destination [next hop is %d]\n", aodv_entry_nextHop_get(dest)); }//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// void aodv_rrep_pk_generate_from_relay(Packet* ) ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//void aodv_rrep_pk_generate_from_relay(Packet* rreq_pk_ptr) { Packet *rrep_pk_ptr; double lifetime; RoutingTableEntry *forwardEntryPtr; RoutingTableEntry *reverseEntryPtr; int dest; int source; int previousHop; /* /* This routine is called when an intermediate node /* receives a RREQ an has fresh enough route to /* to generate a RREP for the requested destination. */ // Read request packet op_pk_nfd_get (rreq_pk_ptr,"SRC",&source);
op_pk_nfd_get (rreq_pk_ptr,"DEST",&dest);
op_pk_nfd_get (rreq_pk_ptr,"PreviousHop",&previousHop); // Read forward entry forwardEntryPtr=aodv_routingTable_entry_get(dest); // Create reply packet rrep_pk_ptr = op_pk_create_fmt("AODV_RREP");
/* Assign source and dest to the reply packet */
op_pk_nfd_set(rrep_pk_ptr,"SRC",source);
op_pk_nfd_set(rrep_pk_ptr,"DEST",dest);
op_pk_nfd_set(rrep_pk_ptr,"HopCount",forwardEntryPtr->hopCount);
lifetime = forwardEntryPtr->expirationTime - op_sim_time(); if(lifetime <= 0) lifetime = ACTIVE_ROUTE_TIMEOUT; op_pk_nfd_set(rrep_pk_ptr,"Lifetime",lifetime);
op_pk_nfd_set(rrep_pk_ptr,"DestSeqNb",forwardEntryPtr->destSeqNb);
// add previousHop toward "source" to the precursor list of the forward entry aodv_listOfPrecursors_node_put(forwardEntryPtr,previousHop); // add nextHop toward "destination" to the precursor list of the reverse entry reverseEntryPtr=aodv_routingTable_entry_get(source); aodv_listOfPrecursors_node_put(reverseEntryPtr,forwardEntryPtr->nextHop);
// send reply to mac layer if(DEBUG > 1 ) printf(" > RREP has been generated from relay: unicast it to source node [next hop is %d]\n",previousHop); aodv_pk_send_to_mac_layer(rrep_pk_ptr,previousHop); // Refresh timeout aodv_entry_expirationTime_set(source,op_sim_time()+ACTIVE_ROUTE_TIMEOUT); // Destroy rreq op_pk_destroy(rreq_pk_ptr); }//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// void aodv_rreq_pk_forward(Packet* rreq_pk_ptr) ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// void aodv_rreq_pk_forward(Packet* rreq_pk_ptr) { int ttl, hopCount; /* /* Node does not have a fresh enough entry /* (or does not have an entry at all) to answer /* the received RREQ, so it decides to forward /* it. Node increments the Hop Count field /* and decrements the TTL field. /* Note that packet is sent to mac layer only if /* TTL > 0. */ op_pk_nfd_get (rreq_pk_ptr,"TTL",&ttl); op_pk_nfd_get (rreq_pk_ptr,"HopCount",&hopCount);
if(ttl > 1) { if(DEBUG > 1 ) printf(" > Node forwards request\n",ttl);
op_pk_nfd_set(rreq_pk_ptr,"TTL",ttl-1);
op_pk_nfd_set(rreq_pk_ptr,"HopCount",hopCount+1);
// send to mac aodv_pk_send_to_mac_layer(rreq_pk_ptr, BROADCAST);
} else { if(DEBUG > 1 ) printf(" > TTL expired: rreq destroyed\n"); op_pk_destroy(rreq_pk_ptr); } }//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// void aodv_entry_update_or_create_from_rreq(Packet* ) ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//void aodv_entry_update_or_create_from_rreq(Packet* rreq_pk_ptr) { RoutingTableEntry * reverseEntryPtr; int source, previousHop, srcSeqNb, hopCount; /* /* Update or create reverse entry following a RREQ reception. */ // Read RREQ packet op_pk_nfd_get (rreq_pk_ptr,"SRC",&source); op_pk_nfd_get (rreq_pk_ptr,"PreviousHop",&previousHop);
op_pk_nfd_get (rreq_pk_ptr,"SrcSeqNb",&srcSeqNb);
op_pk_nfd_get (rreq_pk_ptr,"HopCount",&hopCount);
// Check if any request is pending for this destination if(RequestSent[source].status != OFF) aodv_requestSent_repository_reset(source); // Node creates or updates a REVERSE route
reverseEntryPtr=aodv_routingTable_entry_get(source);
if(reverseEntryPtr != OPC_NIL)
{
//entry already exists if((srcSeqNb > reverseEntryPtr->destSeqNb) ||
((srcSeqNb == reverseEntryPtr->destSeqNb)
&&((hopCount+1)< reverseEntryPtr->hopCount)) || (reverseEntryPtr->status != ACTIVE) )
{ // entry updated only if (greater seqNb) or
//(same seqNbs but smaller hopCount) if(DEBUG > 1 ) printf(" > Node updates its reverse route to source node\n");
reverseEntryPtr->destSeqNb=srcSeqNb;
reverseEntryPtr->nextHop= previousHop; if(reverseEntryPtr->hopCount != INFINITY)
reverseEntryPtr->lastHopCount= reverseEntryPtr->hopCount;
reverseEntryPtr->hopCount=hopCount+1;
} else if(DEBUG > 1) printf(" > Node does not need to update its reverse entry\n");
// Refresh entry timeout to max(current expiration time, currentTime+REV_ROUTE_LIFE) if((op_sim_time()+REV_ROUTE_LIFE) > reverseEntryPtr->expirationTime) { aodv_entry_expirationTime_set(source,op_sim_time()+REV_ROUTE_LIFE); } else if(DEBUG > 1) printf(" > Reverse entry timeout does not need to be refreshened\n");
// set entry status reverseEntryPtr->status = ACTIVE; } else
{ //entry doesn't exist: node creates it if(DEBUG > 1 ) printf(" > Node creates a reverse entry to source node\n");
reverseEntryPtr=aodv_entry_create_new(); reverseEntryPtr->listOfPrecursors=newFifo();
reverseEntryPtr->status = ACTIVE; reverseEntryPtr->dest=source;
reverseEntryPtr->destSeqNb=srcSeqNb;
reverseEntryPtr->nextHop= previousHop;
reverseEntryPtr->hopCount=hopCount+1; reverseEntryPtr->lastHopCount = hopCount+1; // Add the entry to the RoutingTable aodv_routingTable_entryPtr_put(reverseEntryPtr);
// Refresh entry timeout aodv_entry_expirationTime_set(source,op_sim_time()+REV_ROUTE_LIFE); } // if reverse entry updated or created, then // Serve buffer if any packet's waiting if(reverseEntryPtr->hopCount != INFINITY) aodv_buffer_serve(source); }//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// void aodv_rreq_pk_regenerate(int destination) ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//void aodv_rreq_pk_regenerate(int destination)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -