DESERT 3.5.1
Loading...
Searching...
No Matches
sun-ipr-node-pathest-answer.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2021 Regents of the SIGNET lab, University of Padova.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived from this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29
42#include "sun-ipr-node.h"
44
45extern packet_t PT_SUN_DATA;
46extern packet_t PT_SUN_PATH_EST;
47
48/* This function is invoked by a node with hop count = 1.
49 * This function creates an Path Establishment Answer packet and, using other
50 * functions it sends
51 * the packet back.
52 */
53void
54SunIPRoutingNode::answerPath(const Packet *p_old)
55{
56 if (STACK_TRACE)
57 std::cout << "> answerPath()" << std::endl;
58 // This node is a node with hop count = 1. Checks anyway for errors.
59 // The packet p_old is removed by the method that invokes this one.
60 if (this->getNumberOfHopToSink() == 1) {
61 Packet *p_answer = Packet::alloc();
62 this->initPktPathEstAnswer(p_answer, p_old);
67 if (printDebug_ > 5) {
68 std::cout << "[" << NOW
69 << "]::Node[IP:" << this->printIP(ipAddr_)
70 << "||hops:" << this->getNumberOfHopToSink()
71 << "]::PATH_ANSWER_SENT::UID:" << ch_answer->uid()
72 << "::SRC:" << printIP(iph_old->saddr())
73 << "::HOPCOUNT:" << (hpest->list_of_hops_length() + 1)
74 << std::endl;
75 }
78 if (trace_)
79 this->tracePacket(p_answer, "SEND_PTH");
80 sendDown(p_answer, this->getDelay(period_status_));
81 return;
82 } else {
83 return;
84 }
85} /* SunIPRoutingNode::answerPath */
86
87/* This function initialize a Path Establishment Answer packet passed
88 * as first argument with the values contained in the Path Establishment Request
89 * packet passed as second argument.
90 */
91void
92SunIPRoutingNode::initPktPathEstAnswer(Packet *new_pkt, const Packet *old_pkt)
93{
94 if (STACK_TRACE)
95 std::cout << "> initPktPathEstAnswer()" << std::endl;
96 // Common header.
99 ch_new->uid() = sunuid_++;
100 ch_new->ptype() = PT_SUN_PATH_EST;
101 // ch_new->size() = 0; // Look Down.
102 ch_new->direction() = hdr_cmn::DOWN;
103 // ch_new->next_hop() = 0; // Look Down.
104 ch_new->prev_hop_ = ipAddr_;
105
106 // IP Header
109 iph_new->saddr() = ipAddr_; // The relay with hop count 1 will set as source
110 // it's own IP.
111 // iph_new->sport() = 0; // Set by the Application above.
112 iph_new->daddr() = iph_old->saddr(); // The daddr is the IP of the node that
113 // sent the path request.
114 // iph_new->dport() = 0; // Set by the Application above.
115 // iph_new->ttl() = 0; // Set by IPModule.
116
117 // Path establishment header.
120 hpest_new->sinkAssociated() = sink_associated;
121 hpest_new->ptype() = PATH_ANSWER;
122 hpest_new->list_of_hops_length() = hpest_old->list_of_hops_length();
123 hpest_new->pointer() = hpest_new->list_of_hops_length() -
124 2; // -1 because the length starts from 1, -1 because the next hop
125 // is the previous node in the list
126 // cout << "pointer: " << (int) hpest_new->pointer() << endl;
127 // cout << ">-----------begin initPathAnswer--------------<" << endl;
128 // cout << "my hop count must be 1 and it is: " <<
129 // this->getNumberOfHopToSink() << endl;
130 // cout << "Node IP: " << printIP(ipAddr_) << endl;
131 // cout << "Requesting node: " << printIP(iph_old->saddr()) << endl;
132 // cout << "Previous node: " << printIP(ch_old->prev_hop_) << endl;
133 for (int i = 0; i < hpest_new->list_of_hops_length(); i++) {
134 hpest_new->list_of_hops()[i] = hpest_old->list_of_hops()[i];
135 // cout << "hop[" << i << "]: " <<
136 // printIP(hpest_new->list_of_hops()[i]) << endl;
137 }
138 // cout << ">------------end initPathAnswer---------------<" << endl;
139 hpest_new->quality() = hpest_old->quality();
140
141 ch_new->size() += sizeof(hdr_sun_path_est);
142 // cout << "list of hops length: " << (int)
143 // hpest_old->list_of_hops_length() << endl;
144 // cout << "pointer: " << (int) hpest_new->pointer() << endl;
145 if (hpest_new->pointer() < 0) {
146 ch_new->next_hop() = ch_old->prev_hop_; // iph_old->saddr();
147 } else {
148 ch_new->next_hop() = hpest_new->list_of_hops()[hpest_new->pointer()];
149 }
150 // cout << "next hop: " << printIP(ch_new->next_hop()) << endl;
151 ch_new->timestamp() = Scheduler::instance().clock();
152} /* SunIPRoutingNode::initPktPathEstAnswer */
153
154/* This function receives a Path Establishment Answer Packet and checks
155 * if the IP of the current node is in the list.
156 * If no it drops the packet, otherwise it sends to the previous node the
157 * packet,
158 * and adds the information about the route in its the routing table.
159 * Returns 0 if it drops the packet, 1 if it sends back the packet.
160 */
161void
163{
164 if (STACK_TRACE)
165 std::cout << "> sendRouteBack()" << std::endl;
166 hdr_cmn *ch = HDR_CMN(p);
167 hdr_uwip *iph = HDR_UWIP(p);
169
170 if (hpest->ptype() ==
171 PATH_ANSWER) { // This function processes only PATH_ANSWER packets
172 if (hpest->list_of_hops_length() == 0) {
174 return;
175 } else {
176 short j_ = hpest->pointer();
177 if (hpest->list_of_hops()[j_] ==
178 ipAddr_) { // The current node is the right next hop.
179 // Update the hop table of the current node only if the node
180 // receives a new best path or it doesn't have any path.
181 /* The number of hops from the node to the sink are:
182 * list_of_hops_length - 1 + pointer + 1 = list_of_hops_length -
183 * pointer
184 */
185 if (metrics_ == HOPCOUNT) {
186 if (((hpest->list_of_hops_length() - hpest->pointer()) <=
187 this->getNumberOfHopToSink()) ||
188 (this->getNumberOfHopToSink() ==
189 0)) { // Attention: the pointer is a
190 // decreasing value.
191 // Reset of the routing information.
192 this->clearHops();
193 this->setNumberOfHopToSink(0);
194 // Update the routing table of the current node.
195 for (int i = j_ + 1, w = 0; i < hpest->list_of_hops_length(); i++, w++) {
196 hop_table[w] = hpest->list_of_hops()[i];
197 }
198 hop_table_length = hpest->list_of_hops_length() - hpest->pointer() - 1;
203 ack_error_state = false;
204
205 // Keep track of the nodes that responded to a PATH_SEARCH request
207 if (paths_selected.find(endnode) == paths_selected.end())
209 else
211 }
212 } else if (metrics_ == SNR) {
213 double tmp_ = hpest->quality();
214 if (this->isZero(quality_link) || (quality_link < tmp_) ||
215 (this->getNumberOfHopToSink() == 0)) {
216 // Reset of the routing information.
217 this->clearHops();
218 this->setNumberOfHopToSink(0);
219 // Update the routing table of the current node.
220 for (int i = j_ + 1, w = 0; i < hpest->list_of_hops_length(); i++, w++) {
221 hop_table[w] = hpest->list_of_hops()[i];
222 }
223 hop_table_length = hpest->list_of_hops_length() - hpest->pointer() - 1;
229 ack_error_state = false;
230
231 // Keep track of the nodes that responded to a PATH_SEARCH request
233 if (paths_selected.find(endnode) == paths_selected.end())
235 else
237 }
238 } else if (metrics_ == LESSCONGESTED) {
239 double tmp_ =
240 hpest->quality() / hpest->list_of_hops_length();
241 if ((!this->isZero(quality_link) &&
242 (quality_link > tmp_)) ||
243 (this->getNumberOfHopToSink() == 0)) {
244 // Reset of the routing information.
245 this->clearHops();
246 this->setNumberOfHopToSink(0);
247 // Update the routing table of the current node.
248 for (int i = j_ + 1, w = 0;
249 i < hpest->list_of_hops_length();
250 i++, w++) {
251 hop_table[w] = hpest->list_of_hops()[i];
252 }
253 hop_table_length = hpest->list_of_hops_length() -
254 hpest->pointer() - 1;
260 ack_error_state = false;
261 }
262 }
263 // Update the information in the Path Establishment Answer
264 // packet.
265 hpest->pointer()--;
266 if (hpest->pointer() < 0) { // The list is over, the next hop
267 // will be the destination.
268 ch->next_hop() = iph->daddr();
269 ch->prev_hop_ = ipAddr_;
270 } else { // Look in the hop list for the next hop.
271 ch->next_hop() = hpest->list_of_hops()[hpest->pointer()];
272 ch->prev_hop_ = ipAddr_;
273 }
274 if (printDebug_ > 5) {
275 std::cout << "[" << NOW
276 << "]::Node[IP:" << this->printIP(ipAddr_)
277 << "||hops:" << this->getNumberOfHopToSink()
278 << "]::UID:" << ch->uid()
279 << "::SEND_ROUTE_BACK::NEXT_HOP:" << printIP(ch->next_hop())
280 << "::DESTINATION:" << printIP(iph->saddr())
281 << std::endl;
282 }
284 if (trace_)
285 this->tracePacket(p, "FRWD_PTH");
286 sendDown(p, this->getDelay(period_status_));
287 return;
288 } else {
290 return;
291 }
292 }
293 } else {
294 Packet::free(p);
295 return;
296 }
297} /* SunIPRoutingNode::sendRouteBack */
298
299/* This function is invoked by the node that requested a Search Path.
300 * The function accepts in input a packet path establishment with a full queue
301 * of paths. Compare it with the previous saved, if it exists, and decide which
302 * is the better one.
303 * It returns the current value of num_hop_to_sink.
304 */
305const int &
307{
308 if (STACK_TRACE)
309 std::cout << "> evaluatePath()" << std::endl;
310 hdr_cmn *ch = HDR_CMN(p);
311 hdr_uwip *iph = HDR_UWIP(p);
313
314 if (metrics_ == HOPCOUNT) {
315 int tmp_metric_ = hpest->list_of_hops_length();
316 if (tmp_metric_ > 0) { // There is at least one hop in the path.
317 if (((this->getNumberOfHopToSink() == 0) ||
318 (this->getNumberOfHopToSink() > tmp_metric_ + 1)) &&
319 this->getNumberOfHopToSink() !=
320 1) { // New best route. +1 because of the final hop.
321 this->clearHops();
322 this->setNumberOfHopToSink(0);
323 // cout << "----> " << printIP(ipAddr_) << endl;
324 for (int i = 0; i < hpest->list_of_hops_length(); i++) {
325 hop_table[i] = hpest->list_of_hops()[i];
326 // cout << "hop_table[i].ip_ = " <<
327 // printIP(hop_table[i]) << endl;
328 }
330 sink_associated = hpest->sinkAssociated();
331 hop_table_length = hpest->list_of_hops_length();
333 1); // The value to reach the node connected to the sink
334 // + 1 (node-node with hc 1-sink)
335
336 if (printDebug_ > 5) {
337 std::cout << "[" << NOW
338 << "]::Node[IP:" << this->printIP(ipAddr_)
339 << "||hops:" << this->getNumberOfHopToSink()
340 << "]::UID:" << ch->uid()
341 << "::ROUTE_ESTABLISHED::HOPS:" << getNumberOfHopToSink()
342 << "::LAST_HOP:" << printIP(iph->saddr()) << "::";
343 for (int s = 0; s < hpest->list_of_hops_length(); s++)
344 std::cout << ":" << (int)hpest->list_of_hops()[s];
345 std::cout << std::endl;
346 }
347
348 // Keep track of the nodes that responded to a PATH_SEARCH request
349 uint endnode = iph->saddr();
350 if (paths_selected.find(endnode) == paths_selected.end())
352 else
354
357 ack_error_state = false;
358 }
359 return this->getNumberOfHopToSink();
360 } else {
361 return this->getNumberOfHopToSink();
362 }
363 } else if (metrics_ == SNR) {
364 double tmp_metric_ = hpest->quality();
365 if (hpest->list_of_hops_length() >
366 0) { // There is at least one hop in the path.
367 if (this->isZero(quality_link) || (quality_link < tmp_metric_) ||
368 (this->getNumberOfHopToSink() == 0)) {
369 this->clearHops();
370 this->setNumberOfHopToSink(0);
371 for (int i = 0; i < hpest->list_of_hops_length(); i++) {
372 hop_table[i] = hpest->list_of_hops()[i];
373 // cout << "hop[" << i << "]: " <<
374 // printIP(hop_table[i].ip_) << endl;
375 }
377 sink_associated = hpest->sinkAssociated();
378 hop_table_length = hpest->list_of_hops_length();
380 1); // The value to reach the node connected to the sink
381 // + 1 (node-node with hc 1-sink)
382 if (printDebug_ > 5) {
383 std::cout << "[" << NOW
384 << "]::Node[IP:" << this->printIP(ipAddr_)
385 << "||hops:" << this->getNumberOfHopToSink()
386 << "]::UID:" << ch->uid()
387 << "::ROUTE_ESTABLISHED::HOPS:" << getNumberOfHopToSink()
388 << "::LAST_HOP:" << printIP(iph->saddr())
389 << "::SNR:" << quality_link << "dB::";
390 for (int s = 0; s < hpest->list_of_hops_length(); s++)
391 std::cout << ":" << (int)hpest->list_of_hops()[s];
392 std::cout << std::endl;
393 }
394
395 // Keep track of the nodes that responded to a PATH_SEARCH request
396 uint endnode = iph->saddr();
397 if (paths_selected.find(endnode) == paths_selected.end())
399 else
401
404 ack_error_state = false;
405 }
406 return this->getNumberOfHopToSink();
407 } else {
408 return this->getNumberOfHopToSink();
409 }
410 } else if (metrics_ == LESSCONGESTED) {
411 double tmp_metric_ = hpest->quality() / hpest->list_of_hops_length();
412 if (hpest->list_of_hops_length() >
413 0) { // There is at least one hop in the path.
414 if (this->isZero(quality_link) || (quality_link > tmp_metric_) ||
415 (this->getNumberOfHopToSink() == 0)) {
416 this->clearHops();
417 this->setNumberOfHopToSink(0);
418 for (int i = 0; i < hpest->list_of_hops_length(); i++) {
419 hop_table[i] = hpest->list_of_hops()[i];
420 // cout << "hop[" << i << "]: " <<
421 // printIP(hop_table[i].ip_) << endl;
422 }
424 sink_associated = hpest->sinkAssociated();
425 hop_table_length = hpest->list_of_hops_length();
427 1); // The value to reach the node connected to the sink
428 // + 1 (node-node with hc 1-sink)
429
430 if (printDebug_ > 5) {
431 std::cout << "[" << NOW
432 << "]::Node[IP:" << this->printIP(ipAddr_)
433 << "||hops:" << this->getNumberOfHopToSink()
434 << "]::SN:" << ch->uid()
435 << "::NEW_BEST_ROUTE::HOPCOUNT" << this->getNumberOfHopToSink()
436 << "::LOAD:" << quality_link
437 << "::FINAL_HOP:" << printIP(iph->saddr())
438 << std::endl;
439 }
442 ack_error_state = false;
443 }
444 return this->getNumberOfHopToSink();
445 } else {
446 return this->getNumberOfHopToSink();
447 }
448 } else {
449 exit(1);
450 }
451} /* SunIPRoutingNode::evaluatePath */
static string printIP(const nsaddr_t &)
Returns a string with an IP in the classic form "x.x.x.x" converting an ns2 nsaddr_t address.
double timer_route_validity_
Maximum validity time for a route entry.
ostringstream osstream_
Used to convert to string.
virtual void clearHops()
Clears all the route information of the current node.
nsaddr_t * hop_table
List of IPs to reach the sink.
long n_paths_established
Number of times the node is established as realy node by the other nodes of the network.
std::map< uint8_t, uint > paths_selected
Map containing the nodes selected as relay to the sink and the number of times each node was selected...
bool trace_
Flag used to enable or disable the trace file for nodes,.
virtual const int & getNumberOfHopToSink() const
Returns the number of hops that separate the node to the sink.
virtual const int & evaluatePath(const Packet *)
Evaluates the route information contained in a Path Establishment packet, and according to different ...
int hop_table_length
Current length of the hop_table.
virtual void sendRouteBack(Packet *)
Forwards a Path Establishment Answer Packet.
static long number_of_pathestablishment_
Comulative number of Path Establishment packets processed by SunIPRoutingNode objects.
double period_status_
Period of the Poisson traffic for status and ack packets.
nsaddr_t sink_associated
IP of the sink associated to the node.
virtual const int & setNumberOfHopToSink(const int &)
Sets the number of hops that the current node needs to reach the sink.
bool ack_error_state
true if the node is not in an error state (that means that it discovered a broken link),...
const double getDelay(const double &period_) const
Returns a delay value to use in transmission.
double quality_link
Quality of the link from the node to the sink.
int ack_warnings_counter_
Number of acks lost since the last reset.
int printDebug_
Flag to enable or disable dirrefent levels of debug.
virtual void tracePacket(const Packet *const, const string &position="UNDEF___")
Traces a packet.
nsaddr_t ipAddr_
IP of the current node.
int metrics_
Metric used by the current node.
RemoveHopTableTimer rmhopTableTmr_
RemoveHopTableTimer object.
virtual void initPktPathEstAnswer(Packet *, const Packet *)
Initializes a Path Establishment Answer packet (previously allocated) retrieving the information from...
virtual void answerPath(const Packet *)
Creates and sends an Path Establishment Answer packet.
const bool isZero(const double &value) const
Evaluates is the number passed as input is equal to zero.
hdr_sun_path_est describes path establishment packets used by UWSUN
uint8_t & sinkAssociated()
Reference to the sink_associated_ variable.
float & quality()
Reference to the quality_ variable.
u_int8_t & list_of_hops_length()
Reference to the list_of_hops_length_ variable.
hdr_uwip describes UWIP packets.
Definition uwip-module.h:70
uint8_t & saddr()
Reference to the saddr_ variable.
Definition uwip-module.h:95
#define PATH_ANSWER
#define HDR_SUN_PATH_EST(p)
Common structures and definition used by SUN.
#define STACK_TRACE
Used to keep track of methods call.
static int sunuid_
Unique identifier for UWSUN packets.
#define DROP_PATH_ESTABLISHMENT_ANSWER_PACKET_GARBAGE
Reason for a drop in a UWSUN module.
Dinamic source routing protocol, this file contains Nodes specifications.
#define HDR_UWIP(P)
Definition uwip-module.h:58