--- a/src/internet-node/arp-cache.cc Sun May 25 14:44:14 2008 -0700
+++ b/src/internet-node/arp-cache.cc Sun May 25 14:44:36 2008 -0700
@@ -20,11 +20,15 @@
#include "ns3/assert.h"
#include "ns3/packet.h"
#include "ns3/simulator.h"
+#include "ns3/uinteger.h"
+#include "ns3/log.h"
#include "arp-cache.h"
#include "arp-header.h"
#include "ipv4-interface.h"
+NS_LOG_COMPONENT_DEFINE ("ArpCache");
+
namespace ns3 {
TypeId
@@ -47,6 +51,11 @@
TimeValue (Seconds (1)),
MakeTimeAccessor (&ArpCache::m_waitReplyTimeout),
MakeTimeChecker ())
+ .AddAttribute ("PendingQueueSize",
+ "The size of the queue for packets pending an arp reply.",
+ UintegerValue (3),
+ MakeUintegerAccessor (&ArpCache::m_pendingQueueSize),
+ MakeUintegerChecker<uint32_t> ())
;
return tid;
}
@@ -54,11 +63,23 @@
ArpCache::ArpCache ()
: m_device (0),
m_interface (0)
-{}
+{
+ NS_LOG_FUNCTION (this);
+}
ArpCache::~ArpCache ()
{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+ArpCache::DoDispose (void)
+{
+ NS_LOG_FUNCTION (this);
Flush ();
+ m_device = 0;
+ m_interface = 0;
+ Object::DoDispose ();
}
void
@@ -145,8 +166,7 @@
ArpCache::Entry::Entry (ArpCache *arp)
: m_arp (arp),
- m_state (ALIVE),
- m_waiting ()
+ m_state (ALIVE)
{}
@@ -171,23 +191,18 @@
ArpCache::Entry::MarkDead (void)
{
m_state = DEAD;
- //NS_ASSERT (m_waiting != 0);
UpdateSeen ();
}
-Ptr<Packet>
+void
ArpCache::Entry::MarkAlive (Address macAddress)
{
NS_ASSERT (m_state == WAIT_REPLY);
- //NS_ASSERT (m_waiting != 0);
m_macAddress = macAddress;
m_state = ALIVE;
UpdateSeen ();
- Ptr<Packet> waiting = m_waiting;
- //m_waiting = 0;
- return waiting;
}
-Ptr<Packet>
+bool
ArpCache::Entry::UpdateWaitReply (Ptr<Packet> waiting)
{
NS_ASSERT (m_state == WAIT_REPLY);
@@ -195,17 +210,20 @@
* we dump the previously waiting packet and
* replace it with this one.
*/
- Ptr<Packet> old = m_waiting;
- m_waiting = waiting;
- return old;
+ if (m_pending.size () >= m_arp->m_pendingQueueSize)
+ {
+ return false;
+ }
+ m_pending.push_back (waiting);
+ return true;
}
void
ArpCache::Entry::MarkWaitReply (Ptr<Packet> waiting)
{
NS_ASSERT (m_state == ALIVE || m_state == DEAD);
- //NS_ASSERT (m_waiting == 0);
+ NS_ASSERT (m_pending.empty ());
m_state = WAIT_REPLY;
- m_waiting = waiting;
+ m_pending.push_back (waiting);
UpdateSeen ();
}
@@ -245,6 +263,20 @@
return false;
}
}
+Ptr<Packet>
+ArpCache::Entry::DequeuePending (void)
+{
+ if (m_pending.empty ())
+ {
+ return 0;
+ }
+ else
+ {
+ Ptr<Packet> p = m_pending.front ();
+ m_pending.pop_front ();
+ return p;
+ }
+}
void
ArpCache::Entry::UpdateSeen (void)
{
--- a/src/internet-node/arp-cache.h Sun May 25 14:44:14 2008 -0700
+++ b/src/internet-node/arp-cache.h Sun May 25 14:44:36 2008 -0700
@@ -21,6 +21,7 @@
#define ARP_CACHE_H
#include <stdint.h>
+#include <list>
#include "ns3/packet.h"
#include "ns3/nstime.h"
#include "ns3/net-device.h"
@@ -103,9 +104,8 @@
void MarkDead (void);
/**
* \param macAddress
- * \return
*/
- Ptr<Packet> MarkAlive (Address macAddress);
+ void MarkAlive (Address macAddress);
/**
* \param waiting
*/
@@ -114,7 +114,7 @@
* \param waiting
* \return
*/
- Ptr<Packet> UpdateWaitReply (Ptr<Packet> waiting);
+ bool UpdateWaitReply (Ptr<Packet> waiting);
/**
* \return True if the state of this entry is dead; false otherwise.
*/
@@ -136,6 +136,12 @@
* \return True if this entry has timedout; false otherwise.
*/
bool IsExpired (void);
+
+ /**
+ * \returns 0 is no packet is pending, the next packet to send if
+ * packets are pending.
+ */
+ Ptr<Packet> DequeuePending (void);
private:
enum ArpCacheEntryState_e {
ALIVE,
@@ -148,18 +154,21 @@
ArpCacheEntryState_e m_state;
Time m_lastSeen;
Address m_macAddress;
- Ptr<Packet> m_waiting;
+ std::list<Ptr<Packet> > m_pending;
};
private:
typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash> Cache;
typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash>::iterator CacheI;
+ virtual void DoDispose (void);
+
Ptr<NetDevice> m_device;
Ptr<Ipv4Interface> m_interface;
Time m_aliveTimeout;
Time m_deadTimeout;
Time m_waitReplyTimeout;
+ uint32_t m_pendingQueueSize;
Cache m_arpCache;
};
--- a/src/internet-node/arp-l3-protocol.cc Sun May 25 14:44:14 2008 -0700
+++ b/src/internet-node/arp-l3-protocol.cc Sun May 25 14:44:36 2008 -0700
@@ -53,12 +53,12 @@
ArpL3Protocol::ArpL3Protocol ()
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (this);
}
ArpL3Protocol::~ArpL3Protocol ()
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (this);
}
void
@@ -70,7 +70,12 @@
void
ArpL3Protocol::DoDispose (void)
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (this);
+ for (CacheList::iterator i = m_cacheList.begin (); i != m_cacheList.end (); ++i)
+ {
+ Ptr<ArpCache> cache = *i;
+ cache->Dispose ();
+ }
m_cacheList.clear ();
m_node = 0;
Object::DoDispose ();
@@ -145,8 +150,17 @@
arp.GetSourceIpv4Address ()
<< " for waiting entry -- flush");
Address from_mac = arp.GetSourceHardwareAddress ();
- Ptr<Packet> waiting = entry->MarkAlive (from_mac);
- cache->GetInterface ()->Send (waiting, arp.GetSourceIpv4Address ());
+ entry->MarkAlive (from_mac);
+ while (true)
+ {
+ Ptr<Packet> pending = entry->DequeuePending();
+ if (pending != 0)
+ {
+ break;
+ }
+ cache->GetInterface ()->Send (pending,
+ arp.GetSourceIpv4Address ());
+ }
}
else
{
@@ -210,25 +224,24 @@
if (entry->IsDead ())
{
NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
- ", dead entry for " << destination << " valid -- drop");
+ ", dead entry for " << destination << " valid -- drop");
// XXX report packet as 'dropped'
}
else if (entry->IsAlive ())
{
NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
- ", alive entry for " << destination << " valid -- send");
+ ", alive entry for " << destination << " valid -- send");
*hardwareDestination = entry->GetMacAddress ();
return true;
}
else if (entry->IsWaitReply ())
{
NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
- ", wait reply for " << destination << " valid -- drop previous");
- Ptr<Packet> old = entry->UpdateWaitReply (packet);
- // XXX report 'old' packet as 'dropped'
+ ", wait reply for " << destination << " valid -- drop previous");
+ // XXX potentially report current packet as 'dropped'
+ entry->UpdateWaitReply (packet);
}
}
-
}
else
{