A Discrete-Event Network Simulator
API
arp-cache.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 #include "arp-cache.h"
20 
21 #include "arp-header.h"
22 #include "ipv4-header.h"
23 #include "ipv4-interface.h"
24 
25 #include "ns3/assert.h"
26 #include "ns3/log.h"
27 #include "ns3/names.h"
28 #include "ns3/node.h"
29 #include "ns3/packet.h"
30 #include "ns3/simulator.h"
31 #include "ns3/trace-source-accessor.h"
32 #include "ns3/uinteger.h"
33 
34 namespace ns3
35 {
36 
37 NS_LOG_COMPONENT_DEFINE("ArpCache");
38 
40 
41 TypeId
43 {
44  static TypeId tid = TypeId("ns3::ArpCache")
45  .SetParent<Object>()
46  .SetGroupName("Internet")
47  .AddAttribute("AliveTimeout",
48  "When this timeout expires, "
49  "the matching cache entry needs refreshing",
50  TimeValue(Seconds(120)),
53  .AddAttribute("DeadTimeout",
54  "When this timeout expires, "
55  "a new attempt to resolve the matching entry is made",
56  TimeValue(Seconds(100)),
59  .AddAttribute("WaitReplyTimeout",
60  "When this timeout expires, "
61  "the cache entries will be scanned and "
62  "entries in WaitReply state will resend ArpRequest "
63  "unless MaxRetries has been exceeded, "
64  "in which case the entry is marked dead",
65  TimeValue(Seconds(1)),
68  .AddAttribute("MaxRetries",
69  "Number of retransmissions of ArpRequest "
70  "before marking dead",
71  UintegerValue(3),
73  MakeUintegerChecker<uint32_t>())
74  .AddAttribute("PendingQueueSize",
75  "The size of the queue for packets pending an arp reply.",
76  UintegerValue(3),
78  MakeUintegerChecker<uint32_t>())
79  .AddTraceSource("Drop",
80  "Packet dropped due to ArpCache entry "
81  "in WaitReply expiring.",
83  "ns3::Packet::TracedCallback");
84  return tid;
85 }
86 
88  : m_device(nullptr),
89  m_interface(nullptr)
90 {
91  NS_LOG_FUNCTION(this);
92 }
93 
95 {
96  NS_LOG_FUNCTION(this);
97 }
98 
99 void
101 {
102  NS_LOG_FUNCTION(this);
103  Flush();
104  m_device = nullptr;
105  m_interface = nullptr;
107  {
109  }
111 }
112 
113 void
115 {
116  NS_LOG_FUNCTION(this << device << interface);
117  m_device = device;
118  m_interface = interface;
119 }
120 
123 {
124  NS_LOG_FUNCTION(this);
125  return m_device;
126 }
127 
130 {
131  NS_LOG_FUNCTION(this);
132  return m_interface;
133 }
134 
135 void
137 {
138  NS_LOG_FUNCTION(this << aliveTimeout);
139  m_aliveTimeout = aliveTimeout;
140 }
141 
142 void
144 {
145  NS_LOG_FUNCTION(this << deadTimeout);
146  m_deadTimeout = deadTimeout;
147 }
148 
149 void
151 {
152  NS_LOG_FUNCTION(this << waitReplyTimeout);
153  m_waitReplyTimeout = waitReplyTimeout;
154 }
155 
156 Time
158 {
159  NS_LOG_FUNCTION(this);
160  return m_aliveTimeout;
161 }
162 
163 Time
165 {
166  NS_LOG_FUNCTION(this);
167  return m_deadTimeout;
168 }
169 
170 Time
172 {
173  NS_LOG_FUNCTION(this);
174  return m_waitReplyTimeout;
175 }
176 
177 void
179 {
180  NS_LOG_FUNCTION(this << &arpRequestCallback);
181  m_arpRequestCallback = arpRequestCallback;
182 }
183 
184 void
186 {
187  NS_LOG_FUNCTION(this);
189  {
190  NS_LOG_LOGIC("Starting WaitReplyTimer at " << Simulator::Now() << " for "
191  << m_waitReplyTimeout);
194  }
195 }
196 
197 void
199 {
200  NS_LOG_FUNCTION(this);
201  ArpCache::Entry* entry;
202  bool restartWaitReplyTimer = false;
203  for (CacheI i = m_arpCache.begin(); i != m_arpCache.end(); i++)
204  {
205  entry = (*i).second;
206  if (entry != nullptr && entry->IsWaitReply())
207  {
208  if (entry->GetRetries() < m_maxRetries)
209  {
210  NS_LOG_LOGIC("node=" << m_device->GetNode()->GetId() << ", ArpWaitTimeout for "
211  << entry->GetIpv4Address()
212  << " expired -- retransmitting arp request since retries = "
213  << entry->GetRetries());
214  m_arpRequestCallback(this, entry->GetIpv4Address());
215  restartWaitReplyTimer = true;
216  entry->IncrementRetries();
217  }
218  else
219  {
220  NS_LOG_LOGIC("node=" << m_device->GetNode()->GetId() << ", wait reply for "
221  << entry->GetIpv4Address()
222  << " expired -- drop since max retries exceeded: "
223  << entry->GetRetries());
224  entry->MarkDead();
225  entry->ClearRetries();
226  Ipv4PayloadHeaderPair pending = entry->DequeuePending();
227  while (pending.first)
228  {
229  // add the Ipv4 header for tracing purposes
230  pending.first->AddHeader(pending.second);
231  m_dropTrace(pending.first);
232  pending = entry->DequeuePending();
233  }
234  }
235  }
236  }
237  if (restartWaitReplyTimer)
238  {
239  NS_LOG_LOGIC("Restarting WaitReplyTimer at " << Simulator::Now().GetSeconds());
242  }
243 }
244 
245 void
247 {
248  NS_LOG_FUNCTION(this);
249  for (CacheI i = m_arpCache.begin(); i != m_arpCache.end(); i++)
250  {
251  delete (*i).second;
252  }
253  m_arpCache.erase(m_arpCache.begin(), m_arpCache.end());
255  {
256  NS_LOG_LOGIC("Stopping WaitReplyTimer at " << Simulator::Now().GetSeconds()
257  << " due to ArpCache flush");
259  }
260 }
261 
262 void
264 {
265  NS_LOG_FUNCTION(this << stream);
266  std::ostream* os = stream->GetStream();
267 
268  for (CacheI i = m_arpCache.begin(); i != m_arpCache.end(); i++)
269  {
270  *os << i->first << " dev ";
271  std::string found = Names::FindName(m_device);
272  if (!Names::FindName(m_device).empty())
273  {
274  *os << found;
275  }
276  else
277  {
278  *os << static_cast<int>(m_device->GetIfIndex());
279  }
280 
281  *os << " lladdr " << i->second->GetMacAddress();
282 
283  if (i->second->IsAlive())
284  {
285  *os << " REACHABLE\n";
286  }
287  else if (i->second->IsWaitReply())
288  {
289  *os << " DELAY\n";
290  }
291  else if (i->second->IsPermanent())
292  {
293  *os << " PERMANENT\n";
294  }
295  else if (i->second->IsAutoGenerated())
296  {
297  *os << " STATIC_AUTOGENERATED\n";
298  }
299  else
300  {
301  *os << " STALE\n";
302  }
303  }
304 }
305 
306 void
308 {
309  NS_LOG_FUNCTION(this);
310  for (CacheI i = m_arpCache.begin(); i != m_arpCache.end();)
311  {
312  if (i->second->IsAutoGenerated())
313  {
314  i->second->ClearPendingPacket(); // clear the pending packets for entry's ipaddress
315  delete i->second;
316  m_arpCache.erase(i++);
317  continue;
318  }
319  i++;
320  }
321 }
322 
323 std::list<ArpCache::Entry*>
325 {
326  NS_LOG_FUNCTION(this << to);
327 
328  std::list<ArpCache::Entry*> entryList;
329  for (CacheI i = m_arpCache.begin(); i != m_arpCache.end(); i++)
330  {
331  ArpCache::Entry* entry = (*i).second;
332  if (entry->GetMacAddress() == to)
333  {
334  entryList.push_back(entry);
335  }
336  }
337  return entryList;
338 }
339 
342 {
343  NS_LOG_FUNCTION(this << to);
344  CacheI it = m_arpCache.find(to);
345  if (it != m_arpCache.end())
346  {
347  return it->second;
348  }
349  return nullptr;
350 }
351 
354 {
355  NS_LOG_FUNCTION(this << to);
356  NS_ASSERT(m_arpCache.find(to) == m_arpCache.end());
357 
358  ArpCache::Entry* entry = new ArpCache::Entry(this);
359  m_arpCache[to] = entry;
360  entry->SetIpv4Address(to);
361  return entry;
362 }
363 
364 void
366 {
367  NS_LOG_FUNCTION(this << entry);
368 
369  for (CacheI i = m_arpCache.begin(); i != m_arpCache.end(); i++)
370  {
371  if ((*i).second == entry)
372  {
373  m_arpCache.erase(i);
374  entry->ClearPendingPacket(); // clear the pending packets for entry's ipaddress
375  delete entry;
376  return;
377  }
378  }
379  NS_LOG_WARN("Entry not found in this ARP Cache");
380 }
381 
383  : m_arp(arp),
384  m_state(ALIVE),
385  m_retries(0)
386 {
387  NS_LOG_FUNCTION(this << arp);
388 }
389 
390 bool
392 {
393  NS_LOG_FUNCTION(this);
394  return (m_state == DEAD);
395 }
396 
397 bool
399 {
400  NS_LOG_FUNCTION(this);
401  return (m_state == ALIVE);
402 }
403 
404 bool
406 {
407  NS_LOG_FUNCTION(this);
408  return (m_state == WAIT_REPLY);
409 }
410 
411 bool
413 {
414  NS_LOG_FUNCTION(this);
415  return (m_state == PERMANENT);
416 }
417 
418 bool
420 {
421  NS_LOG_FUNCTION(this);
422  return (m_state == STATIC_AUTOGENERATED);
423 }
424 
425 void
427 {
428  NS_LOG_FUNCTION(this);
429  NS_ASSERT(m_state == ALIVE || m_state == WAIT_REPLY || m_state == DEAD);
430  m_state = DEAD;
431  ClearRetries();
432  UpdateSeen();
433 }
434 
435 void
437 {
438  NS_LOG_FUNCTION(this << macAddress);
439  NS_ASSERT(m_state == WAIT_REPLY);
440  m_macAddress = macAddress;
441  m_state = ALIVE;
442  ClearRetries();
443  UpdateSeen();
444 }
445 
446 void
448 {
449  NS_LOG_FUNCTION(this << m_macAddress);
450  NS_ASSERT(!m_macAddress.IsInvalid());
451 
452  m_state = PERMANENT;
453  ClearRetries();
454  UpdateSeen();
455 }
456 
457 void
459 {
460  NS_LOG_FUNCTION(this << m_macAddress);
461  NS_ASSERT(!m_macAddress.IsInvalid());
462 
463  m_state = STATIC_AUTOGENERATED;
464  ClearRetries();
465  UpdateSeen();
466 }
467 
468 bool
470 {
471  NS_LOG_FUNCTION(this << waiting.first);
472  NS_ASSERT(m_state == WAIT_REPLY);
473  /* We are already waiting for an answer so
474  * we dump the previously waiting packet and
475  * replace it with this one.
476  */
477  if (m_pending.size() >= m_arp->m_pendingQueueSize)
478  {
479  return false;
480  }
481  m_pending.push_back(waiting);
482  return true;
483 }
484 
485 void
487 {
488  NS_LOG_FUNCTION(this << waiting.first);
489  NS_ASSERT(m_state == ALIVE || m_state == DEAD);
490  NS_ASSERT(m_pending.empty());
491  NS_ASSERT_MSG(waiting.first, "Can not add a null packet to the ARP queue");
492 
493  m_state = WAIT_REPLY;
494  m_pending.push_back(waiting);
495  UpdateSeen();
496  m_arp->StartWaitReplyTimer();
497 }
498 
499 Address
501 {
502  NS_LOG_FUNCTION(this);
503  return m_macAddress;
504 }
505 
506 void
508 {
509  NS_LOG_FUNCTION(this);
510  m_macAddress = macAddress;
511 }
512 
515 {
516  NS_LOG_FUNCTION(this);
517  return m_ipv4Address;
518 }
519 
520 void
522 {
523  NS_LOG_FUNCTION(this << destination);
524  m_ipv4Address = destination;
525 }
526 
527 Time
529 {
530  NS_LOG_FUNCTION(this);
531  switch (m_state)
532  {
534  return m_arp->GetWaitReplyTimeout();
536  return m_arp->GetDeadTimeout();
538  return m_arp->GetAliveTimeout();
540  return Time::Max();
542  return Time::Max();
543  }
544  return Time(); // Silence compiler warning
545 }
546 
547 bool
549 {
550  NS_LOG_FUNCTION(this);
551  Time timeout = GetTimeout();
552  Time delta = Simulator::Now() - m_lastSeen;
553  NS_LOG_DEBUG("delta=" << delta.GetSeconds() << "s");
554  if (delta > timeout)
555  {
556  return true;
557  }
558  return false;
559 }
560 
563 {
564  NS_LOG_FUNCTION(this);
565  if (m_pending.empty())
566  {
567  Ipv4Header h;
568  return Ipv4PayloadHeaderPair(nullptr, h);
569  }
570  else
571  {
572  Ipv4PayloadHeaderPair p = m_pending.front();
573  m_pending.pop_front();
574  return p;
575  }
576 }
577 
578 void
580 {
581  NS_LOG_FUNCTION(this);
582  m_pending.clear();
583 }
584 
585 void
587 {
588  NS_LOG_FUNCTION(this);
589  m_lastSeen = Simulator::Now();
590 }
591 
592 uint32_t
594 {
595  NS_LOG_FUNCTION(this);
596  return m_retries;
597 }
598 
599 void
601 {
602  NS_LOG_FUNCTION(this);
603  m_retries++;
604  UpdateSeen();
605 }
606 
607 void
609 {
610  NS_LOG_FUNCTION(this);
611  m_retries = 0;
612 }
613 
614 } // namespace ns3
a polymophic address class
Definition: address.h:100
A record that that holds information about an ArpCache entry.
Definition: arp-cache.h:184
bool IsDead()
Definition: arp-cache.cc:391
void SetIpv4Address(Ipv4Address destination)
Definition: arp-cache.cc:521
void MarkAutoGenerated()
Changes the state of this entry to auto-generated.
Definition: arp-cache.cc:458
bool IsAlive()
Definition: arp-cache.cc:398
bool UpdateWaitReply(Ipv4PayloadHeaderPair waiting)
Definition: arp-cache.cc:469
Address GetMacAddress() const
Definition: arp-cache.cc:500
void ClearPendingPacket()
Clear the pending packet list.
Definition: arp-cache.cc:579
void MarkPermanent()
Changes the state of this entry to Permanent.
Definition: arp-cache.cc:447
bool IsExpired() const
Definition: arp-cache.cc:548
void ClearRetries()
Zero the counter of number of retries for an entry.
Definition: arp-cache.cc:608
@ WAIT_REPLY
Definition: arp-cache.h:299
@ ALIVE
Definition: arp-cache.h:298
@ STATIC_AUTOGENERATED
Definition: arp-cache.h:302
@ PERMANENT
Definition: arp-cache.h:301
@ DEAD
Definition: arp-cache.h:300
uint32_t GetRetries() const
Definition: arp-cache.cc:593
void UpdateSeen()
Update the entry when seeing a packet.
Definition: arp-cache.cc:586
bool IsWaitReply()
Definition: arp-cache.cc:405
void IncrementRetries()
Increment the counter of number of retries for an entry.
Definition: arp-cache.cc:600
void MarkAlive(Address macAddress)
Definition: arp-cache.cc:436
bool IsAutoGenerated()
Definition: arp-cache.cc:419
void MarkDead()
Changes the state of this entry to dead.
Definition: arp-cache.cc:426
void SetMacAddress(Address macAddress)
Definition: arp-cache.cc:507
void MarkWaitReply(Ipv4PayloadHeaderPair waiting)
Definition: arp-cache.cc:486
Ipv4PayloadHeaderPair DequeuePending()
Definition: arp-cache.cc:562
Ipv4Address GetIpv4Address() const
Definition: arp-cache.cc:514
bool IsPermanent()
Definition: arp-cache.cc:412
Time GetTimeout() const
Returns the entry timeout.
Definition: arp-cache.cc:528
Entry(ArpCache *arp)
Constructor.
Definition: arp-cache.cc:382
An ARP cache.
Definition: arp-cache.h:53
Time GetWaitReplyTimeout() const
Get the time the entry will be in WAIT_REPLY state.
Definition: arp-cache.cc:171
void Remove(ArpCache::Entry *entry)
Remove an entry.
Definition: arp-cache.cc:365
void SetWaitReplyTimeout(Time waitReplyTimeout)
Set the time the entry will be in WAIT_REPLY state.
Definition: arp-cache.cc:150
void HandleWaitReplyTimeout()
This function is an event handler for the event that the ArpCache wants to check whether it must retr...
Definition: arp-cache.cc:198
Time GetAliveTimeout() const
Get the time the entry will be in ALIVE state (unless refreshed)
Definition: arp-cache.cc:157
uint32_t m_maxRetries
max retries for a resolution
Definition: arp-cache.h:340
EventId m_waitReplyTimer
cache alive state timer
Definition: arp-cache.h:337
Time m_aliveTimeout
cache alive state timeout
Definition: arp-cache.h:334
void DoDispose() override
Destructor implementation.
Definition: arp-cache.cc:100
void SetArpRequestCallback(Callback< void, Ptr< const ArpCache >, Ipv4Address > arpRequestCallback)
This callback is set when the ArpCache is set up and allows the cache to generate an Arp request when...
Definition: arp-cache.cc:178
Time m_deadTimeout
cache dead state timeout
Definition: arp-cache.h:335
Time m_waitReplyTimeout
cache reply state timeout
Definition: arp-cache.h:336
Ptr< Ipv4Interface > m_interface
Ipv4Interface associated with the cache.
Definition: arp-cache.h:333
void PrintArpCache(Ptr< OutputStreamWrapper > stream)
Print the ARP cache entries.
Definition: arp-cache.cc:263
void Flush()
Clear the ArpCache of all entries.
Definition: arp-cache.cc:246
void SetAliveTimeout(Time aliveTimeout)
Set the time the entry will be in ALIVE state (unless refreshed)
Definition: arp-cache.cc:136
uint32_t m_pendingQueueSize
number of packets waiting for a resolution
Definition: arp-cache.h:348
TracedCallback< Ptr< const Packet > > m_dropTrace
trace for packets dropped by the ARP cache queue
Definition: arp-cache.h:351
ArpCache::Entry * Add(Ipv4Address to)
Add an Ipv4Address to this ARP cache.
Definition: arp-cache.cc:353
void SetDevice(Ptr< NetDevice > device, Ptr< Ipv4Interface > interface)
Set the NetDevice and Ipv4Interface associated with the ArpCache.
Definition: arp-cache.cc:114
Ptr< Ipv4Interface > GetInterface() const
Returns the Ipv4Interface that this ARP cache is associated with.
Definition: arp-cache.cc:129
std::list< ArpCache::Entry * > LookupInverse(Address destination)
Do lookup in the ARP cache against a MAC address.
Definition: arp-cache.cc:324
Callback< void, Ptr< const ArpCache >, Ipv4Address > m_arpRequestCallback
reply timeout callback
Definition: arp-cache.h:339
ArpCache::Entry * Lookup(Ipv4Address destination)
Do lookup in the ARP cache against an IP address.
Definition: arp-cache.cc:341
Cache m_arpCache
the ARP cache
Definition: arp-cache.h:349
void RemoveAutoGeneratedEntries()
Clear the ArpCache of all Auto-Generated entries.
Definition: arp-cache.cc:307
~ArpCache() override
Definition: arp-cache.cc:94
Ptr< NetDevice > m_device
NetDevice associated with the cache.
Definition: arp-cache.h:332
void StartWaitReplyTimer()
This method will schedule a timeout at WaitReplyTimeout interval in the future, unless a timer is alr...
Definition: arp-cache.cc:185
Time GetDeadTimeout() const
Get the time the entry will be in DEAD state before being removed.
Definition: arp-cache.cc:164
static TypeId GetTypeId()
Get the type ID.
Definition: arp-cache.cc:42
std::pair< Ptr< Packet >, Ipv4Header > Ipv4PayloadHeaderPair
Pair of a packet and an Ipv4 header.
Definition: arp-cache.h:178
void SetDeadTimeout(Time deadTimeout)
Set the time the entry will be in DEAD state before being removed.
Definition: arp-cache.cc:143
Ptr< NetDevice > GetDevice() const
Returns the NetDevice that this ARP cache is associated with.
Definition: arp-cache.cc:122
std::map< Ipv4Address, ArpCache::Entry * >::iterator CacheI
ARP Cache container iterator.
Definition: arp-cache.h:328
Callback template class.
Definition: callback.h:443
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
Packet header for IPv4.
Definition: ipv4-header.h:34
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
Definition: names.cc:830
A base class which provides memory management and object aggregation.
Definition: object.h:89
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
std::ostream * GetStream()
Return a pointer to an ostream previously set in the wrapper.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
static Time Max()
Maximum representable Time Not to be confused with Max(Time,Time).
Definition: nstime.h:296
AttributeValue implementation for Time.
Definition: nstime.h:1423
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:46
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:848
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
ns3::Time timeout