blob: 08e4498cf40e6e01790fd7c475d0ae7f5ce1ff0c [file] [log] [blame]
Junxiao Shicde37ad2015-12-24 01:02:05 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi0ba6d642017-07-17 00:53:22 +00002/*
Davide Pesavento15b55052018-01-27 19:09:28 -05003 * Copyright (c) 2014-2018, 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
Junxiao Shi38b24c72017-01-05 02:59:31 +000028#include "face-system-fixture.hpp"
Davide Pesaventob15276f2017-07-15 16:27:13 -040029#include "factory-test-common.hpp"
Junxiao Shicde37ad2015-12-24 01:02:05 -070030#include "tests/limited-io.hpp"
31
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040032#include <ndn-cxx/net/address-converter.hpp>
33
Junxiao Shicde37ad2015-12-24 01:02:05 -070034namespace nfd {
Junxiao Shi38b24c72017-01-05 02:59:31 +000035namespace face {
Junxiao Shicde37ad2015-12-24 01:02:05 -070036namespace tests {
37
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040038class TcpFactoryFixture : public FaceSystemFactoryFixture<TcpFactory>
39{
40protected:
41 shared_ptr<TcpChannel>
42 createChannel(const std::string& localIp, const std::string& localPort)
43 {
44 tcp::Endpoint endpoint(ndn::ip::addressFromString(localIp),
45 boost::lexical_cast<uint16_t>(localPort));
46 return factory.createChannel(endpoint);
47 }
Alexander Afanasyevded17422018-04-03 19:00:23 -040048
49protected:
50 LimitedIo limitedIo;
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040051};
Junxiao Shi0ba6d642017-07-17 00:53:22 +000052
Junxiao Shicde37ad2015-12-24 01:02:05 -070053BOOST_AUTO_TEST_SUITE(Face)
Junxiao Shi0ba6d642017-07-17 00:53:22 +000054BOOST_FIXTURE_TEST_SUITE(TestTcpFactory, TcpFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -070055
Junxiao Shi0ba6d642017-07-17 00:53:22 +000056BOOST_AUTO_TEST_SUITE(ProcessConfig)
Junxiao Shi38b24c72017-01-05 02:59:31 +000057
Davide Pesavento494a9552018-02-04 22:16:05 -050058BOOST_AUTO_TEST_CASE(Defaults)
59{
60 const std::string CONFIG = R"CONFIG(
61 face_system
62 {
63 tcp
64 }
65 )CONFIG";
66
67 parseConfig(CONFIG, true);
68 parseConfig(CONFIG, false);
69
70 checkChannelListEqual(factory, {"tcp4://0.0.0.0:6363", "tcp6://[::]:6363"});
71 auto channels = factory.getChannels();
72 BOOST_CHECK(std::all_of(channels.begin(), channels.end(),
73 [] (const shared_ptr<const Channel>& ch) { return ch->isListening(); }));
Alexander Afanasyevded17422018-04-03 19:00:23 -040074
75 BOOST_CHECK_EQUAL(factory.m_local.m_whitelist.size(), 2);
76 BOOST_CHECK_EQUAL(factory.m_local.m_whitelist.count("127.0.0.0/8"), 1);
77 BOOST_CHECK_EQUAL(factory.m_local.m_whitelist.count("::1/128"), 1);
78 BOOST_CHECK_EQUAL(factory.m_local.m_blacklist.size(), 0);
Davide Pesavento494a9552018-02-04 22:16:05 -050079}
80
81BOOST_AUTO_TEST_CASE(DisableListen)
Junxiao Shi38b24c72017-01-05 02:59:31 +000082{
83 const std::string CONFIG = R"CONFIG(
84 face_system
85 {
86 tcp
87 {
Davide Pesavento494a9552018-02-04 22:16:05 -050088 listen no
89 port 7001
90 }
91 }
92 )CONFIG";
93
94 parseConfig(CONFIG, true);
95 parseConfig(CONFIG, false);
96
97 checkChannelListEqual(factory, {"tcp4://0.0.0.0:7001", "tcp6://[::]:7001"});
98 auto channels = factory.getChannels();
99 BOOST_CHECK(std::none_of(channels.begin(), channels.end(),
100 [] (const shared_ptr<const Channel>& ch) { return ch->isListening(); }));
101}
102
103BOOST_AUTO_TEST_CASE(DisableV4)
104{
105 const std::string CONFIG = R"CONFIG(
106 face_system
107 {
108 tcp
109 {
110 port 7001
111 enable_v4 no
Junxiao Shi38b24c72017-01-05 02:59:31 +0000112 enable_v6 yes
113 }
114 }
115 )CONFIG";
116
Junxiao Shi1b65ca12017-01-21 23:04:41 +0000117 parseConfig(CONFIG, true);
118 parseConfig(CONFIG, false);
Junxiao Shi38b24c72017-01-05 02:59:31 +0000119
Davide Pesavento494a9552018-02-04 22:16:05 -0500120 checkChannelListEqual(factory, {"tcp6://[::]:7001"});
121}
122
123BOOST_AUTO_TEST_CASE(DisableV6)
124{
125 const std::string CONFIG = R"CONFIG(
126 face_system
127 {
128 tcp
129 {
130 port 7001
131 enable_v4 yes
132 enable_v6 no
133 }
134 }
135 )CONFIG";
136
137 parseConfig(CONFIG, true);
138 parseConfig(CONFIG, false);
139
140 checkChannelListEqual(factory, {"tcp4://0.0.0.0:7001"});
Junxiao Shi38b24c72017-01-05 02:59:31 +0000141}
142
Alexander Afanasyevded17422018-04-03 19:00:23 -0400143BOOST_AUTO_TEST_CASE(ConfigureLocal)
144{
145 const std::string CONFIG = R"CONFIG(
146 face_system
147 {
148 tcp
149 {
150 local {
151 whitelist {
152 subnet 127.0.0.0/8
153 }
154
155 blacklist {
156 subnet ::1/128
157 }
158 }
159 }
160 }
161 )CONFIG";
162
163 parseConfig(CONFIG, true);
164 parseConfig(CONFIG, false);
165
166 BOOST_CHECK_EQUAL(factory.m_local.m_whitelist.size(), 1);
167 BOOST_CHECK_EQUAL(factory.m_local.m_whitelist.count("127.0.0.0/8"), 1);
168 BOOST_CHECK_EQUAL(factory.m_local.m_blacklist.size(), 1);
169 BOOST_CHECK_EQUAL(factory.m_local.m_blacklist.count("::1/128"), 1);
170
171 createFace(factory,
172 FaceUri("tcp4://127.0.0.1:6363"),
173 {},
174 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, false, false},
175 {CreateFaceExpectedResult::SUCCESS, 0, ""},
176 [] (const nfd::Face& face) {
177 BOOST_CHECK_EQUAL(face.getScope(), ndn::nfd::FACE_SCOPE_LOCAL);
178 });
179
180 limitedIo.run(1, 100_ms);
181}
182
183BOOST_AUTO_TEST_CASE(ConfigureNonLocal)
184{
185 const std::string CONFIG = R"CONFIG(
186 face_system
187 {
188 tcp
189 {
190 local {
191 whitelist {
192 *
193 }
194
195 blacklist {
196 subnet 127.0.0.0/8
197 subnet ::1/128
198 }
199 }
200 }
201 }
202 )CONFIG";
203
204 parseConfig(CONFIG, true);
205 parseConfig(CONFIG, false);
206
207 BOOST_CHECK_EQUAL(factory.m_local.m_whitelist.size(), 1);
208 BOOST_CHECK_EQUAL(factory.m_local.m_whitelist.count("*"), 1);
209 BOOST_CHECK_EQUAL(factory.m_local.m_blacklist.size(), 2);
210 BOOST_CHECK_EQUAL(factory.m_local.m_blacklist.count("127.0.0.0/8"), 1);
211 BOOST_CHECK_EQUAL(factory.m_local.m_blacklist.count("::1/128"), 1);
212
213 createFace(factory,
214 FaceUri("tcp4://127.0.0.1:6363"),
215 {},
216 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, false, false},
217 {CreateFaceExpectedResult::SUCCESS, 0, ""},
218 [] (const nfd::Face& face) {
219 BOOST_CHECK_EQUAL(face.getScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
220 });
221
222 limitedIo.run(1, 100_ms);
223}
224
Junxiao Shi38b24c72017-01-05 02:59:31 +0000225BOOST_AUTO_TEST_CASE(Omitted)
226{
227 const std::string CONFIG = R"CONFIG(
228 face_system
229 {
230 }
231 )CONFIG";
232
Junxiao Shi1b65ca12017-01-21 23:04:41 +0000233 parseConfig(CONFIG, true);
234 parseConfig(CONFIG, false);
Junxiao Shi38b24c72017-01-05 02:59:31 +0000235
Junxiao Shi38b24c72017-01-05 02:59:31 +0000236 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
237}
238
Davide Pesavento494a9552018-02-04 22:16:05 -0500239BOOST_AUTO_TEST_CASE(AllDisabled)
240{
241 const std::string CONFIG = R"CONFIG(
242 face_system
243 {
244 tcp
245 {
246 enable_v4 no
247 enable_v6 no
248 }
249 }
250 )CONFIG";
251
252 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
253 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
254}
255
Junxiao Shi38b24c72017-01-05 02:59:31 +0000256BOOST_AUTO_TEST_CASE(BadListen)
257{
258 const std::string CONFIG = R"CONFIG(
259 face_system
260 {
261 tcp
262 {
263 listen hello
264 }
265 }
266 )CONFIG";
267
268 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
269 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
270}
271
Davide Pesavento494a9552018-02-04 22:16:05 -0500272BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(BadPort, 2) // Bug #4489
273BOOST_AUTO_TEST_CASE(BadPort)
Junxiao Shi38b24c72017-01-05 02:59:31 +0000274{
Davide Pesavento494a9552018-02-04 22:16:05 -0500275 // not a number
276 const std::string CONFIG1 = R"CONFIG(
Junxiao Shi38b24c72017-01-05 02:59:31 +0000277 face_system
278 {
279 tcp
280 {
Davide Pesavento494a9552018-02-04 22:16:05 -0500281 port hello
Junxiao Shi38b24c72017-01-05 02:59:31 +0000282 }
283 }
284 )CONFIG";
285
Davide Pesavento494a9552018-02-04 22:16:05 -0500286 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
287 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
288
289 // negative number
290 const std::string CONFIG2 = R"CONFIG(
291 face_system
292 {
293 tcp
294 {
295 port -1
296 }
297 }
298 )CONFIG";
299
300 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
301 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
302
303 // out of range
304 const std::string CONFIG3 = R"CONFIG(
305 face_system
306 {
307 tcp
308 {
309 port 65536
310 }
311 }
312 )CONFIG";
313
314 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
315 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
Junxiao Shi38b24c72017-01-05 02:59:31 +0000316}
317
318BOOST_AUTO_TEST_CASE(UnknownOption)
319{
320 const std::string CONFIG = R"CONFIG(
321 face_system
322 {
323 tcp
324 {
325 hello
326 }
327 }
328 )CONFIG";
329
330 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
331 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
332}
333
334BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
335
Davide Pesaventob15276f2017-07-15 16:27:13 -0400336BOOST_AUTO_TEST_CASE(GetChannels)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700337{
Davide Pesaventob15276f2017-07-15 16:27:13 -0400338 BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
339
340 std::set<std::string> expected;
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400341 expected.insert(createChannel("127.0.0.1", "20070")->getUri().toString());
342 expected.insert(createChannel("127.0.0.1", "20071")->getUri().toString());
343 expected.insert(createChannel("::1", "20071")->getUri().toString());
Davide Pesaventob15276f2017-07-15 16:27:13 -0400344 checkChannelListEqual(factory, expected);
345}
346
347BOOST_AUTO_TEST_CASE(CreateChannel)
348{
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400349 auto channel1 = createChannel("127.0.0.1", "20070");
350 auto channel1a = createChannel("127.0.0.1", "20070");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700351 BOOST_CHECK_EQUAL(channel1, channel1a);
352 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "tcp4://127.0.0.1:20070");
353
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400354 auto channel2 = createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700355 BOOST_CHECK_NE(channel1, channel2);
356
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400357 auto channel3 = createChannel("::1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700358 BOOST_CHECK_NE(channel2, channel3);
359 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "tcp6://[::1]:20071");
360}
361
Davide Pesaventob15276f2017-07-15 16:27:13 -0400362BOOST_AUTO_TEST_CASE(CreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700363{
Eric Newberry42602412016-08-27 09:33:18 -0700364 createFace(factory,
365 FaceUri("tcp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000366 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700367 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -0700368 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700369
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400370 createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700371
Eric Newberry42602412016-08-27 09:33:18 -0700372 createFace(factory,
Eric Newberry78e32b02017-04-01 14:34:44 +0000373 FaceUri("tcp4://127.0.0.1:6363"),
374 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700375 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -0700376 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400377
378 createFace(factory,
379 FaceUri("tcp4://127.0.0.1:6363"),
380 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700381 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, false, false, false},
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400382 {CreateFaceExpectedResult::SUCCESS, 0, ""});
383
384 createFace(factory,
385 FaceUri("tcp4://127.0.0.1:20072"),
386 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700387 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, false, false, false},
Eric Newberry2642cd22017-07-13 21:34:53 -0400388 {CreateFaceExpectedResult::SUCCESS, 0, ""});
389
390 createFace(factory,
391 FaceUri("tcp4://127.0.0.1:20073"),
392 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700393 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, true, false},
394 {CreateFaceExpectedResult::SUCCESS, 0, ""});
395
396 createFace(factory,
397 FaceUri("tcp4://127.0.0.1:20073"),
398 {},
399 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, false, true},
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400400 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700401}
402
Davide Pesaventob15276f2017-07-15 16:27:13 -0400403BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700404{
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400405 createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700406
Eric Newberry42602412016-08-27 09:33:18 -0700407 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400408 FaceUri("tcp4://127.0.0.1:20072"),
Eric Newberry42602412016-08-27 09:33:18 -0700409 FaceUri("tcp4://127.0.0.1:20071"),
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700410 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -0400411 {CreateFaceExpectedResult::FAILURE, 406,
412 "Unicast TCP faces cannot be created with a LocalUri"});
413
414 createFace(factory,
415 FaceUri("tcp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000416 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700417 {ndn::nfd::FACE_PERSISTENCY_ON_DEMAND, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -0700418 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400419 "Outgoing TCP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +0000420
421 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400422 FaceUri("tcp4://198.51.100.100:6363"),
423 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700424 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, true, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -0400425 {CreateFaceExpectedResult::FAILURE, 406,
426 "Local fields can only be enabled on faces with local scope"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700427}
428
Davide Pesaventob15276f2017-07-15 16:27:13 -0400429class CreateFaceTimeoutFixture : public TcpFactoryFixture
Junxiao Shicde37ad2015-12-24 01:02:05 -0700430{
431public:
432 void
Davide Pesavento494a9552018-02-04 22:16:05 -0500433 onFaceCreated(const shared_ptr<nfd::Face>& newFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700434 {
435 BOOST_CHECK_MESSAGE(false, "Timeout expected");
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400436 face = newFace;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700437
438 limitedIo.afterOp();
439 }
440
441 void
442 onConnectFailed(const std::string& reason)
443 {
444 BOOST_CHECK_MESSAGE(true, reason);
445
446 limitedIo.afterOp();
447 }
448
449public:
Davide Pesavento494a9552018-02-04 22:16:05 -0500450 shared_ptr<nfd::Face> face;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700451};
452
Davide Pesaventob15276f2017-07-15 16:27:13 -0400453BOOST_FIXTURE_TEST_CASE(CreateFaceTimeout, CreateFaceTimeoutFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700454{
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400455 createChannel("0.0.0.0", "20070");
Davide Pesavento15b55052018-01-27 19:09:28 -0500456 factory.createFace({FaceUri("tcp4://192.0.2.1:20070"), {}, {}},
Davide Pesaventob15276f2017-07-15 16:27:13 -0400457 bind(&CreateFaceTimeoutFixture::onFaceCreated, this, _1),
458 bind(&CreateFaceTimeoutFixture::onConnectFailed, this, _2));
Junxiao Shicde37ad2015-12-24 01:02:05 -0700459
Davide Pesavento15b55052018-01-27 19:09:28 -0500460 BOOST_REQUIRE_EQUAL(limitedIo.run(1, 10_s), LimitedIo::EXCEED_OPS);
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400461 BOOST_CHECK(face == nullptr);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700462}
463
Junxiao Shicde37ad2015-12-24 01:02:05 -0700464BOOST_AUTO_TEST_SUITE_END() // TestTcpFactory
465BOOST_AUTO_TEST_SUITE_END() // Face
466
467} // namespace tests
Junxiao Shi38b24c72017-01-05 02:59:31 +0000468} // namespace face
Junxiao Shicde37ad2015-12-24 01:02:05 -0700469} // namespace nfd