blob: 837262c408749519655904e4f1a4db18a03fe4d1 [file] [log] [blame]
Junxiao Shicde37ad2015-12-24 01:02:05 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2015, Regents of the University of California,
4 * 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/udp-factory.hpp"
27
28#include "core/network-interface.hpp"
29#include "tests/test-common.hpp"
30#include "tests/limited-io.hpp"
31
32namespace nfd {
33namespace tests {
34
35BOOST_AUTO_TEST_SUITE(Face)
36BOOST_FIXTURE_TEST_SUITE(TestUdpFactory, BaseFixture)
37
38using nfd::Face;
39
40BOOST_AUTO_TEST_CASE(GetChannels)
41{
42 UdpFactory factory;
43 BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
44
45 std::vector<shared_ptr<const Channel>> expectedChannels;
46 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
47 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
48 expectedChannels.push_back(factory.createChannel("::1", "20071"));
49
50 for (const auto& i : factory.getChannels()) {
51 auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), i);
52 BOOST_REQUIRE(pos != expectedChannels.end());
53 expectedChannels.erase(pos);
54 }
55
56 BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
57}
58
59class FactoryErrorCheck : public BaseFixture
60{
61public:
62 bool
63 isTheSameMulticastEndpoint(const UdpFactory::Error& e) {
64 return strcmp(e.what(),
65 "Cannot create the requested UDP unicast channel, local "
66 "endpoint is already allocated for a UDP multicast face") == 0;
67 }
68
69 bool
70 isNotMulticastAddress(const UdpFactory::Error& e) {
71 return strcmp(e.what(),
72 "Cannot create the requested UDP multicast face, "
73 "the multicast group given as input is not a multicast address") == 0;
74 }
75
76 bool
77 isTheSameUnicastEndpoint(const UdpFactory::Error& e) {
78 return strcmp(e.what(),
79 "Cannot create the requested UDP multicast face, local "
80 "endpoint is already allocated for a UDP unicast channel") == 0;
81 }
82
83 bool
84 isLocalEndpointOnDifferentGroup(const UdpFactory::Error& e) {
85 return strcmp(e.what(),
86 "Cannot create the requested UDP multicast face, local "
87 "endpoint is already allocated for a UDP multicast face "
88 "on a different multicast group") == 0;
89 }
90};
91
92BOOST_FIXTURE_TEST_CASE(ChannelMapUdp, FactoryErrorCheck)
93{
94 using boost::asio::ip::udp;
95
96 UdpFactory factory = UdpFactory();
97
98 //to instantiate multicast face on a specific ip address, change interfaceIp
99 std::string interfaceIp = "0.0.0.0";
100
101 shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
102 shared_ptr<UdpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
103 BOOST_CHECK_EQUAL(channel1, channel1a);
104 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
105
106 shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
107 BOOST_CHECK_NE(channel1, channel2);
108
109 shared_ptr<UdpChannel> channel3 = factory.createChannel(interfaceIp, "20070");
110
111 shared_ptr<UdpChannel> channel4 = factory.createChannel("::1", "20071");
112 BOOST_CHECK_NE(channel2, channel4);
113 BOOST_CHECK_EQUAL(channel4->getUri().toString(), "udp6://[::1]:20071");
114
115 //same endpoint of a unicast channel
116 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp, "224.0.0.1", "20070"),
117 UdpFactory::Error, isTheSameUnicastEndpoint);
118
119 auto multicastFace1 = factory.createMulticastFace(interfaceIp, "224.0.0.1", "20072");
120 auto multicastFace1a = factory.createMulticastFace(interfaceIp, "224.0.0.1", "20072");
121 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
122
123 //same endpoint of a multicast face
124 BOOST_CHECK_EXCEPTION(factory.createChannel(interfaceIp, "20072"),
125 UdpFactory::Error, isTheSameMulticastEndpoint);
126
127 //same multicast endpoint, different group
128 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp, "224.0.0.42", "20072"),
129 UdpFactory::Error, isLocalEndpointOnDifferentGroup);
130
131 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp, "192.168.10.15", "20025"),
132 UdpFactory::Error, isNotMulticastAddress);
133
134
135// //Test commented because it required to be run in a machine that can resolve ipv6 query
136// shared_ptr<UdpChannel> channel1v6 = factory.createChannel(//"::1",
137// "fe80::5e96:9dff:fe7d:9c8d%en1",
138// //"fe80::aa54:b2ff:fe08:27b8%wlan0",
139// "20070");
140//
141// //the creation of multicastFace2 works properly. It has been disable because it needs an IP address of
142// //an available network interface (different from the first one used)
143// shared_ptr<MulticastUdpFace> multicastFace2 = factory.createMulticastFace("192.168.1.17",
144// "224.0.0.1",
145// "20073");
146// BOOST_CHECK_NE(multicastFace1, multicastFace2);
147//
148//
149// //ipv6 - work in progress
150// shared_ptr<MulticastUdpFace> multicastFace3 = factory.createMulticastFace("fe80::5e96:9dff:fe7d:9c8d%en1",
151// "FF01:0:0:0:0:0:0:2",
152// "20073");
153//
154// shared_ptr<MulticastUdpFace> multicastFace4 = factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
155// "FF01:0:0:0:0:0:0:2",
156// "20073");
157//
158// BOOST_CHECK_EQUAL(multicastFace3, multicastFace4);
159//
160// shared_ptr<MulticastUdpFace> multicastFace5 = factory.createMulticastFace("::1",
161// "FF01:0:0:0:0:0:0:2",
162// "20073");
163//
164// BOOST_CHECK_NE(multicastFace3, multicastFace5);
165//
166// //same local ipv6 endpoint for a different multicast group
167// BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
168// "FE01:0:0:0:0:0:0:2",
169// "20073"),
170// UdpFactory::Error);
171//
172// //same local ipv6 (expect for th port number) endpoint for a different multicast group
173// BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
174// "FE01:0:0:0:0:0:0:2",
175// "20075"),
176// UdpFactory::Error);
177//
178// BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
179// "FE12:0:0:0:0:0:0:2",
180// "20075"),
181// UdpFactory::Error);
182//
183// //not a multicast ipv6
184// BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
185// "A112:0:0:0:0:0:0:2",
186// "20075"),
187// UdpFactory::Error);
188}
189
190class FaceCreateFixture : protected BaseFixture
191{
192public:
193 void
194 checkError(const std::string& errorActual, const std::string& errorExpected)
195 {
196 BOOST_CHECK_EQUAL(errorActual, errorExpected);
197 }
198
199 void
200 failIfError(const std::string& errorActual)
201 {
202 BOOST_FAIL("No error expected, but got: [" << errorActual << "]");
203 }
204};
205
206BOOST_FIXTURE_TEST_CASE(FaceCreate, FaceCreateFixture)
207{
208 UdpFactory factory = UdpFactory();
209
210 factory.createFace(FaceUri("udp4://127.0.0.1:6363"),
211 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
212 bind([]{}),
213 bind(&FaceCreateFixture::checkError, this, _1,
214 "No channels available to connect to 127.0.0.1:6363"));
215
216 factory.createChannel("127.0.0.1", "20071");
217
218 factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
219 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
220 bind([]{}),
221 bind(&FaceCreateFixture::failIfError, this, _1));
222 //test the upgrade
223 factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
224 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
225 bind([]{}),
226 bind(&FaceCreateFixture::failIfError, this, _1));
227
228 factory.createFace(FaceUri("udp4://127.0.0.1:20072"),
229 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
230 bind([]{}),
231 bind(&FaceCreateFixture::failIfError, this, _1));
232}
233
234BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
235{
236 UdpFactory factory;
237
238 factory.createChannel("127.0.0.1", "20070");
239
240 BOOST_CHECK_THROW(factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
241 ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
242 bind([]{}),
243 bind([]{})),
244 ProtocolFactory::Error);
245}
246
247class FakeNetworkInterfaceFixture : public BaseFixture
248{
249public:
250 FakeNetworkInterfaceFixture()
251 {
252 using namespace boost::asio::ip;
253
254 auto fakeInterfaces = make_shared<std::vector<NetworkInterfaceInfo>>();
255
256 fakeInterfaces->push_back(
257 NetworkInterfaceInfo {0, "eth0",
258 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
259 {address_v4::from_string("0.0.0.0")},
260 {address_v6::from_string("::")},
261 address_v4(),
262 IFF_UP});
263 fakeInterfaces->push_back(
264 NetworkInterfaceInfo {1, "eth0",
265 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
266 {address_v4::from_string("192.168.2.1"), address_v4::from_string("192.168.2.2")},
267 {},
268 address_v4::from_string("192.168.2.255"),
269 0});
270 fakeInterfaces->push_back(
271 NetworkInterfaceInfo {2, "eth1",
272 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
273 {address_v4::from_string("198.51.100.1")},
274 {address_v6::from_string("2001:db8::2"), address_v6::from_string("2001:db8::3")},
275 address_v4::from_string("198.51.100.255"),
276 IFF_MULTICAST | IFF_BROADCAST | IFF_UP});
277
278 setDebugNetworkInterfaces(fakeInterfaces);
279 }
280
281 ~FakeNetworkInterfaceFixture()
282 {
283 setDebugNetworkInterfaces(nullptr);
284 }
285};
286
287BOOST_FIXTURE_TEST_CASE(Bug2292, FakeNetworkInterfaceFixture)
288{
289 using namespace boost::asio::ip;
290
291 UdpFactory factory;
292 factory.prohibitEndpoint(udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024));
293 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
294 BOOST_CHECK((factory.m_prohibitedEndpoints ==
295 std::set<udp::Endpoint> {
296 udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
297 }));
298
299 factory.m_prohibitedEndpoints.clear();
300 factory.prohibitEndpoint(udp::Endpoint(address_v6::from_string("2001:db8::1"), 2048));
301 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
302 BOOST_CHECK((factory.m_prohibitedEndpoints ==
303 std::set<udp::Endpoint> {
304 udp::Endpoint(address_v6::from_string("2001:db8::1"), 2048),
305 }));
306
307 factory.m_prohibitedEndpoints.clear();
308 factory.prohibitEndpoint(udp::Endpoint(address_v4(), 1024));
309 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 6);
310 BOOST_CHECK((factory.m_prohibitedEndpoints ==
311 std::set<udp::Endpoint> {
312 udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
313 udp::Endpoint(address_v4::from_string("192.168.2.2"), 1024),
314 udp::Endpoint(address_v4::from_string("198.51.100.1"), 1024),
315 udp::Endpoint(address_v4::from_string("198.51.100.255"), 1024),
316 udp::Endpoint(address_v4::from_string("255.255.255.255"), 1024),
317 udp::Endpoint(address_v4::from_string("0.0.0.0"), 1024)
318 }));
319
320 factory.m_prohibitedEndpoints.clear();
321 factory.prohibitEndpoint(udp::Endpoint(address_v6(), 2048));
322 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 3);
323 BOOST_CHECK((factory.m_prohibitedEndpoints ==
324 std::set<udp::Endpoint> {
325 udp::Endpoint(address_v6::from_string("2001:db8::2"), 2048),
326 udp::Endpoint(address_v6::from_string("2001:db8::3"), 2048),
327 udp::Endpoint(address_v6::from_string("::"), 2048),
328 }));
329}
330
331BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
332BOOST_AUTO_TEST_SUITE_END() // Face
333
334} // namespace tests
335} // namespace nfd