blob: a479390726cd3212c31f6f5069ba6e910ccd31b8 [file] [log] [blame]
Alexander Afanasyevc74a6022011-08-15 20:01:35 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Alexander Afanasyevab1d5602011-08-17 19:17:18 -07002/*
3 * Copyright (c) 2011 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>
Ilya Moiseenko172763c2011-10-28 13:21:53 -070019 * Ilya Moiseenko <iliamo@cs.ucla.edu>
Alexander Afanasyevab1d5602011-08-17 19:17:18 -070020 */
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070021
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070022#include "ccnx-l3-protocol.h"
23
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070024#include "ns3/packet.h"
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070025#include "ns3/node.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070026#include "ns3/log.h"
27#include "ns3/callback.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070028#include "ns3/uinteger.h"
29#include "ns3/trace-source-accessor.h"
30#include "ns3/object-vector.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070031#include "ns3/boolean.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070032
Alexander Afanasyevc74a6022011-08-15 20:01:35 -070033#include "ns3/ccnx-header-helper.h"
34
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070035#include "ccnx-face.h"
36#include "ccnx-route.h"
Alexander Afanasyevc74a6022011-08-15 20:01:35 -070037#include "ccnx-forwarding-strategy.h"
38#include "ccnx-interest-header.h"
39#include "ccnx-content-object-header.h"
40
Alexander Afanasyev52e9aa92011-11-15 20:23:20 -080041#include "ccnx-net-device-face.h"
42
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -070043#include <boost/foreach.hpp>
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080044#include <boost/lambda/lambda.hpp>
45
46using namespace boost::tuples;
47using namespace boost::lambda;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070048
49NS_LOG_COMPONENT_DEFINE ("CcnxL3Protocol");
50
51namespace ns3 {
52
Alexander Afanasyev7112f482011-08-17 14:05:57 -070053const uint16_t CcnxL3Protocol::ETHERNET_FRAME_TYPE = 0x7777;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070054
55NS_OBJECT_ENSURE_REGISTERED (CcnxL3Protocol);
56
57TypeId
58CcnxL3Protocol::GetTypeId (void)
59{
60 static TypeId tid = TypeId ("ns3::CcnxL3Protocol")
61 .SetParent<Ccnx> ()
Alexander Afanasyev070aa482011-08-20 00:38:25 -070062 .SetGroupName ("Ccnx")
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070063 .AddConstructor<CcnxL3Protocol> ()
Alexander Afanasyev7112f482011-08-17 14:05:57 -070064 // .AddTraceSource ("Tx", "Send ccnx packet to outgoing interface.",
65 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_txTrace))
66 // .AddTraceSource ("Rx", "Receive ccnx packet from incoming interface.",
67 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_rxTrace))
68 // .AddTraceSource ("Drop", "Drop ccnx packet",
69 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_dropTrace))
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -070070 // .AddAttribute ("InterfaceList", "The set of Ccnx interfaces associated to this Ccnx stack.",
71 // ObjectVectorValue (),
72 // MakeObjectVectorAccessor (&CcnxL3Protocol::m_faces),
73 // MakeObjectVectorChecker<CcnxFace> ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070074
Alexander Afanasyev7112f482011-08-17 14:05:57 -070075 // .AddTraceSource ("SendOutgoing", "A newly-generated packet by this node is about to be queued for transmission",
76 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_sendOutgoingTrace))
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070077
78 ;
79 return tid;
80}
81
82CcnxL3Protocol::CcnxL3Protocol()
Alexander Afanasyevab1d5602011-08-17 19:17:18 -070083: m_faceCounter (0)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070084{
85 NS_LOG_FUNCTION (this);
Alexander Afanasyevcf133f02011-09-06 12:13:48 -070086
87 m_rit = CreateObject<CcnxRit> ();
88 m_pit = CreateObject<CcnxPit> ();
89 m_contentStore = CreateObject<CcnxContentStore> ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070090}
91
92CcnxL3Protocol::~CcnxL3Protocol ()
93{
94 NS_LOG_FUNCTION (this);
95}
96
97void
98CcnxL3Protocol::SetNode (Ptr<Node> node)
99{
100 m_node = node;
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700101 m_fib = m_node->GetObject<CcnxFib> ();
102 NS_ASSERT_MSG (m_fib != 0, "FIB should be created and aggregated to a node before calling Ccnx::SetNode");
103
104 m_pit->SetFib (m_fib);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700105}
106
107/*
108 * This method is called by AddAgregate and completes the aggregation
109 * by setting the node in the ccnx stack
110 */
111void
112CcnxL3Protocol::NotifyNewAggregate ()
113{
114 if (m_node == 0)
115 {
116 Ptr<Node>node = this->GetObject<Node>();
117 // verify that it's a valid node and that
118 // the node has not been set before
119 if (node != 0)
120 {
121 this->SetNode (node);
122 }
123 }
124 Object::NotifyNewAggregate ();
125}
126
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700127void
128CcnxL3Protocol::DoDispose (void)
129{
130 NS_LOG_FUNCTION (this);
131
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700132 for (CcnxFaceList::iterator i = m_faces.begin (); i != m_faces.end (); ++i)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700133 {
134 *i = 0;
135 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700136 m_faces.clear ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700137 m_node = 0;
Alexander Afanasyevd02a5d62011-11-21 11:01:51 -0800138
139 // Force delete on objects
Alexander Afanasyev18252852011-11-21 13:35:31 -0800140 m_forwardingStrategy = 0; // there is a reference to PIT stored in here
Alexander Afanasyevd02a5d62011-11-21 11:01:51 -0800141 m_rit = 0;
142 m_pit = 0;
143 m_contentStore = 0;
Alexander Afanasyev18252852011-11-21 13:35:31 -0800144 m_fib = 0;
145
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700146 // m_forwardingStrategy = 0;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700147 Object::DoDispose ();
148}
149
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700150void
151CcnxL3Protocol::SetForwardingStrategy (Ptr<CcnxForwardingStrategy> forwardingStrategy)
152{
153 NS_LOG_FUNCTION (this);
154 m_forwardingStrategy = forwardingStrategy;
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700155 // m_forwardingStrategy->SetCcnx (this);
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700156}
157
158Ptr<CcnxForwardingStrategy>
159CcnxL3Protocol::GetForwardingStrategy (void) const
160{
161 return m_forwardingStrategy;
162}
163
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700164uint32_t
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700165CcnxL3Protocol::AddFace (const Ptr<CcnxFace> &face)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700166{
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700167 NS_LOG_FUNCTION (this << &face);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700168
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700169 face->SetNode (m_node);
Alexander Afanasyevab1d5602011-08-17 19:17:18 -0700170 face->SetId (m_faceCounter); // sets a unique ID of the face. This ID serves only informational purposes
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700171
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700172 // ask face to register in lower-layer stack
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700173 face->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::Receive, this));
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700174
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700175 m_faces.push_back (face);
Alexander Afanasyevab1d5602011-08-17 19:17:18 -0700176 m_faceCounter ++;
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700177 return face->GetId ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700178}
179
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700180void
181CcnxL3Protocol::RemoveFace (Ptr<CcnxFace> face)
182{
183 // ask face to register in lower-layer stack
184 face->RegisterProtocolHandler (MakeNullCallback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>&> ());
185 CcnxFaceList::iterator face_it = find (m_faces.begin(), m_faces.end(), face);
186 NS_ASSERT_MSG (face_it != m_faces.end (), "Attempt to remove face that doesn't exist");
187 m_faces.erase (face_it);
188}
189
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700190Ptr<CcnxFace>
Alexander Afanasyev98256102011-08-14 01:00:02 -0700191CcnxL3Protocol::GetFace (uint32_t index) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700192{
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700193 BOOST_FOREACH (const Ptr<CcnxFace> &face, m_faces) // this function is not supposed to be called often, so linear search is fine
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700194 {
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700195 if (face->GetId () == index)
196 return face;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700197 }
198 return 0;
199}
200
Alexander Afanasyev52e9aa92011-11-15 20:23:20 -0800201Ptr<CcnxFace>
202CcnxL3Protocol::GetFaceByNetDevice (Ptr<NetDevice> netDevice) const
203{
204 BOOST_FOREACH (const Ptr<CcnxFace> &face, m_faces) // this function is not supposed to be called often, so linear search is fine
205 {
206 Ptr<CcnxNetDeviceFace> netDeviceFace = DynamicCast<CcnxNetDeviceFace> (face);
207 if (netDeviceFace == 0) continue;
208
209 if (netDeviceFace->GetNetDevice () == netDevice)
210 return face;
211 }
212 return 0;
213}
214
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700215uint32_t
Alexander Afanasyev98256102011-08-14 01:00:02 -0700216CcnxL3Protocol::GetNFaces (void) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700217{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700218 return m_faces.size ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700219}
220
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700221void
222CcnxL3Protocol::TransmittedDataTrace (Ptr<Packet> packet,
223 ContentObjectSource type,
224 Ptr<Ccnx> ccnx, Ptr<const CcnxFace> face)
225{
226 // a "small" inefficiency for logging purposes
227 Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader> ();
228 static CcnxContentObjectTail tail;
229 packet->RemoveHeader (*header);
230 packet->RemoveTrailer (tail);
231
232 m_transmittedDataTrace (header, packet/*payload*/, type, ccnx, face);
233
234 packet->AddHeader (*header);
235 packet->AddTrailer (tail);
236}
237
238
Alexander Afanasyev98256102011-08-14 01:00:02 -0700239// Callback from lower layer
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700240void
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700241CcnxL3Protocol::Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700242{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700243 if (!face->IsUp ())
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700244 {
245 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700246 // m_dropTrace (p, INTERFACE_DOWN, m_node->GetObject<Ccnx> ()/*this*/, face);
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700247 return;
248 }
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700249 NS_LOG_LOGIC ("Packet from face " << *face << " received on node " << m_node->GetId ());
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700250
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700251 Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700252 try
253 {
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700254 CcnxHeaderHelper::Type type = CcnxHeaderHelper::GetCcnxHeaderType (p);
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700255 switch (type)
256 {
257 case CcnxHeaderHelper::INTEREST:
258 {
259 Ptr<CcnxInterestHeader> header = Create<CcnxInterestHeader> ();
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700260
261 // Deserialization. Exception may be thrown
262 packet->RemoveHeader (*header);
263 NS_ASSERT_MSG (packet->GetSize () == 0, "Payload of Interests should be zero");
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800264
265 if (header->GetNack () > 0)
266 OnNack (face, header, p/*original packet*/);
267 else
268 OnInterest (face, header, p/*original packet*/);
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700269 break;
270 }
271 case CcnxHeaderHelper::CONTENT_OBJECT:
272 {
273 Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader> ();
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700274
275 static CcnxContentObjectTail contentObjectTrailer; //there is no data in this object
276
277 // Deserialization. Exception may be thrown
278 packet->RemoveHeader (*header);
279 packet->RemoveTrailer (contentObjectTrailer);
280
281 OnData (face, header, packet/*payload*/, p/*original packet*/);
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700282 break;
283 }
284 }
285
286 // exception will be thrown if packet is not recognized
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700287 }
288 catch (CcnxUnknownHeaderException)
289 {
290 NS_ASSERT_MSG (false, "Unknown CCNx header. Should not happen");
291 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700292}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700293
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800294void
295CcnxL3Protocol::OnNack (const Ptr<CcnxFace> &face,
296 Ptr<CcnxInterestHeader> &header,
297 const Ptr<const Packet> &p)
298{
299 NS_LOG_FUNCTION (face << header << p);
300
301 // Huh... Ignore all this for now
302
303 /*if( header->IsCongested () == false )
304 m_pit->LeakBucket(incomingFace,1);
305
306
307 m_droppedInterestsTrace (header, DROP_CONGESTION,
308 m_node->GetObject<Ccnx> (), incomingFace);
309
310 m_pit->modify(pitEntry, CcnxPitEntry::DeleteOutgoing(incomingFace));*/
311
312 // No matter is it duplicate or not, if it is a NACK message, remove all possible incoming
313 // entries for this interface (NACK means that neighbor gave up trying and there is no
314 // point of sending data in this direction)
315
316 // NS_LOG_INFO("Before (header->IsNack()) && (pitEntry != m_pit->end ())");
317 // if ((header->IsNack()) && (pitEntry != m_pit->end ()))
318 // {
319 // //m_pit->erase (pitEntry);
320 // NS_LOG_INFO("TRUE");
321 // m_pit->modify(pitEntry, CcnxPitEntry::DeleteIncoming(incomingFace));
322 // }
323
324 // m_fib->modify (m_fib->iterator_to (pitEntry->m_fibEntry),
325 // CcnxFibEntry::UpdateStatus(incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
326
327 // if (!pitEntry.AreThereMoreFacesToTry ())
328 // {
329 // BOOST_FOREACH (const CcnxPitEntryIncomingFace face, pitEntry.m_incoming)
330 // {
331 // // check all entries if the name of RIT entry matches the name of interest
332 // for (CcnxRitByNonce::type::iterator it = m_rit->begin(); it != m_rit->end(); it++)
333 // {
334 // if (it->m_prefix == iter->GetPrefix() )
335 // {
336 // header->SetNonce(it->m_nonce);
337 // header->SetNack(true);
338 // SendInterest(face.m_face, header, packet->Copy());
339 // }
340 // }
341 // }
342
343 // m_pit->erase(pitEntry);
344
345 // return;
346 // }
347}
348
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700349// Processing Interests
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800350//
351// !!! Key point.
352// !!! All interests should be answerred!!! Either later with data, immediately with data, or immediately with NACK
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700353void CcnxL3Protocol::OnInterest (const Ptr<CcnxFace> &incomingFace,
354 Ptr<CcnxInterestHeader> &header,
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700355 const Ptr<const Packet> &packet)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700356{
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800357 NS_LOG_FUNCTION (incomingFace << header << packet);
358 // m_receivedInterestsTrace (header, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700359
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800360 // Lookup of Pit (and associated Fib) entry for this Interest
361 const CcnxPitEntry &pitEntry;
362 bool isNew;
363 bool isDuplicated;
364 tie (pitEntry, isNew, isDuplicated) = m_pit->Lookup (*header);
Ilya Moiseenkod83eb0d2011-11-16 15:23:46 -0800365
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800366 if (isDuplicated)
Ilya Moiseenko172763c2011-10-28 13:21:53 -0700367 {
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800368 /**
369 * This condition will handle "routing" loops and also recently satisfied interests.
370 * Every time interest is satisfied, PIT entry (with empty incoming and outgoing faces)
371 * is kept for another small chunk of time.
372 */
Ilya Moiseenko172763c2011-10-28 13:21:53 -0700373
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800374 // //Trace duplicate interest
375 // m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST, m_node->GetObject<Ccnx> (), incomingFace);
Ilya Moiseenko172763c2011-10-28 13:21:53 -0700376
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800377 header->SetNack (CcnxInterestHeader::NACK_LOOP);
378 Ptr<Packet> packet = Create<Packet> ();
379 packet->AddHeader (*header);
Ilya Moiseenko172763c2011-10-28 13:21:53 -0700380
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800381 SendInterest (m_incomingFace, header, packet);
Ilya Moiseenko172763c2011-10-28 13:21:53 -0700382
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800383 // //Trace duplicate interest
384 // m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700385 return;
386 }
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800387
388 Ptr<Packet> contentObject;
389 Ptr<CcnxContentObjectHeader> contentObjectHeader;
390 tie (contentObject, contentObjectHeader) = m_contentStore->Lookup (header);
391 if (contentObject != 0)
392 {
393 NS_ASSERT_MSG (pitEntry.m_incoming.size () == 0,
394 "Something strange. Data is cached, but size of incoming interests is not zero...");
395 NS_ASSERT (contentObjectHeader != 0);
396
397 NS_LOG_LOGIC("Found in cache");
398
399 // TransmittedDataTrace (contentObject, CACHED,
400 // m_node->GetObject<Ccnx> (), incomingFace);
401 SendContentObject (incomingFace, contentObjectHeader, contentObject);
402
403 // Set pruning timout on PIT entry (instead of deleting the record)
404 m_pit->modify (m_pit->iterator_to (pitEntry),
405 boost::bind (&CcnxPitEntry::SetExpireTime, _1,
406 Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
407 return;
408 }
409
410 // \todo Detect retransmissions. Not yet sure how...
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700411
Ilya Moiseenko172763c2011-10-28 13:21:53 -0700412 // Data is not in cache
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800413 CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry.m_incoming.find (incomingFace);
414 CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry.m_outgoing.find (incomingFace);
415
416 if (inFace != pitEntry.m_incoming.end ())
Ilya Moiseenko172763c2011-10-28 13:21:53 -0700417 {
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800418 // CcnxPitEntryIncomingFace.m_arrivalTime keeps track arrival time of the first packet... why?
Ilya Moiseenko172763c2011-10-28 13:21:53 -0700419
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800420 // this is almost definitely a retransmission. But should we trust the user on that?
421 }
Ilya Moiseenko172763c2011-10-28 13:21:53 -0700422 else
423 {
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800424 m_pit->modify (m_pit->iterator_to (m_pitpitEntry),
425 iface = _1->m_incoming.insert (CcnxPitEntryIncoming (incomingFace, Simulator::Now ())));
426 }
427
428 if (outFace != pitEntry.m_outgoing.end ())
429 {
430 // got a non-duplicate interest from the face we have sent interest to
431 // Probably, there is no point in waiting data from that face... Not sure yet
432
433 // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
434 // Mark interface YELLOW, but keep a small hope that data will come eventually.
435
436 // ?? not sure if we need to do that ?? ...
437
438 m_fib->modify(m_fib->iterator_to (pitEntry.m_fibEntry),
439 boost::bind (&CcnxFibEntry::UpdateStatus,
440 _1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
441
442 // suppress?
443 }
444 else if (pitEntry->m_outgoing.size() > 0) // Suppress this interest if we're still expecting data from some other face
445
446 {
447 // We are already expecting data later in future. Suppress the interest
448 // m_droppedInterestsTrace (header, NDN_SUPPRESSED_INTEREST, m_node->GetObject<Ccnx> (), incomingFace);
449 return;
450 }
451
452 /////////////////////////////////////////////////////////////////////
453 // Propagate
454 /////////////////////////////////////////////////////////////////////
455
456 NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
457
458 bool propagated = m_forwardingStrategy->
459 PropagateInterest (pitEntry, fibEntry,incomingFace, header, packet,
460 MakeCallback (&CcnxL3Protocol::SendInterest, this)
461 );
462
463 // ForwardingStrategy will try its best to forward packet to at least one interface.
464 // If no interests was propagated, then there is not other option for forwarding or
465 // ForwardingStrategy failed to find it.
466 if (!propagated)
467 {
468 Ptr<Packet> packet = Create<Packet> ();
469 header->SetNack (CcnxInterestHeader::NACK_CONGESTION);
470 packet.AddHeader (*header);
471
472 while (pitEntry.m_incoming.size () > 0)
473 {
474 SendInterest (pitEntry.m_incoming.front ().m_face, header, packet->Copy ());
475
476 pitEntry.m_incoming.pop_front ();
477
478 // m_droppedInterestsTrace (header, DROP_CONGESTION,
479 // m_node->GetObject<Ccnx> (), incomingFace);
480 }
481
482 // Set pruning timout on PIT entry (instead of deleting the record)
483 m_pit->modify (m_pit->iterator_to (pitEntry),
484 boost::bind (&CcnxPitEntry::SetExpireTime, _1,
485 Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
486 }
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700487}
488
489// Processing ContentObjects
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700490void CcnxL3Protocol::OnData (const Ptr<CcnxFace> &incomingFace,
491 Ptr<CcnxContentObjectHeader> &header,
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700492 Ptr<Packet> &payload,
493 const Ptr<const Packet> &packet)
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700494{
Ilya Moiseenko172763c2011-10-28 13:21:53 -0700495
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800496 NS_LOG_FUNCTION (incomingFace << header, payload, packet);
497 // m_receivedDataTrace (header, payload, m_node->GetObject<Ccnx> ()/*this*/, incomingFace);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700498
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700499 // 1. Lookup PIT entry
500 try
501 {
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700502 const CcnxPitEntry &pitEntry = m_pit->Lookup (*header);
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700503
504 // Note that with MultiIndex we need to modify entries indirectly
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700505
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700506 // Update metric status for the incoming interface in the corresponding FIB entry
507 m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800508 boost::bind (CcnxFibEntry::UpdateStatus, _1, incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700509
510 // Add or update entry in the content store
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700511 m_contentStore->Add (header, payload);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700512
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800513 CcnxPitEntryOutgoingFaceContainer::type::iterator out = pitEntry.m_outgoing.find (incomingFace);
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700514
515 // If we have sent interest for this data via this face, then update stats.
516 if (out != pitEntry.m_outgoing.end ())
517 {
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800518 m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
519 boost::bind (&CcnxFibEntry::UpdateRtt,
520 _1,
521 Simulator::Now () - out->m_sendTime));
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700522 }
523 else
524 {
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800525 // Unsolicited data, but we're interested in it... should we get it?
526 // Potential hole for attacks
527
528 NS_LOG_ERROR ("Node "<< m_node->GetId() <<
529 ". PIT entry for "<< header->GetName ()<<" is valid, "
530 "but outgoing entry for interface "<< incomingFace <<" doesn't exist\n");
531
532 NS_ASSERT (false); // temporary put false here
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700533 }
534
535 //satisfy all pending incoming Interests
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800536 while (pitEntry.m_incoming.size () > 0)
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700537 {
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800538 if (pitEntry.m_incoming.front ().m_face != incomingFace)
539 SendInterest (pitEntry.m_incoming.front ().m_face, header, packet->Copy ());
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700540
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800541 pitEntry.m_incoming.pop_front ();
542
543 // m_transmittedDataTrace (header, payload, FORWARDED, m_node->GetObject<Ccnx> (), interest.m_face);
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700544 }
545
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800546 // Set pruning timout on PIT entry (instead of deleting the record)
547 m_pit->modify (m_pit->iterator_to (pitEntry),
548 boost::bind (&CcnxPitEntry::SetExpireTime, _1,
549 Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700550 }
551 catch (CcnxPitEntryNotFound)
552 {
553 // 2. Drop data packet if PIT entry is not found
554 // (unsolicited data packets should not "poison" content store)
555
556 //drop dulicated or not requested data packet
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800557 // m_droppedDataTrace (header, payload, NDN_UNSOLICITED_DATA, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700558 return; // do not process unsoliced data packets
559 }
560}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700561
562void
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700563CcnxL3Protocol::SendInterest (const Ptr<CcnxFace> &face,
564 const Ptr<CcnxInterestHeader> &header,
565 const Ptr<Packet> &packet)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700566{
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700567 NS_LOG_FUNCTION (this << "packet: " << &packet << ", face: "<< &face);
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700568 NS_ASSERT_MSG (face != 0, "Face should never be NULL");
569
570 if (face->IsUp ())
571 {
572 NS_LOG_LOGIC ("Sending via face " << &face); //
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800573 // m_transmittedInterestsTrace (header, m_node->GetObject<Ccnx> (), face);
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700574 face->Send (packet);
575 }
576 else
577 {
578 NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << &face);
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800579 // m_droppedInterestsTrace (header, INTERFACE_DOWN, m_node->GetObject<Ccnx> (), face);
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700580 }
581}
582
583void
584CcnxL3Protocol::SendContentObject (const Ptr<CcnxFace> &face,
585 const Ptr<CcnxContentObjectHeader> &header,
586 const Ptr<Packet> &packet)
587{
588 NS_LOG_FUNCTION (this << "packet: " << &packet << ", face: "<< &face);
589 NS_ASSERT_MSG (face != 0, "Face should never be NULL");
590
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700591 if (face->IsUp ())
592 {
593 NS_LOG_LOGIC ("Sending via face " << &face); //
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700594 // m_txTrace (packet, m_node->GetObject<Ccnx> (), face);
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700595 face->Send (packet);
596 }
597 else
598 {
599 NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << &face);
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700600 // m_dropTrace (packet, INTERFACE_DOWN, m_node->GetObject<Ccnx> (), face);
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700601 }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700602}
603
Ilya Moiseenko172763c2011-10-28 13:21:53 -0700604Ptr<CcnxPit>
605CcnxL3Protocol::GetPit()
606{
607 return m_pit;
608}
Ilya Moiseenkod83eb0d2011-11-16 15:23:46 -0800609
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800610// void
611// CcnxL3Protocol::ScheduleLeakage()
612// {
613// m_pit->LeakBuckets();
614// Time interval = MilliSeconds (NDN_INTEREST_RESET_PERIOD);
615
616// Simulator::Schedule (interval, &CcnxL3Protocol::ScheduleLeakage, this);
617// }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700618} //namespace ns3