📄 dsr_routing_layer.pr.c
字号:
/* If the route_found returns 0 it could have been the case that the cached route included 1 or
more of the nodes found in the request packet path...if this was the case then the final route
that would be provided would have had a loop in it. Thus the call to dsr_transmit_reply_from_relay
eliminates those routes from its cache and returns a zero.
Thus another check should be done to see if there is another route that was not deleted from the cache
*/
if ((route_found == 0) && (route_cache[destination_dsr_address].node_route[0].size_route > 0) &&
((route_cache[destination_dsr_address].node_route[0].size_route + size_route) < MAX_SIZE_ROUTE))
{
// a reply (from relay) packet must be built and sent
route_found = dsr_transmit_reply_from_relay(pk_ptr);
}
}
// otherwise if the request is not too hold (life time and number of hops) and
// a route is not found in the cache, then forward the request on
if ((route_found == 0) && (creation_time+MAX_REQUEST_PERIOD>op_sim_time()) && (seg_left>0))
{
// the packet must be forwarded
dsr_forward_request(pk_ptr);
}
// otherwise
else if (route_found == 0)
{
// the packet must be destroyed
dsr_message("Route not found and the request is too old or non-propagating, thus I am destroying the packet\n");
op_pk_destroy(pk_ptr);
}
}
}
// otherwise if the packet has been already seen it must not be processed in order to avoid loops or multiple similar replies
else
{
// thus it is destroyed
op_pk_destroy(pk_ptr);
}
// breakpoint for debugging purpose
if (1)
{
op_prg_odb_bkpt("handle_request");
}
}
/*************************************************************/
/* DSR_REQUEST_ALREADY_SEEN */
/*************************************************************/
/* This function checks if the request identified by its source,
/* its destination and its sequence_number has been already seen
/* and consequently handled
/*
/* int source_dsr_address: the dsr address of the request source
/* int destination_dsr_address: the dsr address of the request destination
/* int sequence_number: the sequence number of the request
/* RETURN: 1 if the request packet has been already seen
/* 0 otherwise
/*************************************************************/
int dsr_request_already_seen(int source_dsr_address,int destination_dsr_address,int sequence_number)
{
// the request has been already seen since its sequence number is lower or equal than the one stored in memory
if (request_seen[source_dsr_address][destination_dsr_address]>=sequence_number)
{
dsr_message("I have already seen this request\n");
return(1);
}
else
{
// store the fact that the request has been already seen for the future by storing its sequence number
request_seen[source_dsr_address][destination_dsr_address]=sequence_number;
dsr_message("It is the first time that I am seeing this request\n");
return (0);
}
}
/*************************************************************/
/* DSR_FORWARD_REQUEST */
/*************************************************************/
/* This function forward the request received by the node
/*
/* Packet* pk_ptr: a pointer to the request packet to forward
/*************************************************************/
void dsr_forward_request(Packet* pk_ptr)
{
int size_route;
int seg_left;
char field[10];
int destination_dsr_address;
// get the size of the route from the request packet
op_pk_nfd_get (pk_ptr,"Opt_Data_Len",&size_route);
op_pk_nfd_get (pk_ptr,"IP_TTL",&seg_left);
// the current node adds its own dsr address in the request path
sprintf(field,"Node_%d",size_route);
op_pk_nfd_set (pk_ptr,field,my_dsr_address);
// decrement by one the Seg_left field of the packet
op_pk_nfd_set(pk_ptr,"IP_TTL",--seg_left);
// increment by one the Size_Route
op_pk_nfd_set(pk_ptr,"Opt_Data_Len",++size_route);
// write the node_objid in the packet for the transmission range purpose
op_pk_nfd_set(pk_ptr,"TR_source",my_node_objid);
op_pk_nfd_get(pk_ptr,"Node_0",&destination_dsr_address);
sprintf(message,"I forward the request destined for %d\n",destination_dsr_address);
dsr_message(message);
// update statistics
++total_forward_request;
++node_forward_request;
op_stat_write(stat_node_forward_request,node_forward_request);
op_stat_write(stat_total_forward_request,total_forward_request);
// send the request to the MAC layer which will BROADCAST it
dsr_send_to_mac(pk_ptr,BROADCAST);
// breakpoint for debugging purpose
if (1)
{
op_prg_odb_bkpt("forward request");
}
}
/*************************************************************/
/* DSR_TRANSMIT_REPLY_FROM_TARGET */
/*************************************************************/
/* This function build and transmit a reply packet from target
/* (the node is the destination of the received request)
/*
/* Packet* pk_ptr: a pointer to the request packet to reply
/*************************************************************/
void dsr_transmit_reply_from_target(Packet* pk_ptr)
{
Packet* reply_pk_ptr;
int request_source_dsr_address;
int node_dsr_address;
int relay_dsr_address;
int relay_mac_address;
char field[10];
int seg_left,size_route;
int sequence_number;
int i;
// create the reply packet and set its Type field
reply_pk_ptr = op_pk_create_fmt("dsr_reply");
op_pk_nfd_set(pk_ptr,"Option_Type",REPLY_PACKET_TYPE);
// since I am the request target I am also the reply source
op_pk_nfd_set(reply_pk_ptr,"SRC",my_dsr_address);
// set the reply DEST field => the request source is the reply destination
op_pk_nfd_get(pk_ptr,"SRC",&request_source_dsr_address);
op_pk_nfd_set(reply_pk_ptr,"DEST",request_source_dsr_address);
// set the field in the packet indicating that it is a reply from target
op_pk_nfd_set(reply_pk_ptr,"Reply_From_Target",1);
// set the reply Identification field => same sequence number than the request
op_pk_nfd_get(pk_ptr,"Identification",&sequence_number);
op_pk_nfd_set(reply_pk_ptr,"Identification",sequence_number);
op_pk_nfd_get(pk_ptr,"Opt_Data_Len",&size_route);
// add the source node to the size_route
size_route = size_route + 1;
// Print the source route to the screen
if (DEBUG != 0)
{
printf("Reply from Target route: ");
printf("%d...",request_source_dsr_address);
}
// Copy the fields "Node_i" from the request to the reply in the same order
for (i=0; i<size_route-2; i++) {
sprintf(field,"Node_%d",i+1);
op_pk_nfd_get(pk_ptr,field,&node_dsr_address);
sprintf(field,"Node_%d",i);
op_pk_nfd_set(reply_pk_ptr,field,node_dsr_address);
if (DEBUG != 0)
{
printf("%d...",node_dsr_address);
}
}
// Set the target address (my_dsr_address) to the last address of the source route in reply
sprintf(field,"Node_%d",size_route-2);
op_pk_nfd_set(reply_pk_ptr,field,my_dsr_address);
if (DEBUG != 0)
{
printf("%d...end\n",my_dsr_address);
}
// Assign the first relay on the reply packet's route (-2 for the index of the last node of the route and another -1 for the previous one)
if (size_route > 2)
{
sprintf(field,"Node_%d",size_route-3);
op_pk_nfd_get(reply_pk_ptr,field,&relay_dsr_address);
}
else
{
op_pk_nfd_get(reply_pk_ptr,"DEST",&relay_dsr_address);
}
// update the seg_left and size route fields (-1 = number of hops in the route, another -1 = segment left)
seg_left=size_route-2;
op_pk_nfd_set(reply_pk_ptr,"IP_TTL",seg_left);
// Set Opt_Data_Len to size_route minus source node
op_pk_nfd_set(reply_pk_ptr,"Opt_Data_Len",size_route-1);
// set the TR_source fields for the Transmission range purpose
op_pk_nfd_set(reply_pk_ptr,"TR_source",my_node_objid);
// since I am the reply transmitter I will not have to process it in the future
dsr_reply_already_seen(request_source_dsr_address,my_dsr_address,sequence_number);
// convert the dsr address of the first relay in its mac address
relay_mac_address = dsr_support_get_mac_from_dsr_address(relay_dsr_address);
// and send the reply packet instantanetly since I am the target of the request
dsr_send_to_mac(reply_pk_ptr,relay_mac_address);
//dsr_send_to_mac(reply_pk_ptr,relay_dsr_address);
sprintf(message,"I am sending a reply from target for %d to %d with sequence_number %d\n",request_source_dsr_address,relay_dsr_address,sequence_number);
dsr_message(message);
// update replies statistics
++total_replies_from_target;
++total_replies;
op_stat_write(stat_total_replies_from_target,total_replies_from_target);
op_stat_write(stat_total_replies,total_replies);
// and destroy the request packet
op_pk_destroy(pk_ptr);
// breakpoints for debugging purpose
if (1)
{
op_prg_odb_bkpt("transmit_reply");
op_prg_odb_bkpt("transmit_reply_from_target");
}
}
/*************************************************************/
/* DSR_TRANSMIT_REPLY_FROM_RELAY */
/*************************************************************/
/* This function builds and transmits a reply packet from relay
/* (the node is not the destination of the received request, but
/* can reply by using its route cache)
/*
/* Packet* pk_ptr: a pointer to the request packet to reply
/*************************************************************/
int dsr_transmit_reply_from_relay(Packet *pk_ptr)
{
Packet* reply_pk_ptr;
int request_source_dsr_address;
int request_destination_dsr_address;
int relay_dsr_address;
int node_dsr_address;
char field[10];
int seg_left;
int size_route;
int sequence_number;
sNodeRoute reply_route;
Distribution* delay_reply_dist;
double delay;
sReply* reply;
int* intPtr;
int i,j;
int node_found;
int route_found;
// read the Size_Route and request destination address from the request packet
op_pk_nfd_get(pk_ptr,"Opt_Data_Len",&size_route);
op_pk_nfd_get(pk_ptr,"Node_0",&request_destination_dsr_address);
// Check if the pasted route's length will be still < MAX_SIZE_ROUTE length
if ((size_route+route_cache[request_destination_dsr_address].node_route[0].size_route)<MAX_SIZE_ROUTE)
{
// create the reply packet and set its Type field
reply_pk_ptr = op_pk_create_fmt("dsr_reply");
op_pk_nfd_set(reply_pk_ptr,"Option_Type",REPLY_PACKET_TYPE);
// assign the Source and Dest field to the reply packet
op_pk_nfd_set(reply_pk_ptr,"SRC",my_dsr_address);
op_pk_nfd_get(pk_ptr,"SRC",&request_source_dsr_address);
op_pk_nfd_set(reply_pk_ptr,"DEST",request_source_dsr_address);
// set the field in the packet indicating that it is a reply from relay
op_pk_nfd_set(reply_pk_ptr,"Reply_From_Target",0);
// set the reply Identification field => same sequence number than the request
op_pk_nfd_get(pk_ptr,"Identification",&sequence_number);
op_pk_nfd_set(reply_pk_ptr,"Identification",sequence_number);
// copy the first part of the route coming from the request in the reply_route
reply_route.route[0]=request_source_dsr_address;
for (i=1; i<size_route; i++)
{
sprintf(field,"Node_%d",i);
op_pk_nfd_get(pk_ptr,field,&node_dsr_address);
reply_route.route[i]=node_dsr_address;
}
// copy the second part of the route coming from the route_cache in the reply_route
for (i=size_route;i<(size_route+route_cache[request_destination_dsr_address].node_route[0].size_route);i++)
{
reply_route.route[i]=route_cache[request_destination_dsr_address].node_route[0].route[i-size_route];
}
// calculate the size ot the reply_route
reply_route.size_route=size_route+route_cache[request_destination_dsr_address].node_route[0].size_route;
// clear every loop from the reply_route
dsr_no_loop_in_route(&reply_route);
// check if the node is still in the path and find its position
i=0;
do
{
i++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -