View | Details | Raw Unified | Return to bug 253
Collapse All | Expand All

(-)a/src/internet-stack/arp-cache.cc (-3 / +121 lines)
 Lines 22-27    Link Here 
22
#include "ns3/simulator.h"
22
#include "ns3/simulator.h"
23
#include "ns3/uinteger.h"
23
#include "ns3/uinteger.h"
24
#include "ns3/log.h"
24
#include "ns3/log.h"
25
#include "ns3/node.h"
26
#include "ns3/trace-source-accessor.h"
25
27
26
#include "arp-cache.h"
28
#include "arp-cache.h"
27
#include "arp-header.h"
29
#include "arp-header.h"
 Lines 47-61   ArpCache::GetTypeId (void) Link Here 
47
                   MakeTimeAccessor (&ArpCache::m_deadTimeout),
49
                   MakeTimeAccessor (&ArpCache::m_deadTimeout),
48
                   MakeTimeChecker ())
50
                   MakeTimeChecker ())
49
    .AddAttribute ("WaitReplyTimeout",
51
    .AddAttribute ("WaitReplyTimeout",
50
                   "When this timeout expires, the matching cache entry is marked dead",
52
                   "When this timeout expires, the cache entries will be scanned and entries in WaitReply state will resend ArpRequest unless MaxRetries has been exceeded, in which case the entry is marked dead",           
51
                   TimeValue (Seconds (1)),
53
                   TimeValue (Seconds (1)),
52
                   MakeTimeAccessor (&ArpCache::m_waitReplyTimeout),
54
                   MakeTimeAccessor (&ArpCache::m_waitReplyTimeout),
53
                   MakeTimeChecker ())
55
                   MakeTimeChecker ())
56
    .AddAttribute ("MaxRetries",                   
57
                   "Number of retransmissions of ArpRequest before marking dead",                  
58
                   UintegerValue (3),
59
                   MakeUintegerAccessor (&ArpCache::m_maxRetries),
60
                   MakeUintegerChecker<uint32_t> ())
54
    .AddAttribute ("PendingQueueSize",
61
    .AddAttribute ("PendingQueueSize",
55
                   "The size of the queue for packets pending an arp reply.",
62
                   "The size of the queue for packets pending an arp reply.",
56
                   UintegerValue (3),
63
                   UintegerValue (3),
57
                   MakeUintegerAccessor (&ArpCache::m_pendingQueueSize),
64
                   MakeUintegerAccessor (&ArpCache::m_pendingQueueSize),
58
                   MakeUintegerChecker<uint32_t> ())
65
                   MakeUintegerChecker<uint32_t> ())
66
    .AddTraceSource ("Drop",                     
67
                     "Packet dropped due to ArpCache entry in WaitReply expiring.",
68
                     MakeTraceSourceAccessor (&ArpCache::m_dropTrace))
59
    ;
69
    ;
60
  return tid;
70
  return tid;
61
}
71
}
 Lines 79-84   ArpCache::DoDispose (void) Link Here 
79
  Flush ();
89
  Flush ();
80
  m_device = 0;
90
  m_device = 0;
81
  m_interface = 0;
91
  m_interface = 0;
92
  if (!m_waitReplyTimer.IsRunning ())
93
    {
94
      Simulator::Remove (m_waitReplyTimer);
95
    }
82
  Object::DoDispose ();
96
  Object::DoDispose ();
83
}
97
}
84
98
 Lines 143-148   ArpCache::GetWaitReplyTimeout (void) con Link Here 
143
}
157
}
144
158
145
void 
159
void 
160
ArpCache::SetArpRequestCallback (Callback<void, Ptr<const ArpCache>,
161
                             Ipv4Address> arpRequestCallback)
162
{
163
  NS_LOG_FUNCTION_NOARGS ();
164
  m_arpRequestCallback = arpRequestCallback;
165
}
166
167
void 
168
ArpCache::StartWaitReplyTimer (void)
169
{
170
  NS_LOG_FUNCTION_NOARGS ();
171
  if (!m_waitReplyTimer.IsRunning ())
172
    {
173
      NS_LOG_LOGIC ("Starting WaitReplyTimer at " << Simulator::Now ().GetSeconds ());
174
      m_waitReplyTimer = Simulator::Schedule (m_waitReplyTimeout, 
175
        &ArpCache::HandleWaitReplyTimeout, this);
176
    }
177
}
178
179
void
180
ArpCache::HandleWaitReplyTimeout (void)
181
{
182
  NS_LOG_FUNCTION_NOARGS ();
183
  ArpCache::Entry* entry;
184
  bool restartWaitReplyTimer = false;
185
  for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++) 
186
    {
187
      entry = (*i).second;
188
      if (entry != 0 && entry->IsWaitReply () && entry->IsExpired ())
189
          {
190
          if (entry->GetRetries () < m_maxRetries)
191
            {
192
              NS_LOG_LOGIC ("node="<< m_device->GetNode ()->GetId () <<
193
                ", ArpWaitTimeout for " << entry->GetIpv4Address () <<
194
                " expired -- retransmitting arp request since retries = " << 
195
                entry->GetRetries ());
196
              m_arpRequestCallback (this, entry->GetIpv4Address ());
197
              restartWaitReplyTimer = true;
198
              entry->IncrementRetries ();
199
            }
200
          else
201
            {
202
              NS_LOG_LOGIC ("node="<<m_device->GetNode ()->GetId () <<
203
                ", wait reply for " << entry->GetIpv4Address () << 
204
                " expired -- drop since max retries exceeded: " << 
205
                 entry->GetRetries ());
206
              entry->MarkDead ();
207
              entry->ClearRetries ();
208
              Ptr<Packet> pending = entry->DequeuePending();
209
              while (pending != 0)
210
                {
211
                  m_dropTrace (pending);
212
                  pending = entry->DequeuePending();
213
                }
214
            }
215
       }
216
217
    }
218
  if (restartWaitReplyTimer)
219
    {
220
      NS_LOG_LOGIC ("Restarting WaitReplyTimer at " << Simulator::Now ().GetSeconds ());
221
      m_waitReplyTimer = Simulator::Schedule (m_waitReplyTimeout, 
222
        &ArpCache::HandleWaitReplyTimeout, this);
223
    }
224
}
225
226
void 
146
ArpCache::Flush (void)
227
ArpCache::Flush (void)
147
{
228
{
148
  NS_LOG_FUNCTION_NOARGS ();
229
  NS_LOG_FUNCTION_NOARGS ();
 Lines 173-184   ArpCache::Add (Ipv4Address to) Link Here 
173
254
174
  ArpCache::Entry *entry = new ArpCache::Entry (this);
255
  ArpCache::Entry *entry = new ArpCache::Entry (this);
175
  m_arpCache[to] = entry;  
256
  m_arpCache[to] = entry;  
257
  entry->SetIpv4Address (to);
176
  return entry;
258
  return entry;
177
}
259
}
178
260
179
ArpCache::Entry::Entry (ArpCache *arp)
261
ArpCache::Entry::Entry (ArpCache *arp)
180
  : m_arp (arp),
262
  : m_arp (arp),
181
    m_state (ALIVE)
263
    m_state (ALIVE),
264
    m_retries (0)
182
{
265
{
183
  NS_LOG_FUNCTION_NOARGS ();
266
  NS_LOG_FUNCTION_NOARGS ();
184
}
267
}
 Lines 209-214   ArpCache::Entry::MarkDead (void) Link Here 
209
{
292
{
210
  NS_LOG_FUNCTION_NOARGS ();
293
  NS_LOG_FUNCTION_NOARGS ();
211
  m_state = DEAD;
294
  m_state = DEAD;
295
  ClearRetries ();
212
  UpdateSeen ();
296
  UpdateSeen ();
213
}
297
}
214
void
298
void
 Lines 218-223   ArpCache::Entry::MarkAlive (Address macA Link Here 
218
  NS_ASSERT (m_state == WAIT_REPLY);
302
  NS_ASSERT (m_state == WAIT_REPLY);
219
  m_macAddress = macAddress;
303
  m_macAddress = macAddress;
220
  m_state = ALIVE;
304
  m_state = ALIVE;
305
  ClearRetries ();
221
  UpdateSeen ();
306
  UpdateSeen ();
222
}
307
}
223
308
 Lines 246-260   ArpCache::Entry::MarkWaitReply (Ptr<Pack Link Here 
246
  m_state = WAIT_REPLY;
331
  m_state = WAIT_REPLY;
247
  m_pending.push_back (waiting);
332
  m_pending.push_back (waiting);
248
  UpdateSeen ();
333
  UpdateSeen ();
334
  m_arp->StartWaitReplyTimer ();
249
}
335
}
250
336
251
Address
337
Address
252
ArpCache::Entry::GetMacAddress (void)
338
ArpCache::Entry::GetMacAddress (void) const
253
{
339
{
254
  NS_LOG_FUNCTION_NOARGS ();
340
  NS_LOG_FUNCTION_NOARGS ();
255
  NS_ASSERT (m_state == ALIVE);
341
  NS_ASSERT (m_state == ALIVE);
256
  return m_macAddress;
342
  return m_macAddress;
257
}
343
}
344
Ipv4Address 
345
ArpCache::Entry::GetIpv4Address (void) const
346
{
347
  NS_LOG_FUNCTION_NOARGS ();
348
  return m_ipv4Address;
349
}
350
void 
351
ArpCache::Entry::SetIpv4Address (Ipv4Address destination)
352
{
353
  NS_LOG_FUNCTION (this << destination);
354
  m_ipv4Address = destination;
355
}
356
258
bool 
357
bool 
259
ArpCache::Entry::IsExpired (void)
358
ArpCache::Entry::IsExpired (void)
260
{
359
{
 Lines 307-312   ArpCache::Entry::UpdateSeen (void) Link Here 
307
  NS_LOG_FUNCTION_NOARGS ();
406
  NS_LOG_FUNCTION_NOARGS ();
308
  m_lastSeen = Simulator::Now ();
407
  m_lastSeen = Simulator::Now ();
309
}
408
}
409
uint32_t
410
ArpCache::Entry::GetRetries (void) const
411
{
412
  NS_LOG_FUNCTION_NOARGS ();
413
  return m_retries;
414
}
415
void
416
ArpCache::Entry::IncrementRetries (void)
417
{
418
  NS_LOG_FUNCTION_NOARGS ();
419
  m_retries++;
420
  UpdateSeen ();
421
}
422
void
423
ArpCache::Entry::ClearRetries (void)
424
{
425
  NS_LOG_FUNCTION_NOARGS ();
426
  m_retries = 0;
427
}
310
428
311
} // namespace ns3
429
} // namespace ns3
312
430
(-)a/src/internet-stack/arp-cache.h (-2 / +54 lines)
 Lines 22-27    Link Here 
22
22
23
#include <stdint.h>
23
#include <stdint.h>
24
#include <list>
24
#include <list>
25
#include "ns3/simulator.h"
26
#include "ns3/callback.h"
25
#include "ns3/packet.h"
27
#include "ns3/packet.h"
26
#include "ns3/nstime.h"
28
#include "ns3/nstime.h"
27
#include "ns3/net-device.h"
29
#include "ns3/net-device.h"
 Lines 29-34    Link Here 
29
#include "ns3/address.h"
31
#include "ns3/address.h"
30
#include "ns3/ptr.h"
32
#include "ns3/ptr.h"
31
#include "ns3/object.h"
33
#include "ns3/object.h"
34
#include "ns3/traced-callback.h"
32
#include "sgi-hashmap.h"
35
#include "sgi-hashmap.h"
33
36
34
namespace ns3 {
37
namespace ns3 {
 Lines 72-78   public: Link Here 
72
  Time GetWaitReplyTimeout (void) const;
75
  Time GetWaitReplyTimeout (void) const;
73
76
74
  /**
77
  /**
75
   * \brief Do lookup in the ARP chache against an IP address
78
   * This callback is set when the ArpCache is set up and allows
79
   * the cache to generate an Arp request when the WaitReply
80
   * time expires and a retransmission must be sent
81
   *
82
   * \param arpRequestCallback Callback for transmitting an Arp request.
83
   */
84
  void SetArpRequestCallback (Callback<void, Ptr<const ArpCache>, 
85
                             Ipv4Address> arpRequestCallback);
86
  /**
87
   * This method will schedule a timeout at WaitReplyTimeout interval
88
   * in the future, unless a timer is already running for the cache,
89
   * in which case this method does nothing.
90
   */
91
  void StartWaitReplyTimer (void);
92
  /**
93
   * \brief Do lookup in the ARP cache against an IP address
76
   * \param destination The destination IPv4 address to lookup the MAC address
94
   * \param destination The destination IPv4 address to lookup the MAC address
77
   * of
95
   * of
78
   * \return An ArpCache::Entry with info about layer 2
96
   * \return An ArpCache::Entry with info about layer 2
 Lines 131-137   public: Link Here 
131
    /**
149
    /**
132
     * \return The MacAddress of this entry
150
     * \return The MacAddress of this entry
133
     */
151
     */
134
    Address GetMacAddress (void);
152
    Address GetMacAddress (void) const;
153
    /**
154
     * \return The Ipv4Address for this entry
155
     */
156
    Ipv4Address GetIpv4Address (void) const;
157
    /**
158
     * \param The Ipv4Address for this entry
159
     */
160
    void SetIpv4Address (Ipv4Address destination);
135
    /**
161
    /**
136
     * \return True if this entry has timedout; false otherwise.
162
     * \return True if this entry has timedout; false otherwise.
137
     */
163
     */
 Lines 142-147   public: Link Here 
142
     *            packets are pending.
168
     *            packets are pending.
143
     */
169
     */
144
    Ptr<Packet> DequeuePending (void);
170
    Ptr<Packet> DequeuePending (void);
171
    /**
172
     * \returns number of retries that have been sent for an ArpRequest
173
     *  in WaitReply state.
174
     */
175
    uint32_t GetRetries (void) const;
176
    /**
177
     * \brief Increment the counter of number of retries for an entry
178
     */
179
    void IncrementRetries (void);
180
    /**
181
     * \brief Zero the counter of number of retries for an entry
182
     */
183
    void ClearRetries (void);
184
145
  private:
185
  private:
146
    enum ArpCacheEntryState_e {
186
    enum ArpCacheEntryState_e {
147
      ALIVE,
187
      ALIVE,
 Lines 154-160   public: Link Here 
154
    ArpCacheEntryState_e m_state;
194
    ArpCacheEntryState_e m_state;
155
    Time m_lastSeen;
195
    Time m_lastSeen;
156
    Address m_macAddress;
196
    Address m_macAddress;
197
    Ipv4Address m_ipv4Address;
157
    std::list<Ptr<Packet> > m_pending;
198
    std::list<Ptr<Packet> > m_pending;
199
    uint32_t m_retries;
158
  };
200
  };
159
201
160
private:
202
private:
 Lines 168-175   private: Link Here 
168
  Time m_aliveTimeout;
210
  Time m_aliveTimeout;
169
  Time m_deadTimeout;
211
  Time m_deadTimeout;
170
  Time m_waitReplyTimeout;
212
  Time m_waitReplyTimeout;
213
  EventId m_waitReplyTimer;
214
  Callback<void, Ptr<const ArpCache>, Ipv4Address> m_arpRequestCallback;
215
  uint32_t m_maxRetries;
216
  /**
217
   * This function is an event handler for the event that the
218
   * ArpCache wants to check whether it must retry any Arp requests.
219
   * If there are no Arp requests pending, this event is not scheduled.
220
   */
221
  void HandleWaitReplyTimeout (void);
171
  uint32_t m_pendingQueueSize;
222
  uint32_t m_pendingQueueSize;
172
  Cache m_arpCache;
223
  Cache m_arpCache;
224
  TracedCallback<Ptr<const Packet> > m_dropTrace;
173
};
225
};
174
226
175
227
(-)a/src/internet-stack/arp-l3-protocol.cc (-10 / +2 lines)
 Lines 95-100   ArpL3Protocol::CreateCache (Ptr<NetDevic Link Here 
95
  cache->SetDevice (device, interface);
95
  cache->SetDevice (device, interface);
96
  NS_ASSERT (device->IsBroadcast ());
96
  NS_ASSERT (device->IsBroadcast ());
97
  device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache));
97
  device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache));
98
  cache->SetArpRequestCallback (MakeCallback (&ArpL3Protocol::SendArpRequest, this));
98
  m_cacheList.push_back (cache);
99
  m_cacheList.push_back (cache);
99
  return cache;
100
  return cache;
100
}
101
}
 Lines 218-233   ArpL3Protocol::Lookup (Ptr<Packet> packe Link Here 
218
            } 
219
            } 
219
          else if (entry->IsWaitReply ()) 
220
          else if (entry->IsWaitReply ()) 
220
            {
221
            {
221
              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
222
              NS_FATAL_ERROR ("Test for possibly unreachable code-- please file a bug report if this is ever hit");
222
                        ", wait reply for " << destination << " expired -- drop");
223
              entry->MarkDead ();
224
              Ptr<Packet> pending = entry->DequeuePending();
225
              while (pending != 0)
226
                {
227
                  m_dropTrace (pending);
228
                  pending = entry->DequeuePending();
229
                }
230
              m_dropTrace (packet);
231
            }
223
            }
232
        } 
224
        } 
233
      else 
225
      else 
(-)a/src/internet-stack/arp-l3-protocol.h (-1 / +1 lines)
 Lines 52-58   public: Link Here 
52
  Ptr<ArpCache> CreateCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface);
52
  Ptr<ArpCache> CreateCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface);
53
53
54
  /**
54
  /**
55
   * \brief Recieve a packet
55
   * \brief Receive a packet
56
   */
56
   */
57
  void Receive(Ptr<NetDevice> device, Ptr<Packet> p, uint16_t protocol, const Address &from, const Address &to,
57
  void Receive(Ptr<NetDevice> device, Ptr<Packet> p, uint16_t protocol, const Address &from, const Address &to,
58
               NetDevice::PacketType packetType);
58
               NetDevice::PacketType packetType);

Return to bug 253