blob: 9224b40d799e87458f9115f7826a4f6a3e172d23 [file] [log] [blame]
Junxiao Shi5e5e4452015-09-24 16:56:52 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Davide Pesavento459cf192016-03-03 02:20:12 +01003 * Copyright (c) 2014-2016, Regents of the University of California,
Junxiao Shi5e5e4452015-09-24 16:56:52 -07004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "topology-tester.hpp"
27#include <ndn-cxx/encoding/encoding-buffer-fwd.hpp>
28#include "face/generic-link-service.hpp"
29
30namespace nfd {
31namespace fw {
32namespace tests {
33
Junxiao Shi6535f1e2015-10-08 13:02:18 -070034using face::InternalTransportBase;
35using face::InternalForwarderTransport;
36using face::InternalClientTransport;
Junxiao Shi6535f1e2015-10-08 13:02:18 -070037using face::GenericLinkService;
Junxiao Shi5e5e4452015-09-24 16:56:52 -070038
Junxiao Shi6535f1e2015-10-08 13:02:18 -070039TopologyLink::TopologyLink(const time::nanoseconds& delay)
Junxiao Shi5e5e4452015-09-24 16:56:52 -070040 : m_isUp(true)
Hila Ben Abraham39a79be2016-03-30 22:00:55 -070041{
42 this->setDelay(delay);
43}
44
45void
46TopologyLink::setDelay(const time::nanoseconds& delay)
Junxiao Shi5e5e4452015-09-24 16:56:52 -070047{
Junxiao Shi6535f1e2015-10-08 13:02:18 -070048 BOOST_ASSERT(delay > time::nanoseconds::zero());
49 // zero delay does not work on OSX
Hila Ben Abraham39a79be2016-03-30 22:00:55 -070050
51 m_delay = delay;
Junxiao Shi5e5e4452015-09-24 16:56:52 -070052}
53
54void
Junxiao Shicde37ad2015-12-24 01:02:05 -070055TopologyLink::addFace(TopologyNode i, shared_ptr<Face> face)
Junxiao Shi6535f1e2015-10-08 13:02:18 -070056{
Junxiao Shicde37ad2015-12-24 01:02:05 -070057 this->attachTransport(i, dynamic_cast<InternalTransportBase*>(face->getTransport()));
Junxiao Shi6535f1e2015-10-08 13:02:18 -070058 m_faces[i] = face;
59}
60
61void
62TopologyLink::attachTransport(TopologyNode i, InternalTransportBase* transport)
Junxiao Shi5e5e4452015-09-24 16:56:52 -070063{
64 BOOST_ASSERT(transport != nullptr);
65 BOOST_ASSERT(m_transports.count(i) == 0);
66
67 m_transports[i] = transport;
68 transport->afterSend.connect([this, i] (const Block& packet) { this->transmit(i, packet); });
69}
70
71void
Junxiao Shi6535f1e2015-10-08 13:02:18 -070072TopologyLink::transmit(TopologyNode i, const Block& packet)
Junxiao Shi5e5e4452015-09-24 16:56:52 -070073{
74 if (!m_isUp) {
75 return;
76 }
77
78 for (auto&& p : m_transports) {
79 if (p.first == i) {
80 continue;
81 }
82
Junxiao Shi6535f1e2015-10-08 13:02:18 -070083 InternalTransportBase* recipient = p.second;
Junxiao Shi5e5e4452015-09-24 16:56:52 -070084 this->scheduleReceive(recipient, packet);
85 }
86}
87
Junxiao Shi5e5e4452015-09-24 16:56:52 -070088void
Junxiao Shi6535f1e2015-10-08 13:02:18 -070089TopologyLink::scheduleReceive(InternalTransportBase* recipient, const Block& packet)
Junxiao Shi5e5e4452015-09-24 16:56:52 -070090{
91 scheduler::schedule(m_delay, [packet, recipient] {
Junxiao Shi6535f1e2015-10-08 13:02:18 -070092 recipient->receiveFromLink(packet);
Junxiao Shi5e5e4452015-09-24 16:56:52 -070093 });
94}
95
Junxiao Shicde37ad2015-12-24 01:02:05 -070096TopologyAppLink::TopologyAppLink(shared_ptr<Face> forwarderFace)
Junxiao Shi6535f1e2015-10-08 13:02:18 -070097 : m_face(forwarderFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -070098 , m_forwarderTransport(static_cast<InternalForwarderTransport*>(forwarderFace->getTransport()))
Junxiao Shi6535f1e2015-10-08 13:02:18 -070099 , m_clientTransport(make_shared<InternalClientTransport>())
100 , m_client(make_shared<ndn::Face>(m_clientTransport, getGlobalIoService()))
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700101{
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700102 this->recover();
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700103}
104
105void
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700106TopologyAppLink::fail()
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700107{
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700108 m_clientTransport->connectToForwarder(nullptr);
109}
110
111void
112TopologyAppLink::recover()
113{
114 m_clientTransport->connectToForwarder(m_forwarderTransport);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700115}
116
117TopologyNode
118TopologyTester::addForwarder(const std::string& label)
119{
120 size_t i = m_forwarders.size();
Davide Pesavento459cf192016-03-03 02:20:12 +0100121 m_forwarders.push_back(make_unique<Forwarder>());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700122 m_forwarderLabels.push_back(label);
123 BOOST_ASSERT(m_forwarders.size() == m_forwarderLabels.size());
124 return i;
125}
126
127shared_ptr<TopologyLink>
128TopologyTester::addLink(const std::string& label, const time::nanoseconds& delay,
129 std::initializer_list<TopologyNode> forwarders,
130 bool forceMultiAccessFace)
131{
Yumin Xiaab497452016-05-10 20:23:24 +0800132 auto link = std::make_shared<TopologyLink>(delay);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700133 FaceUri remoteUri("topology://link/" + label);
134 ndn::nfd::LinkType linkType = (forceMultiAccessFace || forwarders.size() > 2) ?
135 ndn::nfd::LINK_TYPE_MULTI_ACCESS :
136 ndn::nfd::LINK_TYPE_POINT_TO_POINT;
137
138 for (TopologyNode i : forwarders) {
139 Forwarder& forwarder = this->getForwarder(i);
140 FaceUri localUri("topology://" + m_forwarderLabels.at(i) + "/" + label);
141
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700142 auto service = make_unique<GenericLinkService>();
143 auto transport = make_unique<InternalForwarderTransport>(localUri, remoteUri,
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700144 ndn::nfd::FACE_SCOPE_NON_LOCAL, linkType);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700145 auto face = make_shared<Face>(std::move(service), std::move(transport));
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700146
Junxiao Shicde37ad2015-12-24 01:02:05 -0700147 forwarder.addFace(face);
148 link->addFace(i, face);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700149 }
150
151 m_links.push_back(link); // keep a shared_ptr so callers don't have to
152 return link;
153}
154
155shared_ptr<TopologyAppLink>
156TopologyTester::addAppFace(const std::string& label, TopologyNode i)
157{
158 Forwarder& forwarder = this->getForwarder(i);
159 FaceUri localUri("topology://" + m_forwarderLabels.at(i) + "/local/" + label);
160 FaceUri remoteUri("topology://" + m_forwarderLabels.at(i) + "/app/" + label);
161
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700162 auto service = make_unique<GenericLinkService>();
163 auto transport = make_unique<InternalForwarderTransport>(localUri, remoteUri,
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700164 ndn::nfd::FACE_SCOPE_LOCAL, ndn::nfd::LINK_TYPE_POINT_TO_POINT);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700165 auto face = make_shared<Face>(std::move(service), std::move(transport));
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700166
Junxiao Shicde37ad2015-12-24 01:02:05 -0700167 forwarder.addFace(face);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700168
Junxiao Shicde37ad2015-12-24 01:02:05 -0700169 auto al = make_shared<TopologyAppLink>(face);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700170 m_appLinks.push_back(al); // keep a shared_ptr so callers don't have to
171 return al;
172}
173
174shared_ptr<TopologyAppLink>
175TopologyTester::addAppFace(const std::string& label, TopologyNode i, const Name& prefix, uint64_t cost)
176{
177 shared_ptr<TopologyAppLink> al = this->addAppFace(label, i);
178 this->registerPrefix(i, al->getForwarderFace(), prefix, cost);
179 return al;
180}
181
182void
183TopologyTester::registerPrefix(TopologyNode i, const Face& face, const Name& prefix, uint64_t cost)
184{
185 Forwarder& forwarder = this->getForwarder(i);
186 Fib& fib = forwarder.getFib();
Junxiao Shia6de4292016-07-12 02:08:10 +0000187 fib.insert(prefix).first->addNextHop(const_cast<Face&>(face), cost);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700188}
189
190void
191TopologyTester::addEchoProducer(ndn::Face& face, const Name& prefix)
192{
193 face.setInterestFilter(prefix,
194 [&face] (const ndn::InterestFilter&, const Interest& interest) {
195 shared_ptr<Data> data = makeData(interest.getName());
196 face.put(*data);
197 });
198}
199
200void
201TopologyTester::addIntervalConsumer(ndn::Face& face, const Name& prefix,
202 const time::nanoseconds& interval, size_t n)
203{
204 Name name(prefix);
205 name.appendTimestamp();
206 shared_ptr<Interest> interest = makeInterest(name);
207 face.expressInterest(*interest, bind([]{}));
208
209 if (n > 1) {
210 scheduler::schedule(interval, bind(&TopologyTester::addIntervalConsumer, this,
211 ref(face), prefix, interval, n - 1));
212 }
213}
214
215} // namespace tests
216} // namespace fw
217} // namespace nfd