plugins/ip-faces: Initial implementation of UdpFace
Refs #1006 (http://redmine.named-data.net/)
diff --git a/model/ndn-l3-protocol.cc b/model/ndn-l3-protocol.cc
index e89c9ea..0c0332f 100644
--- a/model/ndn-l3-protocol.cc
+++ b/model/ndn-l3-protocol.cc
@@ -49,6 +49,7 @@
namespace ndn {
const uint16_t L3Protocol::ETHERNET_FRAME_TYPE = 0x7777;
+const uint16_t L3Protocol::IP_STACK_PORT = 9695;
NS_OBJECT_ENSURE_REGISTERED (L3Protocol);
diff --git a/model/ndn-l3-protocol.h b/model/ndn-l3-protocol.h
index 406e194..552bd19 100644
--- a/model/ndn-l3-protocol.h
+++ b/model/ndn-l3-protocol.h
@@ -74,9 +74,9 @@
*/
static TypeId GetTypeId ();
- static const uint16_t ETHERNET_FRAME_TYPE; ///< \brief Ethernet Frame Type of Ndn
- // static const uint16_t IP_PROTOCOL_TYPE; ///< \brief IP protocol type of Ndn
- // static const uint16_t UDP_PORT; ///< \brief UDP port of Ndn
+ static const uint16_t ETHERNET_FRAME_TYPE; ///< @brief Ethernet Frame Type of Ndn
+ static const uint16_t IP_STACK_PORT; ///< @brief TCP/UDP port for NDN stack
+ // static const uint16_t IP_PROTOCOL_TYPE; ///< \brief IP protocol type of NDN
/**
* \brief Default constructor. Creates an empty stack without forwarding strategy set
diff --git a/plugins/ip-faces/ndn-ip-face-stack.cc b/plugins/ip-faces/ndn-ip-face-stack.cc
index 94faea4..cbb5e24 100644
--- a/plugins/ip-faces/ndn-ip-face-stack.cc
+++ b/plugins/ip-faces/ndn-ip-face-stack.cc
@@ -38,8 +38,6 @@
NS_OBJECT_ENSURE_REGISTERED (IpFaceStack);
-const uint16_t NDN_IP_STACK_PORT = 9695;
-
TypeId
IpFaceStack::GetTypeId (void)
{
@@ -53,10 +51,10 @@
MakeBooleanAccessor (&IpFaceStack::m_enableTcp),
MakeBooleanChecker ())
- // .AddAttribute ("EnableUDP", "Enable ability to create UDP faces",
- // BooleanValue (true),
- // MakeBooleanAccessor (&IpFaceStack::m_enableUdp),
- // MakeBooleanChecker ())
+ .AddAttribute ("EnableUDP", "Enable ability to create UDP faces",
+ BooleanValue (true),
+ MakeBooleanAccessor (&IpFaceStack::m_enableUdp),
+ MakeBooleanChecker ())
;
return tid;
}
@@ -92,12 +90,20 @@
{
m_tcpServer = Socket::CreateSocket (m_node, TcpSocketFactory::GetTypeId ());
- m_tcpServer->Bind (InetSocketAddress (Ipv4Address::GetAny (), NDN_IP_STACK_PORT));
+ m_tcpServer->Bind (InetSocketAddress (Ipv4Address::GetAny (), L3Protocol::IP_STACK_PORT));
m_tcpServer->Listen ();
m_tcpServer->SetAcceptCallback (MakeCallback (&IpFaceStack::OnTcpConnectionRequest, this),
MakeCallback (&IpFaceStack::OnTcpConnectionAccept, this));
+ }
+ if (m_enableUdp)
+ {
+ // m_udpServer = Socket::CreateSocket (m_node, UdpSocketFactory::GetTypeId ());
+ // m_udpServer->Bind (InetSocketAddress (Ipv4Address::GetAny (), L3Protocol::IP_STACK_PORT));
+
+ // m_udpServer->SetRecvCallback (MakeCallback (&IpFaceStack::HandleRead, this));
+ // #error "Broken"
}
}
diff --git a/plugins/ip-faces/ndn-ip-face-stack.h b/plugins/ip-faces/ndn-ip-face-stack.h
index 83cf4cb..bf15b3e 100644
--- a/plugins/ip-faces/ndn-ip-face-stack.h
+++ b/plugins/ip-faces/ndn-ip-face-stack.h
@@ -76,9 +76,10 @@
Ptr<Node> m_node;
bool m_enableTcp;
- // bool m_enableUdp;
+ bool m_enableUdp;
Ptr<Socket> m_tcpServer;
+ Ptr<Socket> m_udpServer;
};
} // namespace ndn
diff --git a/plugins/ip-faces/ndn-tcp-face.cc b/plugins/ip-faces/ndn-tcp-face.cc
index c1d9321..4ef8908 100644
--- a/plugins/ip-faces/ndn-tcp-face.cc
+++ b/plugins/ip-faces/ndn-tcp-face.cc
@@ -37,8 +37,6 @@
namespace ns3 {
namespace ndn {
-const uint16_t NDN_IP_STACK_PORT = 9695;
-
TcpFace::FaceMap TcpFace::s_map;
class TcpBoundaryHeader : public Header
@@ -262,7 +260,7 @@
socket->SetConnectCallback (MakeCallback (&TcpFace::OnConnect, face),
MakeNullCallback< void, Ptr< Socket > > ());
- socket->Connect (InetSocketAddress (address, NDN_IP_STACK_PORT));
+ socket->Connect (InetSocketAddress (address, L3Protocol::IP_STACK_PORT));
s_map.insert (std::make_pair (address, face));
@@ -286,7 +284,7 @@
std::ostream&
TcpFace::Print (std::ostream& os) const
{
- os << "dev=tcp(" << GetId () << ")";
+ os << "dev=tcp(" << GetId () << ", " << m_address << ")";
return os;
}
diff --git a/plugins/ip-faces/ndn-udp-face.cc b/plugins/ip-faces/ndn-udp-face.cc
new file mode 100644
index 0000000..4ebff28
--- /dev/null
+++ b/plugins/ip-faces/ndn-udp-face.cc
@@ -0,0 +1,161 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *
+ */
+
+#include "ndn-udp-face.h"
+#include "ns3/ndn-l3-protocol.h"
+
+#include "ns3/log.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/pointer.h"
+#include "ns3/tcp-socket-factory.h"
+
+#include "ns3/ndn-name.h"
+
+using namespace std;
+
+NS_LOG_COMPONENT_DEFINE ("ndn.UdpFace");
+
+namespace ns3 {
+namespace ndn {
+
+UdpFace::FaceMap UdpFace::s_map;
+
+NS_OBJECT_ENSURE_REGISTERED (UdpFace);
+
+TypeId
+UdpFace::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::ndn::UdpFace")
+ .SetParent<Face> ()
+ .SetGroupName ("Ndn")
+ ;
+ return tid;
+}
+
+/**
+ * By default, Ndn face are created in the "down" state. Before
+ * becoming useable, the user must invoke SetUp on the face
+ */
+UdpFace::UdpFace (Ptr<Node> node, Ptr<Socket> socket, Ipv4Address address)
+ : Face (node)
+ , m_socket (socket)
+ , m_address (address)
+{
+ SetMetric (1); // default metric
+}
+
+UdpFace::~UdpFace ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+UdpFace& UdpFace::operator= (const UdpFace &)
+{
+ return *this;
+}
+
+void
+UdpFace::RegisterProtocolHandler (ProtocolHandler handler)
+{
+ NS_LOG_FUNCTION (this);
+
+ Face::RegisterProtocolHandler (handler);
+
+ m_socket->SetRecvCallback (MakeCallback (&UdpFace::ReceiveFromUdp, this));
+}
+
+bool
+UdpFace::SendImpl (Ptr<Packet> packet)
+{
+ NS_LOG_FUNCTION (this << packet);
+ Ptr<Packet> boundary = Create<Packet> ();
+ TcpBoundaryHeader hdr (packet);
+ boundary->AddHeader (hdr);
+
+ m_socket->Send (boundary);
+ m_socket->Send (packet);
+
+ return true;
+}
+
+void
+UdpFace::ReceiveFromUdp (Ptr< Socket > clientSocket)
+{
+ NS_LOG_FUNCTION (this << clientSocket);
+
+ Ptr<Packet> packet;
+ Address from;
+ while ((packet = socket->RecvFrom (from)))
+ {
+ Receive (realPacket);
+ }
+ }
+}
+
+Ipv4Address
+UdpFace::GetAddress () const
+{
+ return m_address;
+}
+
+Ptr<UdpFace>
+UdpFace::GetFaceByAddress (const Ipv4Address &address)
+{
+ FaceMap::iterator i = s_map.find (address);
+ if (i != s_map.end ())
+ return i->second;
+ else
+ return 0;
+}
+
+Ptr<UdpFace>
+UdpFace::CreateOrGetFace (Ptr<Node> node, Ipv4Address address)
+{
+ NS_LOG_FUNCTION (address);
+
+ FaceMap::iterator i = s_map.find (address);
+ if (i != s_map.end ())
+ return i->second;
+
+ Ptr<Socket> socket = Socket::CreateSocket (node, UdpSocketFactory::GetTypeId ());
+ Ptr<UdpFace> face = CreateObject<UdpFace> (node, socket, address);
+
+ Ptr<L3Protocol> ndn = GetNode ()->GetObject<L3Protocol> ();
+
+ ndn->AddFace (this);
+ this->SetUp (true);
+
+ s_map.insert (std::make_pair (address, face));
+
+ return face;
+}
+
+std::ostream&
+UdpFace::Print (std::ostream& os) const
+{
+ os << "dev=udp(" << GetId () << ")";
+ return os;
+}
+
+} // namespace ndn
+} // namespace ns3
+
diff --git a/plugins/ip-faces/ndn-udp-face.h b/plugins/ip-faces/ndn-udp-face.h
new file mode 100644
index 0000000..54f5fe3
--- /dev/null
+++ b/plugins/ip-faces/ndn-udp-face.h
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_UDP_FACE_H
+#define NDN_UDP_FACE_H
+
+#include "ns3/ndn-face.h"
+#include "ns3/socket.h"
+#include "ns3/ptr.h"
+
+#include <map>
+
+namespace ns3 {
+namespace ndn {
+
+/**
+ * \ingroup ndn-face
+ * \brief Implementation of UDP/IP NDN face
+ *
+ * \see ndn::AppFace, ndn::NetDeviceFace, ndn::Ipv4Face, ndn::TcpFace
+ */
+class UdpFace : public Face
+{
+public:
+ static TypeId
+ GetTypeId ();
+
+ /**
+ * @brief A singleton method allowing creation and lookup of faces
+ *
+ * All created UDP faces are stored internally in the map, and if the same face is created, it will simply be looked up
+ */
+ static Ptr<UdpFace>
+ CreateOrGetFace (Ptr<Node> node, Ipv4Address address);
+
+ /**
+ * \brief Constructor
+ *
+ * @param node Node associated with the face
+ */
+ UdpFace (Ptr<Node> node, Ptr<Socket> socket, Ipv4Address address);
+ virtual ~UdpFace();
+
+ ////////////////////////////////////////////////////////////////////
+ // methods overloaded from NdnFace
+ virtual void
+ RegisterProtocolHandler (ProtocolHandler handler);
+
+ Ipv4Address
+ GetAddress () const;
+
+ static Ptr<UdpFace>
+ GetFaceByAddress (const Ipv4Address &addr);
+
+protected:
+ // also from NdnFace
+ virtual bool
+ SendImpl (Ptr<Packet> p);
+
+public:
+ /**
+ * @brief Print out name of the NdnFace to the stream
+ */
+ virtual std::ostream&
+ Print (std::ostream &os) const;
+ ////////////////////////////////////////////////////////////////////
+
+private:
+ UdpFace (const UdpFace &); ///< \brief Disabled copy constructor
+ UdpFace& operator= (const UdpFace &); ///< \brief Disabled copy operator
+
+ void
+ ReceiveFromUdp (Ptr< Socket > clientSocket);
+
+private:
+ Ptr<Socket> m_socket;
+ Ipv4Address m_address;
+
+ typedef std::map<Ipv4Address, Ptr<UdpFace> > FaceMap;
+ static FaceMap s_map;
+};
+
+} // namespace ndn
+} // namespace ns3
+
+#endif // NDN_UDP_FACE_H