blob: d1432513aec408b1bfcb5f8cc3499c571400447b [file] [log] [blame]
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +01001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
Alexander Afanasyev0eb70652014-02-27 18:35:07 -08007#include "face/unix-stream-factory.hpp"
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +01008#include <ndn-cpp-dev/security/key-chain.hpp>
9
Junxiao Shid9ee45c2014-02-27 15:38:11 -070010#include "tests/test-common.hpp"
Junxiao Shi7e2413b2014-03-02 11:15:09 -070011#include "tests/core/limited-io.hpp"
Junxiao Shid9ee45c2014-02-27 15:38:11 -070012
13namespace nfd {
14namespace tests {
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010015
16using namespace boost::asio::local;
17
Junxiao Shid9ee45c2014-02-27 15:38:11 -070018BOOST_FIXTURE_TEST_SUITE(FaceUnixStream, BaseFixture)
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010019
20BOOST_AUTO_TEST_CASE(ChannelMap)
21{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080022 UnixStreamFactory factory;
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010023
Alexander Afanasyevd6655302014-02-28 08:41:28 -080024 shared_ptr<UnixStreamChannel> channel1 = factory.createChannel("foo");
25 shared_ptr<UnixStreamChannel> channel1a = factory.createChannel("foo");
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010026 BOOST_CHECK_EQUAL(channel1, channel1a);
27
Alexander Afanasyevd6655302014-02-28 08:41:28 -080028 shared_ptr<UnixStreamChannel> channel2 = factory.createChannel("bar");
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010029 BOOST_CHECK_NE(channel1, channel2);
30}
31
Junxiao Shid9ee45c2014-02-27 15:38:11 -070032class EndToEndFixture : protected BaseFixture
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010033{
34public:
35 void
36 client_onConnect(const boost::system::error_code& error)
37 {
38 BOOST_CHECK_MESSAGE(!error, error.message());
39
Junxiao Shi7e2413b2014-03-02 11:15:09 -070040 m_limitedIo.afterOp();
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010041 }
42
43 void
44 channel1_onFaceCreated(const shared_ptr<UnixStreamFace>& newFace)
45 {
46 BOOST_CHECK(!static_cast<bool>(m_face1));
47 m_face1 = newFace;
48 m_face1->onReceiveInterest +=
49 bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
50 m_face1->onReceiveData +=
51 bind(&EndToEndFixture::face1_onReceiveData, this, _1);
52
Junxiao Shi7e2413b2014-03-02 11:15:09 -070053 m_limitedIo.afterOp();
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010054 }
55
56 void
57 channel1_onConnectFailed(const std::string& reason)
58 {
59 BOOST_CHECK_MESSAGE(false, reason);
60
Junxiao Shi7e2413b2014-03-02 11:15:09 -070061 m_limitedIo.afterOp();
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010062 }
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080063
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010064 void
65 face1_onReceiveInterest(const Interest& interest)
66 {
67 m_face1_receivedInterests.push_back(interest);
68
Junxiao Shi7e2413b2014-03-02 11:15:09 -070069 m_limitedIo.afterOp();
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010070 }
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080071
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010072 void
73 face1_onReceiveData(const Data& data)
74 {
75 m_face1_receivedDatas.push_back(data);
76
Junxiao Shi7e2413b2014-03-02 11:15:09 -070077 m_limitedIo.afterOp();
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010078 }
79
80 void
81 face2_onReceiveInterest(const Interest& interest)
82 {
83 m_face2_receivedInterests.push_back(interest);
84
Junxiao Shi7e2413b2014-03-02 11:15:09 -070085 m_limitedIo.afterOp();
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010086 }
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080087
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010088 void
89 face2_onReceiveData(const Data& data)
90 {
91 m_face2_receivedDatas.push_back(data);
92
Junxiao Shi7e2413b2014-03-02 11:15:09 -070093 m_limitedIo.afterOp();
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010094 }
95
96 void
97 channel_onFaceCreated(const shared_ptr<UnixStreamFace>& newFace)
98 {
99 m_faces.push_back(newFace);
100
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700101 m_limitedIo.afterOp();
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100102 }
103
104 void
105 channel_onConnectFailed(const std::string& reason)
106 {
107 BOOST_CHECK_MESSAGE(false, reason);
108
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700109 m_limitedIo.afterOp();
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100110 }
111
112protected:
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700113 LimitedIo m_limitedIo;
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100114
115 shared_ptr<UnixStreamFace> m_face1;
116 std::vector<Interest> m_face1_receivedInterests;
117 std::vector<Data> m_face1_receivedDatas;
118 shared_ptr<UnixStreamFace> m_face2;
119 std::vector<Interest> m_face2_receivedInterests;
120 std::vector<Data> m_face2_receivedDatas;
121
122 std::list< shared_ptr<UnixStreamFace> > m_faces;
123};
124
125
126BOOST_FIXTURE_TEST_CASE(EndToEnd, EndToEndFixture)
127{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800128 UnixStreamFactory factory;
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100129
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800130 shared_ptr<UnixStreamChannel> channel1 = factory.createChannel("foo");
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100131 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
132 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
133
134 shared_ptr<stream_protocol::socket> client =
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800135 make_shared<stream_protocol::socket>(boost::ref(g_io));
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100136 client->async_connect(stream_protocol::endpoint("foo"),
137 bind(&EndToEndFixture::client_onConnect, this, _1));
138
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700139 BOOST_CHECK_MESSAGE(m_limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
140 "UnixStreamChannel error: cannot connect or cannot accept connection");
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100141
142 BOOST_REQUIRE(static_cast<bool>(m_face1));
143
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100144 m_face2 = make_shared<UnixStreamFace>(client);
145 m_face2->onReceiveInterest +=
146 bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
147 m_face2->onReceiveData +=
148 bind(&EndToEndFixture::face2_onReceiveData, this, _1);
149
150 Interest interest1("ndn:/TpnzGvW9R");
151 Data data1 ("ndn:/KfczhUqVix");
152 data1.setContent(0, 0);
153 Interest interest2("ndn:/QWiIMfj5sL");
154 Data data2 ("ndn:/XNBV796f");
155 data2.setContent(0, 0);
156
157 ndn::SignatureSha256WithRsa fakeSignature;
158 fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
159
160 // set fake signature on data1 and data2
161 data1.setSignature(fakeSignature);
162 data2.setSignature(fakeSignature);
163
164 m_face1->sendInterest(interest1);
165 m_face1->sendData (data1 );
166 m_face2->sendInterest(interest2);
167 m_face2->sendData (data2 );
168
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700169 BOOST_CHECK_MESSAGE(m_limitedIo.run(4, time::seconds(1)) == LimitedIo::EXCEED_OPS,
170 "UnixStreamChannel error: cannot send or receive Interest/Data packets");
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100171
172 BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
173 BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 1);
174 BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
175 BOOST_REQUIRE_EQUAL(m_face2_receivedDatas .size(), 1);
176
177 BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
178 BOOST_CHECK_EQUAL(m_face1_receivedDatas [0].getName(), data2.getName());
179 BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
180 BOOST_CHECK_EQUAL(m_face2_receivedDatas [0].getName(), data1.getName());
181}
182
183BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
184{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800185 UnixStreamFactory factory;
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100186
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800187 shared_ptr<UnixStreamChannel> channel = factory.createChannel("foo");
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100188 channel->listen(bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
189 bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
190
191 shared_ptr<stream_protocol::socket> client1 =
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800192 make_shared<stream_protocol::socket>(boost::ref(g_io));
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100193 client1->async_connect(stream_protocol::endpoint("foo"),
194 bind(&EndToEndFixture::client_onConnect, this, _1));
195
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700196 BOOST_CHECK_MESSAGE(m_limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
197 "UnixStreamChannel error: cannot connect or cannot accept connection");
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100198
199 BOOST_CHECK_EQUAL(m_faces.size(), 1);
200
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100201 shared_ptr<stream_protocol::socket> client2 =
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800202 make_shared<stream_protocol::socket>(boost::ref(g_io));
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100203 client2->async_connect(stream_protocol::endpoint("foo"),
204 bind(&EndToEndFixture::client_onConnect, this, _1));
205
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700206 BOOST_CHECK_MESSAGE(m_limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
207 "UnixStreamChannel error: cannot accept multiple connections");
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100208
209 BOOST_CHECK_EQUAL(m_faces.size(), 2);
210
211 // now close one of the faces
212 m_faces.front()->close();
213
214 // we should still be able to send/receive with the other one
215 m_face1 = m_faces.back();
216 m_face1->onReceiveInterest +=
217 bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
218 m_face1->onReceiveData +=
219 bind(&EndToEndFixture::face1_onReceiveData, this, _1);
220
221 m_face2 = make_shared<UnixStreamFace>(client2);
222 m_face2->onReceiveInterest +=
223 bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
224 m_face2->onReceiveData +=
225 bind(&EndToEndFixture::face2_onReceiveData, this, _1);
226
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100227 Interest interest1("ndn:/TpnzGvW9R");
228 Data data1 ("ndn:/KfczhUqVix");
229 data1.setContent(0, 0);
230 Interest interest2("ndn:/QWiIMfj5sL");
231 Data data2 ("ndn:/XNBV796f");
232 data2.setContent(0, 0);
233
234 ndn::SignatureSha256WithRsa fakeSignature;
235 fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
236
237 // set fake signature on data1 and data2
238 data1.setSignature(fakeSignature);
239 data2.setSignature(fakeSignature);
240
241 m_face1->sendInterest(interest1);
242 m_face1->sendData (data1 );
243 m_face2->sendInterest(interest2);
244 m_face2->sendData (data2 );
245
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700246 BOOST_CHECK_MESSAGE(m_limitedIo.run(4, time::seconds(1)) == LimitedIo::EXCEED_OPS,
247 "UnixStreamChannel error: cannot send or receive Interest/Data packets");
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100248
249 BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
250 BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 1);
251 BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
252 BOOST_REQUIRE_EQUAL(m_face2_receivedDatas .size(), 1);
253
254 BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
255 BOOST_CHECK_EQUAL(m_face1_receivedDatas [0].getName(), data2.getName());
256 BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
257 BOOST_CHECK_EQUAL(m_face2_receivedDatas [0].getName(), data1.getName());
258}
259
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800260static inline void
261noOp()
262{
263}
264
265BOOST_FIXTURE_TEST_CASE(UnixStreamFaceLocalControlHeader, EndToEndFixture)
266{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800267 UnixStreamFactory factory;
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800268
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800269 shared_ptr<UnixStreamChannel> channel1 = factory.createChannel("foo");
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800270 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
271 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
272
273 shared_ptr<stream_protocol::socket> client =
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800274 make_shared<stream_protocol::socket>(boost::ref(g_io));
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800275 client->async_connect(stream_protocol::endpoint("foo"),
276 bind(&EndToEndFixture::client_onConnect, this, _1));
277
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700278 BOOST_CHECK_MESSAGE(m_limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
279 "UnixStreamChannel error: cannot connect or cannot accept connection");
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800280
281 BOOST_REQUIRE(static_cast<bool>(m_face1));
282
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800283 m_face2 = make_shared<UnixStreamFace>(client);
284 m_face2->onReceiveInterest +=
285 bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
286 m_face2->onReceiveData +=
287 bind(&EndToEndFixture::face2_onReceiveData, this, _1);
288
289 Interest interest1("ndn:/TpnzGvW9R");
290 Data data1 ("ndn:/KfczhUqVix");
291 data1.setContent(0, 0);
292 Interest interest2("ndn:/QWiIMfj5sL");
293 Data data2 ("ndn:/XNBV796f");
294 data2.setContent(0, 0);
295
296 ndn::SignatureSha256WithRsa fakeSignature;
297 fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
298
299 // set fake signature on data1 and data2
300 data1.setSignature(fakeSignature);
301 data2.setSignature(fakeSignature);
302
303 m_face1->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID);
304 m_face1->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID);
305
306 BOOST_CHECK(m_face1->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID));
307 BOOST_CHECK(m_face1->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID));
308
309 m_face2->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID);
310 m_face2->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID);
311
312 BOOST_CHECK(m_face2->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID));
313 BOOST_CHECK(m_face2->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID));
314
315 ////////////////////////////////////////////////////////
316
317 interest1.setIncomingFaceId(11);
318 interest1.setNextHopFaceId(111);
319
320 m_face1->sendInterest(interest1);
321
322 data1.setIncomingFaceId(22);
323 data1.getLocalControlHeader().setNextHopFaceId(222);
324
325 m_face1->sendData (data1);
326
327 //
328
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700329 BOOST_CHECK_MESSAGE(m_limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
330 "UnixStreamChannel error: cannot send or receive Interest/Data packets");
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800331
332 BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
333 BOOST_REQUIRE_EQUAL(m_face2_receivedDatas .size(), 1);
334
335 // sending allows only IncomingFaceId, receiving allows only NextHopFaceId
336 BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getLocalControlHeader().hasIncomingFaceId(), false);
337 BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getLocalControlHeader().hasNextHopFaceId(), false);
338
339 BOOST_CHECK_EQUAL(m_face2_receivedDatas[0].getLocalControlHeader().hasIncomingFaceId(), false);
340 BOOST_CHECK_EQUAL(m_face2_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
341
342 ////////////////////////////////////////////////////////
343
344 using namespace boost::asio;
345
346 std::vector<const_buffer> interestWithHeader;
347 Block iHeader = interest1.getLocalControlHeader().wireEncode(interest1, true, true);
348 Block iPayload = interest1.wireEncode();
349 interestWithHeader.push_back(buffer(iHeader.wire(), iHeader.size()));
350 interestWithHeader.push_back(buffer(iPayload.wire(), iPayload.size()));
351
352 std::vector<const_buffer> dataWithHeader;
353 Block dHeader = data1.getLocalControlHeader().wireEncode(data1, true, true);
354 Block dPayload = data1.wireEncode();
355 dataWithHeader.push_back(buffer(dHeader.wire(), dHeader.size()));
356 dataWithHeader.push_back(buffer(dPayload.wire(), dPayload.size()));
357
358 //
359
360 client->async_send(interestWithHeader, bind(&noOp));
361 client->async_send(dataWithHeader, bind(&noOp));
362
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700363 BOOST_CHECK_MESSAGE(m_limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
364 "UnixStreamChannel error: cannot send or receive Interest/Data packets");
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800365
366 BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
367 BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 1);
368
369 BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getLocalControlHeader().hasIncomingFaceId(), false);
370 BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getLocalControlHeader().hasNextHopFaceId(), true);
371 BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getNextHopFaceId(), 111);
372
373 BOOST_CHECK_EQUAL(m_face1_receivedDatas[0].getLocalControlHeader().hasIncomingFaceId(), false);
374 BOOST_CHECK_EQUAL(m_face1_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
375}
376
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100377BOOST_AUTO_TEST_SUITE_END()
378
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700379} // namespace tests
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +0100380} // namespace nfd