DESERT 3.5.1
Loading...
Searching...
No Matches
sun-ipr-node-buffermanager.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
41#include "sun-ipr-node.h"
42#include "uwcbr-module.h"
43
44extern packet_t PT_SUN_ACK;
45extern packet_t PT_SUN_DATA;
46extern packet_t PT_SUN_PATH_EST;
47extern packet_t PT_SUN_PROBE;
48
49/* Timer. It is invoked automatically when the timer on a sink probe expires.
50 */
51void
53{
54 module->bufferManager();
55} /* BufferTimer::expire */
56
57void
59{
60 if (STACK_TRACE)
61 cout << "> bufferManager()" << endl;
62 double delay_tx_ = this->getDelay(period_data_);
63 if (buffer_data.size() >= 1) { // There is at least 1 pkt in the buffer.
64
65 buffer_element _tmp = buffer_data.front(); // Pointer to the first element in the buffer.
66
67 // If the first pkt is valid.
68 if (_tmp.retx_ <= max_retx_ && _tmp.num_attempts_ < max_ack_error_) {
69 Packet *p = _tmp.p_->copy();
70
71 hdr_cmn *ch = HDR_CMN(p);
72 hdr_uwip *iph = HDR_UWIP(p);
75
76 // cout << printIP(ipAddr_) << ":hc:" <<
77 // this->getNumberOfHopToSink() << ":destination:" <<
78 // printIP(iph->daddr()) << ":source:" <<
79 // printIP(iph->saddr()) << endl;
80 // cout << "--->";
81 // for (int i = 0; i < hdata->list_of_hops_length(); i++)
82 // {
83 // cout << printIP(hdata->list_of_hops()[i]) << "-";
84 // }
85 // cout << endl;
86 // cout << "---#";
87 // for (int i = 0; i < hop_table_length; i++) {
88 // cout << printIP(hop_table[i]) << "-";
89 // }
90 // cout << endl;
91
92 if (this->getNumberOfHopToSink() == 1) {
93
94 if (iph->daddr() == 0) { // The packet is not initialized.
95
96 this->initPktDataPacket(p);
97 _tmp.t_last_tx_ = Scheduler::instance().clock();
98 ch->next_hop() = sink_associated;
99 ch->prev_hop_ = ipAddr_;
100 iph->daddr() = sink_associated;
101 _tmp.p_ = p->copy();
102 Packet::free(((buffer_element) buffer_data.front()).p_);
103 buffer_data.erase(buffer_data.begin());
104 buffer_data.insert(buffer_data.begin(), _tmp);
106 data_and_hops[0]++; // The node is directly connected to the
107 // sink, the hop count is 1; In the
108 // stats this value can be less or equal
109 // to the number of packet generated by
110 // the Application of this node. This
111 // because the buffer can be full.
112 pkt_tx_++;
113 if (trace_)
114 this->tracePacket(_tmp.p_, "SEND_DTA");
115 sendDown(_tmp.p_->copy(), delay_tx_);
116 } else { // The packet was previously initialized.
117 _tmp.retx_++;
118 _tmp.t_last_tx_ = Scheduler::instance().clock();
119 ch->next_hop() = sink_associated;
120 ch->prev_hop_ = ipAddr_;
121 iph->daddr() = sink_associated;
122 _tmp.p_ = p->copy();
123 Packet::free(((buffer_element) buffer_data.front()).p_); // FF: to fix a mem leak
124 buffer_data.erase(buffer_data.begin());
125 buffer_data.insert(buffer_data.begin(), _tmp);
126 if (iph->saddr() != ipAddr_) {
128 }
130 pkt_tx_++;
131 if (trace_)
132 this->tracePacket(_tmp.p_, "SEND_DTA");
133 sendDown(_tmp.p_->copy(), delay_tx_);
134 }
135 if (printDebug_ > 5) {
136 std::cout << "[" << NOW
137 << "]::Node[IP:" << this->printIP(ipAddr_)
138 << "||hops:" << this->getNumberOfHopToSink()
139 << "]::PACKET_SENT::RETX:" << _tmp.retx_
140 << "::UID:" << ch->uid()
141 << "::SN:" << uwcbrh->sn()
142 << "::SRC:" << printIP(iph->saddr())
143 << "::PATH:";
144 for (int i = 0; i < hdata->list_of_hops_length(); i++) {
145 std::cout << printIP(hdata->list_of_hops()[i]) << ";";
146 }
147 std::cout << std::endl;
148 }
149 } else if (this->getNumberOfHopToSink() == 0) {
150
152 this->searchPath(); // Node not connected with any sink:
153 // send a path establishment request.
154 search_path_enable_ = false;
156 }
157 if (iph->daddr() == 0) { // The packet is not initialized and
158 // the current node doesn't have any
159 // path to the sink: wait.
160 ch->prev_hop_ = ipAddr_;
161 _tmp.num_attempts_++;
162 _tmp.t_last_tx_ = Scheduler::instance().clock();
163 _tmp.p_ = p->copy();
164 Packet::free(((buffer_element) buffer_data.front()).p_);
165 buffer_data.erase(buffer_data.begin());
166 buffer_data.insert(buffer_data.begin(), _tmp);
167 } else {
168 if (iph->saddr() == ipAddr_) { // The current node created a
169 // packet but now it doesn't
170 // have a path to the sink ->
171 // reset the packet.
172 iph->daddr() = 0;
173 _tmp.num_attempts_++;
174 _tmp.t_last_tx_ = Scheduler::instance().clock();
175 _tmp.p_ = p->copy();
176 Packet::free(((buffer_element) buffer_data.front()).p_);
177 buffer_data.erase(buffer_data.begin());
178 buffer_data.insert(buffer_data.begin(), _tmp);
179 pkt_tx_++;
180 } else { // Otherwise forward.
181 _tmp.num_attempts_++;
182 _tmp.t_last_tx_ = Scheduler::instance().clock();
183 _tmp.p_ = p->copy();
184 Packet::free(((buffer_element) buffer_data.front()).p_);
185 buffer_data.erase(buffer_data.begin());
186 buffer_data.insert(buffer_data.begin(), _tmp);
187 this->forwardDataPacket(_tmp.p_->copy());
188 }
189 }
190 if (printDebug_ > 5) {
191 std::cout << "[" << NOW
192 << "]::Node[IP:" << this->printIP(ipAddr_)
193 << "||hops:" << this->getNumberOfHopToSink()
194 << "]::PACKET_WAITING::NO_ROUTE::RETX:" << _tmp.retx_
195 << "::UID:" << ch->uid()
196 << "::SN:" << uwcbrh->sn()
197 << std::endl;
198 }
199 }
200 if (this->getNumberOfHopToSink() > 1) {
201
202 if (iph->daddr() == 0) { // The packet is not initialized.
203 // cout << "node:" << printIP(ipAddr_) <<
204 // "-bufsize:" << buffer_data.size() <<
205 // "-hop:" <<
206 // this->getNumberOfHopToSink() <<
207 // "-init." << endl;
208 this->initPktDataPacket(p);
209 ch->next_hop() = this->hop_table[0];
210 ch->prev_hop_ = ipAddr_;
211 iph->daddr() = sink_associated;
213 _tmp.retx_++;
214 _tmp.t_last_tx_ = Scheduler::instance().clock();
215 _tmp.p_ = p->copy();
216 Packet::free(((buffer_element) buffer_data.front()).p_);
217 buffer_data.erase(buffer_data.begin());
218 buffer_data.insert(buffer_data.begin(), _tmp);
219 data_and_hops[int(hdata->list_of_hops_length())]++;
220 pkt_tx_++;
221 if (trace_)
222 this->tracePacket(_tmp.p_, "SEND_DTA");
223 sendDown(_tmp.p_->copy(), delay_tx_);
224 } else {
225 // cout << "node:" << printIP(ipAddr_) <<
226 // "-bufsize:" << buffer_data.size() <<
227 // "-hop:" <<
228 // this->getNumberOfHopToSink() <<
229 // "-send." << endl;
230 ch->prev_hop_ = ipAddr_;
231 _tmp.retx_++;
232 _tmp.t_last_tx_ = Scheduler::instance().clock();
233 _tmp.p_ = p->copy();
234 Packet::free(((buffer_element) buffer_data.front()).p_);
235 buffer_data.erase(buffer_data.begin());
236 buffer_data.insert(buffer_data.begin(), _tmp);
237 if (iph->saddr() == ipAddr_) { // Send.
239 pkt_tx_++;
240 if (trace_)
241 this->tracePacket(_tmp.p_, "SEND_DTA");
242 sendDown(_tmp.p_->copy(), delay_tx_);
243 } else { // Otherwise forward.
244 this->forwardDataPacket(_tmp.p_->copy());
245 }
246 }
247 if (printDebug_ > 5) {
248 std::cout << "[" << NOW
249 << "]::Node[IP:" << this->printIP(ipAddr_)
250 << "||hops:" << this->getNumberOfHopToSink()
251 << "]::PACKET_SENT::RETX:" << _tmp.retx_
252 << "::UID:" << ch->uid()
253 << "::SN:" << uwcbrh->sn()
254 << "::SRC:" << printIP(iph->saddr())
255 << "::ROUTE:";
256 for (int i = 0; i < hdata->list_of_hops_length(); i++) {
257 std::cout << printIP(hdata->list_of_hops()[i]) << ";";
258 }
259 std::cout << std::endl;
260 }
261 }
262 Packet::free(p);
263 } else { // The first packet in the buffer is invalid.
264 Packet *p = _tmp.p_->copy();
265 hdr_cmn *ch = HDR_CMN(p);
266 hdr_uwip *iph = HDR_UWIP(p);
268
269 if (iph->saddr() == ipAddr_) { // Current node creates the packet
270 // that generated an error: remove
271 // the routing information.
272 this->clearHops();
273 this->setNumberOfHopToSink(0);
274 } else { // Another node created the packet: create a route error
275 // packet.
276 if (!disable_path_error_) {
277 Packet *p_error = Packet::alloc();
278 this->createRouteError(p, p_error);
279
280 if (ch->next_hop() == this->sink_associated) {
281 this->clearHops();
282 this->setNumberOfHopToSink(0);
283 } else if (ch->next_hop() != 0 &&
284 ch->next_hop() == hop_table[0]) { // If the next hop of the
285 // packet that generated an
286 // error is equal to the
287 // next hop of the current
288 // node: update the routing
289 // information.
290 this->clearHops();
291 this->setNumberOfHopToSink(0);
292 }
293 if (trace_)
294 this->tracePacket(p_error, "SEND_ERR");
295 sendDown(p_error->copy());
296 Packet::free(p_error);
297 }
298 }
300 Packet::free(((buffer_element) buffer_data.front()).p_);
301 buffer_data.erase(buffer_data.begin()); // Remove the first pkt.
302 Packet::free(p);
303 if (reset_buffer_if_error_) { // If == 1 all the packets in the
304 // buffer will be removed.
305 while (!buffer_data.empty()) {
306 Packet::free(((buffer_element) buffer_data.front()).p_);
307 buffer_data.erase(buffer_data.begin());
308 }
309 }
310 if (printDebug_ > 5) {
311 std::cout << "[" << NOW
312 << "]::Node[IP:" << this->printIP(ipAddr_)
313 << "||hops:" << this->getNumberOfHopToSink()
314 << "]::INVALID_PACKET::UID:" << ch->uid()
315 << "::SN:" << uwcbrh->sn()
316 << std::endl;
317 }
318 }
319 }
321 return;
322}
SunIPRoutingNode *virtual void expire(Event *e)
< Pointer to an objet of type SunIPRoutingNode.
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.
uint max_retx_
Maximum Number of transmissions performed: real retransmissions counter the counter is increased only...
vector< buffer_element > buffer_data
Buffer used to store data packets.
ostringstream osstream_
Used to convert to string.
bool search_path_enable_
Flag to enable or disable the possibility to send search_path packets.
static long number_of_datapkt_
Comulative number of Data packets processed by SunIPRoutingNode objects.
virtual void initPktDataPacket(Packet *)
Initializes a data packet passed as argument with the default values.
virtual void createRouteError(const Packet *, Packet *)
Used to create a route error packet.
virtual void clearHops()
Clears all the route information of the current node.
nsaddr_t * hop_table
List of IPs to reach the sink.
virtual void forwardDataPacket(Packet *)
Forwards a data packet to the next hop.
int disable_path_error_
Flag to enable or disable the possibility to send Path Error packets.
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 void bufferManager()
Manage the buffer of the data packets.
int data_and_hops[MAX_HOP_NUMBER]
Structure that contains the number of data packets sent by the current node to the sink,...
int reset_buffer_if_error_
If == 1 when a node identify a broken link it will automatically free its buffer.
static long number_of_pkt_forwarded_
Comulative number of Data packets forwarded by the network.
BufferTimer bufferTmr_
BufferTimer object.
nsaddr_t sink_associated
IP of the sink associated to the node.
double timer_buffer_
Timer for buffer management.
virtual const int & setNumberOfHopToSink(const int &)
Sets the number of hops that the current node needs to reach the sink.
double period_data_
Period of the Poisson traffic for data packets in the buffer.
SearchPathTimer searchPathTmr_
SearchPathTimer object.
const double getDelay(const double &period_) const
Returns a delay value to use in transmission.
virtual void searchPath()
Sends a Path Establishment Packet with the option field sets to Search.
int max_ack_error_
Maximum number of Ack errors tollerated by the node.
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.
long pkt_tx_
Keep track of the total number of packet retransmitted.
double timer_search_path_
Timer for the search path mechanism.
static long number_of_drops_maxretx_
Comulative number of packets dropped by SunIPRoutingNode objects, reason: max number of retransmissio...
buffer_element describes an entry in the buffer used by SUN.
unsigned int retx_
Real retransmission counter: incremented only if packet is sent donwlayer.
Packet * p_
Pointer to the packet buffered.
hdr_sun_data describes data packets used by UWSUN
hdr_uwcbr describes UWCBR packets.
hdr_uwip describes UWIP packets.
Definition uwip-module.h:70
uint8_t & daddr()
Reference to the daddr_ variable.
#define HDR_SUN_DATA(p)
#define STACK_TRACE
Used to keep track of methods call.
Dinamic source routing protocol, this file contains Nodes specifications.
Provides the UWCBR packets header description and the definition of the class UWCBR.
#define HDR_UWCBR(p)
#define HDR_UWIP(P)
Definition uwip-module.h:58