blob: a66e46a5dde4b09d93c66b747e368166946255b6 [file] [log] [blame]
Junxiao Shicde37ad2015-12-24 01:02:05 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi38b24c72017-01-05 02:59:31 +00003 * Copyright (c) 2014-2017, Regents of the University of California,
Junxiao Shicde37ad2015-12-24 01:02:05 -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 "face/tcp-factory.hpp"
27
Eric Newberry42602412016-08-27 09:33:18 -070028#include "factory-test-common.hpp"
Junxiao Shi38b24c72017-01-05 02:59:31 +000029#include "face-system-fixture.hpp"
Junxiao Shicde37ad2015-12-24 01:02:05 -070030#include "tests/limited-io.hpp"
31
32namespace nfd {
Junxiao Shi38b24c72017-01-05 02:59:31 +000033namespace face {
Junxiao Shicde37ad2015-12-24 01:02:05 -070034namespace tests {
35
36BOOST_AUTO_TEST_SUITE(Face)
37BOOST_FIXTURE_TEST_SUITE(TestTcpFactory, BaseFixture)
38
39using nfd::Face;
40
Junxiao Shi38b24c72017-01-05 02:59:31 +000041BOOST_FIXTURE_TEST_SUITE(ProcessConfig, FaceSystemFixture)
42
43BOOST_AUTO_TEST_CASE(Normal)
44{
45 const std::string CONFIG = R"CONFIG(
46 face_system
47 {
48 tcp
49 {
50 listen yes
51 port 16363
52 enable_v4 yes
53 enable_v6 yes
54 }
55 }
56 )CONFIG";
57
Junxiao Shi1b65ca12017-01-21 23:04:41 +000058 parseConfig(CONFIG, true);
59 parseConfig(CONFIG, false);
Junxiao Shi38b24c72017-01-05 02:59:31 +000060
61 auto& factory = this->getFactoryById<TcpFactory>("tcp");
62 BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
63}
64
65BOOST_AUTO_TEST_CASE(Omitted)
66{
67 const std::string CONFIG = R"CONFIG(
68 face_system
69 {
70 }
71 )CONFIG";
72
Junxiao Shi1b65ca12017-01-21 23:04:41 +000073 parseConfig(CONFIG, true);
74 parseConfig(CONFIG, false);
Junxiao Shi38b24c72017-01-05 02:59:31 +000075
76 auto& factory = this->getFactoryById<TcpFactory>("tcp");
77 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
78}
79
80BOOST_AUTO_TEST_CASE(BadListen)
81{
82 const std::string CONFIG = R"CONFIG(
83 face_system
84 {
85 tcp
86 {
87 listen hello
88 }
89 }
90 )CONFIG";
91
92 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
93 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
94}
95
96BOOST_AUTO_TEST_CASE(ChannelsDisabled)
97{
98 const std::string CONFIG = R"CONFIG(
99 face_system
100 {
101 tcp
102 {
103 port 6363
104 enable_v4 no
105 enable_v6 no
106 }
107 }
108 )CONFIG";
109
110 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
111 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
112}
113
114BOOST_AUTO_TEST_CASE(UnknownOption)
115{
116 const std::string CONFIG = R"CONFIG(
117 face_system
118 {
119 tcp
120 {
121 hello
122 }
123 }
124 )CONFIG";
125
126 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
127 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
128}
129
130BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
131
Junxiao Shicde37ad2015-12-24 01:02:05 -0700132BOOST_AUTO_TEST_CASE(ChannelMap)
133{
134 TcpFactory factory;
135
136 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
137 shared_ptr<TcpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
138 BOOST_CHECK_EQUAL(channel1, channel1a);
139 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "tcp4://127.0.0.1:20070");
140
141 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
142 BOOST_CHECK_NE(channel1, channel2);
143
144 shared_ptr<TcpChannel> channel3 = factory.createChannel("::1", "20071");
145 BOOST_CHECK_NE(channel2, channel3);
146 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "tcp6://[::1]:20071");
147}
148
149BOOST_AUTO_TEST_CASE(GetChannels)
150{
151 TcpFactory factory;
152 BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
153
154 std::vector<shared_ptr<const Channel>> expectedChannels;
155 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
156 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
157 expectedChannels.push_back(factory.createChannel("::1", "20071"));
158
159 for (const auto& ch : factory.getChannels()) {
160 auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), ch);
161 BOOST_REQUIRE(pos != expectedChannels.end());
162 expectedChannels.erase(pos);
163 }
164 BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
165}
166
Eric Newberry42602412016-08-27 09:33:18 -0700167BOOST_AUTO_TEST_CASE(FaceCreate)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700168{
169 TcpFactory factory;
170
Eric Newberry42602412016-08-27 09:33:18 -0700171 createFace(factory,
172 FaceUri("tcp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000173 {},
Eric Newberry42602412016-08-27 09:33:18 -0700174 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700175 false,
Eric Newberry42602412016-08-27 09:33:18 -0700176 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700177
178 factory.createChannel("127.0.0.1", "20071");
179
Eric Newberry42602412016-08-27 09:33:18 -0700180 createFace(factory,
Eric Newberry78e32b02017-04-01 14:34:44 +0000181 FaceUri("tcp4://127.0.0.1:6363"),
182 {},
Eric Newberry42602412016-08-27 09:33:18 -0700183 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700184 false,
Eric Newberry42602412016-08-27 09:33:18 -0700185 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400186
187 createFace(factory,
188 FaceUri("tcp4://127.0.0.1:6363"),
189 {},
190 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
191 false,
192 {CreateFaceExpectedResult::SUCCESS, 0, ""});
193
194 createFace(factory,
195 FaceUri("tcp4://127.0.0.1:20072"),
196 {},
197 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
198 false,
199 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700200}
201
202BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
203{
204 TcpFactory factory;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700205 factory.createChannel("127.0.0.1", "20071");
206
Eric Newberry42602412016-08-27 09:33:18 -0700207 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400208 FaceUri("tcp4://127.0.0.1:20072"),
Eric Newberry42602412016-08-27 09:33:18 -0700209 FaceUri("tcp4://127.0.0.1:20071"),
Davide Pesavento46afec42017-05-28 14:28:47 -0400210 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
211 false,
212 {CreateFaceExpectedResult::FAILURE, 406,
213 "Unicast TCP faces cannot be created with a LocalUri"});
214
215 createFace(factory,
216 FaceUri("tcp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000217 {},
Eric Newberry42602412016-08-27 09:33:18 -0700218 ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
Eric Newberryf40551a2016-09-05 15:41:16 -0700219 false,
Eric Newberry42602412016-08-27 09:33:18 -0700220 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400221 "Outgoing TCP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +0000222
223 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400224 FaceUri("tcp4://127.0.0.1:20071"),
225 {},
Eric Newberry78e32b02017-04-01 14:34:44 +0000226 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
227 false,
228 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400229 "Requested endpoint is prohibited"});
230
231 createFace(factory,
232 FaceUri("tcp4://198.51.100.100:6363"),
233 {},
234 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
235 true,
236 {CreateFaceExpectedResult::FAILURE, 406,
237 "Local fields can only be enabled on faces with local scope"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700238}
239
240class FaceCreateTimeoutFixture : public BaseFixture
241{
242public:
243 void
244 onFaceCreated(const shared_ptr<Face>& newFace)
245 {
246 BOOST_CHECK_MESSAGE(false, "Timeout expected");
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400247 face = newFace;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700248
249 limitedIo.afterOp();
250 }
251
252 void
253 onConnectFailed(const std::string& reason)
254 {
255 BOOST_CHECK_MESSAGE(true, reason);
256
257 limitedIo.afterOp();
258 }
259
260public:
261 LimitedIo limitedIo;
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400262 shared_ptr<Face> face;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700263};
264
265BOOST_FIXTURE_TEST_CASE(FaceCreateTimeout, FaceCreateTimeoutFixture)
266{
267 TcpFactory factory;
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400268 factory.createChannel("0.0.0.0", "20070");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700269
270 factory.createFace(FaceUri("tcp4://192.0.2.1:20070"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000271 {},
Junxiao Shicde37ad2015-12-24 01:02:05 -0700272 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700273 false,
Junxiao Shicde37ad2015-12-24 01:02:05 -0700274 bind(&FaceCreateTimeoutFixture::onFaceCreated, this, _1),
Eric Newberry42602412016-08-27 09:33:18 -0700275 bind(&FaceCreateTimeoutFixture::onConnectFailed, this, _2));
Junxiao Shicde37ad2015-12-24 01:02:05 -0700276
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400277 BOOST_REQUIRE_EQUAL(limitedIo.run(1, time::seconds(10)), LimitedIo::EXCEED_OPS);
278 BOOST_CHECK(face == nullptr);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700279}
280
281class FakeNetworkInterfaceFixture : public BaseFixture
282{
283public:
284 FakeNetworkInterfaceFixture()
285 {
286 using namespace boost::asio::ip;
287
288 auto fakeInterfaces = make_shared<std::vector<NetworkInterfaceInfo>>();
289
290 fakeInterfaces->push_back(
291 NetworkInterfaceInfo {0, "eth0",
292 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
293 {address_v4::from_string("0.0.0.0")},
294 {address_v6::from_string("::")},
295 address_v4(),
296 IFF_UP});
297 fakeInterfaces->push_back(
298 NetworkInterfaceInfo {1, "eth0",
299 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
300 {address_v4::from_string("192.168.2.1"), address_v4::from_string("192.168.2.2")},
301 {},
302 address_v4::from_string("192.168.2.255"),
303 0});
304 fakeInterfaces->push_back(
305 NetworkInterfaceInfo {2, "eth1",
306 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
307 {address_v4::from_string("198.51.100.1")},
308 {address_v6::from_string("2001:db8::2"), address_v6::from_string("2001:db8::3")},
309 address_v4::from_string("198.51.100.255"),
310 IFF_MULTICAST | IFF_BROADCAST | IFF_UP});
311
312 setDebugNetworkInterfaces(fakeInterfaces);
313 }
314
315 ~FakeNetworkInterfaceFixture()
316 {
317 setDebugNetworkInterfaces(nullptr);
318 }
319};
320
321BOOST_FIXTURE_TEST_CASE(Bug2292, FakeNetworkInterfaceFixture)
322{
323 using namespace boost::asio::ip;
324
325 TcpFactory factory;
326 factory.prohibitEndpoint(tcp::Endpoint(address_v4::from_string("192.168.2.1"), 1024));
327 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
328 BOOST_CHECK((factory.m_prohibitedEndpoints ==
329 std::set<tcp::Endpoint> {
330 tcp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
331 }));
332
333 factory.m_prohibitedEndpoints.clear();
334 factory.prohibitEndpoint(tcp::Endpoint(address_v6::from_string("2001:db8::1"), 2048));
335 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
336 BOOST_CHECK((factory.m_prohibitedEndpoints ==
337 std::set<tcp::Endpoint> {
338 tcp::Endpoint(address_v6::from_string("2001:db8::1"), 2048)
339 }));
340
341 factory.m_prohibitedEndpoints.clear();
342 factory.prohibitEndpoint(tcp::Endpoint(address_v4(), 1024));
343 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 4);
344 BOOST_CHECK((factory.m_prohibitedEndpoints ==
345 std::set<tcp::Endpoint> {
346 tcp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
347 tcp::Endpoint(address_v4::from_string("192.168.2.2"), 1024),
348 tcp::Endpoint(address_v4::from_string("198.51.100.1"), 1024),
349 tcp::Endpoint(address_v4::from_string("0.0.0.0"), 1024)
350 }));
351
352 factory.m_prohibitedEndpoints.clear();
353 factory.prohibitEndpoint(tcp::Endpoint(address_v6(), 2048));
354 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 3);
355 BOOST_CHECK((factory.m_prohibitedEndpoints ==
356 std::set<tcp::Endpoint> {
357 tcp::Endpoint(address_v6::from_string("2001:db8::2"), 2048),
358 tcp::Endpoint(address_v6::from_string("2001:db8::3"), 2048),
359 tcp::Endpoint(address_v6::from_string("::"), 2048)
360 }));
361}
362
363BOOST_AUTO_TEST_SUITE_END() // TestTcpFactory
364BOOST_AUTO_TEST_SUITE_END() // Face
365
366} // namespace tests
Junxiao Shi38b24c72017-01-05 02:59:31 +0000367} // namespace face
Junxiao Shicde37ad2015-12-24 01:02:05 -0700368} // namespace nfd