plugins/ip-faces: Updating TcpFace implementation
In addition to changes to follow latest API changes in ndnSIM, the
helper ndn::IpFacesHelper allows scheduling TcpFace creation at specific
point of simulation.
Refs #1006 (http://redmine.named-data.net/)
diff --git a/examples/ndn-simple-tcp.cc b/examples/ndn-simple-tcp.cc
index 641348a..f959dc7 100644
--- a/examples/ndn-simple-tcp.cc
+++ b/examples/ndn-simple-tcp.cc
@@ -97,9 +97,8 @@
Ipv4Address ("10.1.2.1"),
1, 1);
- ndn::IpFacesHelper ipFacesHelper;
- ipFacesHelper.InstallAll ();
- ipFacesHelper.CreateTcpFace (nodes.Get (0), Ipv4Address ("10.1.2.2"), "/tcp-route");
+ ndn::IpFacesHelper::InstallAll ();
+ ndn::IpFacesHelper::CreateTcpFace (Seconds (1.0), nodes.Get (0), Ipv4Address ("10.1.2.2"), "/tcp-route");
// Installing applications
diff --git a/plugins/ip-faces/ndn-ip-face-stack.cc b/plugins/ip-faces/ndn-ip-face-stack.cc
index cbb5e24..89839ba 100644
--- a/plugins/ip-faces/ndn-ip-face-stack.cc
+++ b/plugins/ip-faces/ndn-ip-face-stack.cc
@@ -26,6 +26,7 @@
#include "ns3/log.h"
#include "ns3/assert.h"
#include "ns3/packet.h"
+#include "ns3/boolean.h"
#include "ns3/socket.h"
#include "ns3/tcp-socket-factory.h"
diff --git a/plugins/ip-faces/ndn-ip-faces-helper.cc b/plugins/ip-faces/ndn-ip-faces-helper.cc
index efd956f..4d64268 100644
--- a/plugins/ip-faces/ndn-ip-faces-helper.cc
+++ b/plugins/ip-faces/ndn-ip-faces-helper.cc
@@ -60,25 +60,45 @@
}
-static void
-CreateTcpFaceStep2 (Ptr<Node> node, Ipv4Address address, const std::string &prefix)
+struct TcpPrefixRegistrator : SimpleRefCount<TcpPrefixRegistrator>
{
- Ptr<Face> face = TcpFace::CreateOrGetFace (node, address);
- ndn::StackHelper::AddRoute (node, prefix, face, 1);
-}
+ TcpPrefixRegistrator (Ptr<Node> node, const std::string &prefix, int16_t metric)
+ : m_node (node)
+ , m_prefix (prefix)
+ , m_metric (metric)
+ {
+ }
+
+ void
+ Run (Ptr<Face> face)
+ {
+ ndn::StackHelper::AddRoute (m_node, m_prefix, face, m_metric);
+ }
+private:
+ Ptr<Node> m_node;
+ std::string m_prefix;
+ int16_t m_metric;
+};
static void
-CreateTcpFaceStep1 (Ptr<Node> node, Ipv4Address address, const std::string &prefix)
+ScheduledCreateTcp (Ptr<Node> node, Ipv4Address address, const std::string &prefix, int16_t metric)
{
- TcpFace::CreateOrGetFace (node, address);
-
- Simulator::ScheduleWithContext (node->GetId (), Seconds (1.0), CreateTcpFaceStep2, node, address, prefix);
+ Ptr<Face> face = TcpFace::GetFaceByAddress (address);
+ if (face == 0)
+ {
+ Ptr<TcpPrefixRegistrator> registrator = Create<TcpPrefixRegistrator> (node, prefix, metric);
+ TcpFace::CreateOrGetFace (node, address, MakeCallback (&TcpPrefixRegistrator::Run, registrator));
+ }
+ else
+ {
+ ndn::StackHelper::AddRoute (node, prefix, face, metric);
+ }
}
void
-IpFacesHelper::CreateTcpFace (Ptr<Node> node, Ipv4Address address, const std::string &prefix)
+IpFacesHelper::CreateTcpFace (const Time &when, Ptr<Node> node, Ipv4Address address, const std::string &prefix, int16_t metric/* = 1*/)
{
- Simulator::ScheduleWithContext (node->GetId (), Seconds (1.0), CreateTcpFaceStep1, node, address, prefix);
+ Simulator::ScheduleWithContext (node->GetId (), when, ScheduledCreateTcp, node, address, prefix, metric);
}
diff --git a/plugins/ip-faces/ndn-ip-faces-helper.h b/plugins/ip-faces/ndn-ip-faces-helper.h
index 3ea8859..d5d6d9c 100644
--- a/plugins/ip-faces/ndn-ip-faces-helper.h
+++ b/plugins/ip-faces/ndn-ip-faces-helper.h
@@ -23,6 +23,7 @@
#define NDN_IP_FACES_HELPER_H
#include "ns3/ptr.h"
+#include "ns3/nstime.h"
#include "ns3/ipv4-address.h"
namespace ns3 {
@@ -44,27 +45,38 @@
* @brief Install IpFaceStack interface on a node
* @param node Node to install IpFaceStack interface
*/
- void
+ static void
Install (Ptr<Node> node);
/**
* @brief Install IpFaceStack interface on nodes
* @param nodes NodeContainer to install IpFaceStack interface
*/
- void
+ static void
Install (const NodeContainer &nodes);
/**
* @brief Install IpFaceStack interface on all nodes
*/
- void
+ static void
InstallAll ();
/**
* @brief Create TCP face
+ * @param when Time when to create face (use `Seconds (0)' if face should be created right away)
+ * @param node Node to add TCP face (will initiate connection)
+ * @param address IP address to connect (using standard 9695 port)
+ * @param prefix Prefix to associate with the face
+ * @param metric Metric that will be assigned to the face
+ *
+ * This call schedules connection initiation and after successful connection it will add new face
+ * to NDN stack and add the requested route
+ *
+ * If face has been already created before (same IP address), then this call will simply
+ * update FIB with requested prefix
*/
- void
- CreateTcpFace (Ptr<Node> node, Ipv4Address address, const std::string &prefix);
+ static void
+ CreateTcpFace (const Time &when, Ptr<Node> node, Ipv4Address address, const std::string &prefix, int16_t metric = 1);
};
} // namespace ndn
diff --git a/plugins/ip-faces/ndn-tcp-face.cc b/plugins/ip-faces/ndn-tcp-face.cc
index 4ef8908..68a7d08 100644
--- a/plugins/ip-faces/ndn-tcp-face.cc
+++ b/plugins/ip-faces/ndn-tcp-face.cc
@@ -110,6 +110,8 @@
NS_OBJECT_ENSURE_REGISTERED (TcpFace);
+const Callback< void, Ptr<Face> > TcpFace::NULL_CREATE_CALLBACK = MakeNullCallback< void, Ptr<Face> > ();
+
TypeId
TcpFace::GetTypeId ()
{
@@ -144,19 +146,31 @@
}
void
-TcpFace::RegisterProtocolHandler (ProtocolHandler handler)
+TcpFace::RegisterProtocolHandlers (const InterestHandler &interestHandler, const DataHandler &dataHandler)
{
NS_LOG_FUNCTION (this);
- Face::RegisterProtocolHandler (handler);
-
+ Face::RegisterProtocolHandlers (interestHandler, dataHandler);
m_socket->SetRecvCallback (MakeCallback (&TcpFace::ReceiveFromTcp, this));
}
-bool
-TcpFace::SendImpl (Ptr<Packet> packet)
+void
+TcpFace:: UnRegisterProtocolHandlers ()
{
+ m_socket->SetRecvCallback (MakeNullCallback< void, Ptr<Socket> > ());
+ Face::UnRegisterProtocolHandlers ();
+}
+
+bool
+TcpFace::Send (Ptr<Packet> packet)
+{
+ if (!Face::Send (packet))
+ {
+ return false;
+ }
+
NS_LOG_FUNCTION (this << packet);
+
Ptr<Packet> boundary = Create<Packet> ();
TcpBoundaryHeader hdr (packet);
boundary->AddHeader (hdr);
@@ -247,7 +261,7 @@
}
Ptr<TcpFace>
-TcpFace::CreateOrGetFace (Ptr<Node> node, Ipv4Address address)
+TcpFace::CreateOrGetFace (Ptr<Node> node, Ipv4Address address, Callback< void, Ptr<Face> > onCreate)
{
NS_LOG_FUNCTION (address);
@@ -257,6 +271,8 @@
Ptr<Socket> socket = Socket::CreateSocket (node, TcpSocketFactory::GetTypeId ());
Ptr<TcpFace> face = CreateObject<TcpFace> (node, socket, address);
+
+ face->SetCreateCallback (onCreate);
socket->SetConnectCallback (MakeCallback (&TcpFace::OnConnect, face),
MakeNullCallback< void, Ptr< Socket > > ());
@@ -268,6 +284,12 @@
}
void
+TcpFace::SetCreateCallback (Callback< void, Ptr<Face> > callback)
+{
+ m_onCreateCallback = callback;
+}
+
+void
TcpFace::OnConnect (Ptr<Socket> socket)
{
NS_LOG_FUNCTION (this << socket);
@@ -279,6 +301,12 @@
socket->SetCloseCallbacks (MakeCallback (&TcpFace::OnTcpConnectionClosed, this),
MakeCallback (&TcpFace::OnTcpConnectionClosed, this));
+
+ if (!m_onCreateCallback.IsNull ())
+ {
+ m_onCreateCallback (this);
+ m_onCreateCallback = NULL_CREATE_CALLBACK;
+ }
}
std::ostream&
diff --git a/plugins/ip-faces/ndn-tcp-face.h b/plugins/ip-faces/ndn-tcp-face.h
index 6e9763e..8b4a90c 100644
--- a/plugins/ip-faces/ndn-tcp-face.h
+++ b/plugins/ip-faces/ndn-tcp-face.h
@@ -24,6 +24,7 @@
#include "ns3/ndn-face.h"
#include "ns3/socket.h"
#include "ns3/ptr.h"
+#include "ns3/callback.h"
#include <map>
@@ -48,7 +49,8 @@
* All created TCP faces are stored internally in the map, and if the same face is created, it will simply be looked up
*/
static Ptr<TcpFace>
- CreateOrGetFace (Ptr<Node> node, Ipv4Address address);
+ CreateOrGetFace (Ptr<Node> node, Ipv4Address address,
+ Callback< void, Ptr<Face> > onCreate = NULL_CREATE_CALLBACK);
/**
* \brief Constructor
@@ -59,9 +61,12 @@
virtual ~TcpFace();
////////////////////////////////////////////////////////////////////
- // methods overloaded from NdnFace
+ // methods overloaded from ndn::Face
virtual void
- RegisterProtocolHandler (ProtocolHandler handler);
+ RegisterProtocolHandlers (const InterestHandler &interestHandler, const DataHandler &dataHandler);
+
+ virtual void
+ UnRegisterProtocolHandlers ();
void
OnTcpConnectionClosed (Ptr<Socket> socket);
@@ -72,14 +77,19 @@
static Ptr<TcpFace>
GetFaceByAddress (const Ipv4Address &addr);
+ void
+ SetCreateCallback (Callback< void, Ptr<Face> > callback);
+
+public:
+ const static Callback< void, Ptr<Face> > NULL_CREATE_CALLBACK;
private:
void
OnConnect (Ptr<Socket> socket);
protected:
- // also from NdnFace
+ // also from ndn::Face
virtual bool
- SendImpl (Ptr<Packet> p);
+ Send (Ptr<Packet> p);
public:
/**
@@ -100,6 +110,7 @@
Ptr<Socket> m_socket;
Ipv4Address m_address;
uint32_t m_pendingPacketLength;
+ Callback< void, Ptr<Face> > m_onCreateCallback;
typedef std::map<Ipv4Address, Ptr<TcpFace> > FaceMap;
static FaceMap s_map;