NS-3 based Named Data Networking (NDN) simulator
ndnSIM: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
ndn-tcp-face.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2013 University of California, Los Angeles
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19  *
20  */
21 
22 #include "ndn-tcp-face.h"
23 #include "ndn-ip-face-stack.h"
24 
25 #include "ns3/ndn-l3-protocol.h"
26 
27 #include "ns3/log.h"
28 #include "ns3/packet.h"
29 #include "ns3/node.h"
30 #include "ns3/pointer.h"
31 #include "ns3/tcp-socket-factory.h"
32 
33 #include "ns3/ndn-name.h"
34 
35 using namespace std;
36 
37 NS_LOG_COMPONENT_DEFINE ("ndn.TcpFace");
38 
39 namespace ns3 {
40 namespace ndn {
41 
42 class TcpBoundaryHeader : public Header
43 {
44 public:
45  static TypeId GetTypeId (void)
46  {
47  static TypeId tid = TypeId ("ns3::ndn::TcpFace::BoundaryHeader")
48  .SetGroupName ("Ndn")
49  .SetParent<Header> ()
50  ;
51  return tid;
52  }
53 
55  : m_length (0)
56  {
57  }
58 
59  TcpBoundaryHeader (Ptr<Packet> packet)
60  : m_length (packet->GetSize ())
61  {
62 
63  }
64 
65  TcpBoundaryHeader (uint32_t length)
66  : m_length (length)
67  {
68  }
69 
70  uint32_t
71  GetLength () const
72  {
73  return m_length;
74  }
75 
76  virtual TypeId
77  GetInstanceTypeId (void) const
78  {
79  return TcpBoundaryHeader::GetTypeId ();
80  }
81 
82  virtual void
83  Print (std::ostream &os) const
84  {
85  os << "[" << m_length << "]";
86  }
87 
88  virtual uint32_t
89  GetSerializedSize (void) const
90  {
91  return 4;
92  }
93 
94  virtual void
95  Serialize (Buffer::Iterator start) const
96  {
97  start.WriteU32 (m_length);
98  }
99 
100  virtual uint32_t
101  Deserialize (Buffer::Iterator start)
102  {
103  m_length = start.ReadU32 ();
104  return 4;
105  }
106 
107 private:
108  uint32_t m_length;
109 };
110 
111 NS_OBJECT_ENSURE_REGISTERED (TcpFace);
112 
113 TypeId
114 TcpFace::GetTypeId ()
115 {
116  static TypeId tid = TypeId ("ns3::ndn::TcpFace")
117  .SetParent<Face> ()
118  .SetGroupName ("Ndn")
119  ;
120  return tid;
121 }
122 
127 TcpFace::TcpFace (Ptr<Node> node, Ptr<Socket> socket, Ipv4Address address)
128  : Face (node)
129  , m_socket (socket)
130  , m_address (address)
131  , m_pendingPacketLength (0)
132 {
133  SetMetric (1); // default metric
134 }
135 
136 TcpFace::~TcpFace ()
137 {
138  NS_LOG_FUNCTION_NOARGS ();
139 }
140 
141 TcpFace& TcpFace::operator= (const TcpFace &)
142 {
143  return *this;
144 }
145 
146 void
147 TcpFace::RegisterProtocolHandlers (const InterestHandler &interestHandler, const DataHandler &dataHandler)
148 {
149  NS_LOG_FUNCTION (this);
150 
151  Face::RegisterProtocolHandlers (interestHandler, dataHandler);
152  m_socket->SetRecvCallback (MakeCallback (&TcpFace::ReceiveFromTcp, this));
153 }
154 
155 void
157 {
158  m_socket->SetRecvCallback (MakeNullCallback< void, Ptr<Socket> > ());
160 }
161 
162 bool
163 TcpFace::Send (Ptr<Packet> packet)
164 {
165  if (!Face::Send (packet))
166  {
167  return false;
168  }
169 
170  NS_LOG_FUNCTION (this << packet);
171 
172  Ptr<Packet> boundary = Create<Packet> ();
173  TcpBoundaryHeader hdr (packet);
174  boundary->AddHeader (hdr);
175 
176  m_socket->Send (boundary);
177  m_socket->Send (packet);
178 
179  return true;
180 }
181 
182 void
183 TcpFace::ReceiveFromTcp (Ptr< Socket > clientSocket)
184 {
185  NS_LOG_FUNCTION (this << clientSocket);
186  TcpBoundaryHeader hdr;
187 
188  if (m_pendingPacketLength > 0)
189  {
190  if (clientSocket->GetRxAvailable () >= m_pendingPacketLength)
191  {
192  Ptr<Packet> realPacket = clientSocket->Recv (m_pendingPacketLength, 0);
193  NS_LOG_DEBUG ("+++ Expected " << m_pendingPacketLength << " bytes, got " << realPacket->GetSize () << " bytes");
194  if (realPacket == 0)
195  return;
196 
197  Receive (realPacket);
198  }
199  else
200  return; // still not ready
201  }
202 
203  m_pendingPacketLength = 0;
204 
205  while (clientSocket->GetRxAvailable () >= hdr.GetSerializedSize ())
206  {
207  Ptr<Packet> boundary = clientSocket->Recv (hdr.GetSerializedSize (), 0);
208  if (boundary == 0)
209  return; // no idea why it would happen...
210 
211  NS_LOG_DEBUG ("Expected 4 bytes, got " << boundary->GetSize () << " bytes");
212 
213  boundary->RemoveHeader (hdr);
214  NS_LOG_DEBUG ("Header specifies length: " << hdr.GetLength ());
215  m_pendingPacketLength = hdr.GetLength ();
216 
217  if (clientSocket->GetRxAvailable () >= hdr.GetLength ())
218  {
219  Ptr<Packet> realPacket = clientSocket->Recv (hdr.GetLength (), 0);
220  if (realPacket == 0)
221  {
222  NS_LOG_DEBUG ("Got nothing, but requested at least " << hdr.GetLength ());
223  return;
224  }
225 
226  NS_LOG_DEBUG ("Receiving data " << hdr.GetLength () << " bytes, got " << realPacket->GetSize () << " bytes");
227 
228  Receive (realPacket);
229  m_pendingPacketLength = 0;
230  }
231  else
232  {
233  return;
234  }
235  }
236 }
237 
238 void
239 TcpFace::OnTcpConnectionClosed (Ptr<Socket> socket)
240 {
241  NS_LOG_FUNCTION (this << socket);
242  GetNode ()->GetObject<IpFaceStack> ()->DestroyTcpFace (this);
243 }
244 
245 Ipv4Address
246 TcpFace::GetAddress () const
247 {
248  return m_address;
249 }
250 
251 void
252 TcpFace::SetCreateCallback (Callback< void, Ptr<Face> > callback)
253 {
254  m_onCreateCallback = callback;
255 }
256 
257 void
258 TcpFace::OnConnect (Ptr<Socket> socket)
259 {
260  NS_LOG_FUNCTION (this << socket);
261 
262  Ptr<L3Protocol> ndn = GetNode ()->GetObject<L3Protocol> ();
263 
264  ndn->AddFace (this);
265  this->SetUp (true);
266 
267  socket->SetCloseCallbacks (MakeCallback (&TcpFace::OnTcpConnectionClosed, this),
268  MakeCallback (&TcpFace::OnTcpConnectionClosed, this));
269 
270  if (!m_onCreateCallback.IsNull ())
271  {
272  m_onCreateCallback (this);
273  m_onCreateCallback = IpFaceStack::NULL_CREATE_CALLBACK;
274  }
275 }
276 
277 std::ostream&
278 TcpFace::Print (std::ostream& os) const
279 {
280  os << "dev=tcp(" << GetId () << ", " << m_address << ")";
281  return os;
282 }
283 
284 } // namespace ndn
285 } // namespace ns3
286 
void SetUp(bool up=true)
These are face states and may be distinct from actual lower-layer device states, such as found in rea...
Definition: ndn-face.h:290
uint32_t GetId() const
Get face Id.
Definition: ndn-face.h:314
virtual std::ostream & Print(std::ostream &os) const
Print information about the face into the stream.
virtual void UnRegisterProtocolHandlers()
Un-Register callback to call when new packet arrives on the face.
Definition: ndn-face.cc:113
virtual void RegisterProtocolHandlers(const InterestHandler &interestHandler, const DataHandler &dataHandler)
Register callback to call when new packet arrives on the face.
Definition: ndn-face.cc:104
Virtual class defining NDN face.
Definition: ndn-face.h:58
virtual void SetMetric(uint16_t metric)
Assign routing/forwarding metric with face.
Definition: ndn-face.cc:230
virtual bool Receive(Ptr< const Packet > p)
Send packet up to the stack (towards forwarding strategy)
Definition: ndn-face.cc:163
virtual bool Send(Ptr< Packet > packet)
Send packet down to the stack (towards app or network)
Definition: ndn-face.cc:149
virtual void UnRegisterProtocolHandlers()
Un-Register callback to call when new packet arrives on the face.
Ptr< Node > GetNode() const
Get node to which this face is associated.
Definition: ndn-face.cc:98
Implementation of TCP/IP NDN face.
Definition: ndn-tcp-face.h:40
Callback< void, Ptr< Face >, Ptr< Interest > > InterestHandler
NDN protocol handlers.
Definition: ndn-face.h:71
virtual bool Send(Ptr< Packet > p)
Send packet down to the stack (towards app or network)
virtual void RegisterProtocolHandlers(const InterestHandler &interestHandler, const DataHandler &dataHandler)
Register callback to call when new packet arrives on the face.