Compare commits

...
333 Commits
Author SHA1 Message Date
spirosmastorakis 704430ca07 table: Fixing Pit::erase crash if the Interest name contains implicit digest
Change-Id: I471023fc23ffaebe04d9668426b4c1b03e4973ac
Refs: #3608
2016-05-03 08:53:09 -08:00
Alexander Afanasyev 58d479cd4a docs+build: Prepare release of version 0.4.1
Change-Id: I03fc06c2b2f5be87e86a1fa1ab6eca83e8cc07a0
Refs: #3385
2016-03-24 14:00:09 -07:00
Davide Pesavento 305529410b build: fix pthread detection code in boost tool
It failed to build with several "null argument where
non-null required" errors on some Linux systems.

Change-Id: Ia3dccf3bb0e63d80d73b870632adc3308da6ecd0
2016-03-22 16:39:00 -08:00
Yanbiao Li 150b80deee tests: concatenate StatusDataset respones after all segments are fetched
Change-Id: Ia1c5b973b40c764d6a00fdd681ae4ade123eb7ab
refs: #2182
2016-03-18 08:25:35 -08:00
Weiwei Liu 280d7dde50 face: improve WebSocketChannel test suite
Change-Id: I7b3dfa930713331e6911a57624727163b8a7b3fe
Refs: #3373
2016-03-18 03:31:36 +01:00
Alexander Afanasyev 8509398137 build: Fix detection of Boost.Log compile flags
Change-Id: Ifdd5c485930a0bc50c1cbd76525947b001b44822
Refs: #2513
2016-03-11 13:44:37 -08:00
Davide Pesavento 42388d6c08 tools: delete deprecated ndn-tlv-peek and ndn-tlv-poke
Superseded by ndnpeek and ndnpoke from ndn-tools repo.

Change-Id: Ief379c53d73e0b3e8e0092dfb22b55c6de0de2b1
Refs: #2819
2016-03-10 12:54:48 -08:00
Minsheng Zhang ffe8bbb8aa table: allow setting CS capacity limit to zero
refs #3503

Change-Id: I6e1bfb64ea3a1f31070a7290c250fbcec46623fb
2016-03-10 13:40:37 -07:00
Junxiao Shi 330136a89e fw: fix PIT leak from DNL-detected duplicate Nonce
refs #3484

Change-Id: Id5928356a39b2f8988b6d4969c15ac744d283e3f
2016-03-10 04:53:08 -07:00
Spencer Lee bb9102f7d4 face: improve UdpChannel test suite
Change-Id: I90124bf6701639ea38154a6e3e62918dfbcfa6dd
Refs: #3371
2016-03-08 18:13:11 +01:00
Vince Lehman 4310d505a7 rib: Fix use-after-free in RibEntry::getRouteWithSecondLowestCostByFaceId
refs: #3319

Change-Id: I7c6aeb541a7cd7d83965a87e50be1a0bdf633a2e
2016-03-07 11:08:29 -06:00
Spencer Lee d5fe0cf158 face: improve TcpChannel test suite
Change-Id: I751eb58d5b794bc6ba6f77c065fe6616cfc07ced
Refs: #3370
2016-03-04 02:03:53 +01:00
Weiwei Liu 9360623853 face: improve WebSocketTransport test suite
refs #3374

Change-Id: I6ebfee61ec5f793f21a33071aa2e76295a5b496a
2016-03-03 11:09:06 -08:00
Alexander Afanasyev e6f0e91590 build: Update boost tool
Change-Id: I4255b617c3f6b9dab068114aa01caaf5e2c22569
Refs: #2513
2016-03-03 11:03:16 -08:00
Alexander Afanasyev dd7e5da016 build: Fix compatibility with Python 3
Change-Id: I7a1b98c38c2ed3a147c7b0e6c7b79d2723f2a3ba
Refs: #3493
2016-03-03 08:39:39 -08:00
Davide Pesavento 459cf197b7 tests: fix build with clang 3.8
Change-Id: Idcb5db7b3c0dc645aa569b70b4ea8df9858b7cd4
Refs: #3498
2016-03-03 02:20:12 +01:00
Weiwei Liu 073da60b19 face: improve Face test suite
refs #3376

Change-Id: Ibc36b16d0e6f620112bfa730ecb30149ddfd7ca5
2016-02-26 17:18:25 -07:00
Junxiao Shi 4370fde844 table: fix PIT not matching full name
refs #3363

Change-Id: I4ff3d02aaf43c3aaba843cfcf6221c218c1cea99
2016-02-24 13:28:45 -08:00
Alexander Afanasyev 965f23dd61 docs: Add licensing statements for NFD and third-party components
Change-Id: I544499af303d020a4275fa8782b2b71656c766be
Refs: #3133
2016-02-23 16:33:15 -08:00
Weiwei Liu 72cee94646 face: improve UdpFactory test suite
refs #3375

Change-Id: I8f6b17e5fcdbcd56cf8a4585993159919035f3a1
2016-02-16 14:34:06 -07:00
Alexander Afanasyev bc9ed49a55 tests: Customize environment to run test cases
This commit minimizes the impact of running unit tests on the host
system. In particular, the test cases will have its own public info and
TPM.

Change-Id: Ic6e78ebd80dea920806ca1898caa6a2eac30348b
2016-01-26 22:41:16 -08:00
Yanbiao Li 6db75f0bd2 rib: delete incorrect assertion in AutoPrefixPropagator::afterEraseRibEntry
Change-Id: Ie78675055317e5297174447ce4782c5e0fafd760
refs: #3362
2016-01-26 01:19:36 -08:00
Junxiao Shi 4100646192 Update copyright notices for files modified in 2016
refs #3415

Change-Id: I187c4709a40d3540e89a59cf678e53cf35ad1676
2016-01-19 07:31:59 -07:00
Alexander Afanasyev 3152abac67 ci: Fix unit test execution with boost 1.60
Change-Id: I461e634e5cdf022fed76ca6b92759b18b1d4aed6
Refs: #3417
2016-01-18 22:44:38 +01:00
Vince Lehman 9aac873415 rib: Don't add inherited routes to RIB entries pending removal
refs: #3404

Change-Id: I33a4ee7aa4e286a562c720656cb9e4ee7753ae05
2016-01-11 17:16:26 -06:00
Alexander Afanasyev da3ba96430 docs+build: Prepare release of version 0.4.0
Change-Id: I3af73fed66b44d708532bbda146376b7f7487d28
Refs: #3008
2015-12-29 20:39:40 -08:00
Junxiao Shi 809462490f mgmt: enhance ForwarderStatusManager test suite
Newly added GeneralStatus dataset as well as its legacy counterpart are tested.
The test suite is simplified with ManagerCommonFixture.

refs #3081

Change-Id: I9a00a6f69866c722d7f7fbaa3e207ae6e2ec79f5
2015-12-29 17:53:18 -07:00
Junxiao Shi 498373dd01 mgmt: publish GeneralStatus dataset
In ForwarderStatusManager, publish ForwarderStatus as a dataset at
/localhost/nfd/status/general.
To maintain backwards compatibility, an Interest to /localhost/nfd/status
also retrieves this dataset.

It's intentional not to update the test suite in this commit,
to illustrate that backwards compatibility is maintained.

refs #3081

Change-Id: I9b636e2e621563185303a7304be402c8221c9863
2015-12-29 17:51:26 -07:00
Eric Newberry c64d30aeff mgmt: re-added expiration time to FaceStatus
refs #3381

Change-Id: I57d3166fc6ed52a54c442a80faffe7a7f4051e1d
2015-12-29 13:11:47 -08:00
Alexander Afanasyev 5c47597be9 tools: Automatically start ndn-autoconfig in nfd-start, if enabled in autoconfig.conf
Change-Id: I09d3fff87f00ce8684e6e304e8327f9d03ca18bf
Refs: #2716
2015-12-28 14:15:50 -08:00
Eric Newberry 6d8ee7acc9 tests: MulticastUdpTransport test suite improvements
refs #3346

Change-Id: I31b272b9b99d97ed317cf534d9e1bc4592bde77d
2015-12-24 20:39:56 -07:00
Junxiao Shi cde37ad608 face: face refactoring completion
* delete old Face
* rename LpFace as Face
* eliminate LpFaceWrapper and use new Face

refs #3172

Change-Id: I08c3a5dfb4cc1b9834b30cccd9ab634535d0608c
2015-12-24 01:02:05 -07:00
Junxiao Shi c5401494fe face: UdpChannel minor refactoring
refs #3172

Change-Id: I36d7a27df6d97e8fc1d8ec76e4e25b7987954cf8
2015-12-23 16:33:22 -07:00
Eric Newberry 65caf20092 tests: UnicastUdpTransport test suite improvements
Fixed m_hasBeenUsedRecently uninitialized in DatagramTransport

refs #3307

Change-Id: I786a84009d9cf01e0bb211c872d4375f46c747fd
2015-12-22 11:26:38 -08:00
Davide Pesavento ca25d72064 face: adjust pcap filter in EthernetTransport to accept only untagged frames
Change-Id: Id14d6e57dc9f7c765f0431335b917c2fe74231c4
Refs: #3348
2015-12-21 19:11:07 -08:00
Alexander Afanasyev f22ebaf7f1 tests+ci: Enable dual XML and HRF output of unit test results
This commit also makes unit tests to run against a debug build, to
ensure assertions are properly evaluated (based on suggestion
in I5f4419ea48d4eb333e9d107115ef3df4123f76e5).

Change-Id: I1bbf14f75aab155ed80a36fc4006f7a5d13f1289
Refs: #2252, #2805
2015-12-21 13:50:29 -08:00
Davide Pesavento f35a5a9b08 tests: in LimitedIo, use std::exception_ptr to avoid slicing
Change-Id: I459792cf80ee189842ada84c3a514134bcd79a29
Refs: #3327
2015-12-18 19:21:46 +01:00
Eric Newberry f68f378a23 tests: UnixStreamTransport test suite improvements
refs #3305

Change-Id: I6c6ca52a5e80266920ded811ff45fc568c3e59b9
2015-12-17 23:51:35 -07:00
Eric Newberry 8717e87046 tests: TcpTransport test suite improvements
refs #3306

Change-Id: I3b342b4df13db7996b03de7d1bed65b579798f85
2015-12-09 15:07:08 -07:00
Junxiao Shi 0de23a29c5 face: use IncomingFaceId, NextHopFaceId, CachePolicy tags
This commit replaces all LocalControlHeader usages with these tags,
and deletes LocalFace.

This commit also does minor improvements in RIB test suites.

refs #3339

Change-Id: I14cbfc296a6723a5860bf8bd95d9804d3bac3da5
2015-12-03 20:07:02 +00:00
Muktadir R Chowdhury 6c4a67af0d tools: adapt to ndn-cxx SegmentFetcher API change
Refs: #2734
Change-Id: Ibce8942007d0b26f34b212140a7b4313c4b6a397
2015-12-01 15:15:51 -07:00
Davide Pesavento 35120ea2f1 face: EthernetTransport
This commit replaces NDNLPv1 fragmentation and reassembly
with NDNLPv2 fragmentation and reassembly.

Change-Id: I10751157fcced94d441167ce470aaed79c12bb54
Refs: #3170
2015-11-26 02:53:20 +01:00
Davide Pesavento eee7b97d7b face: MulticastUdpTransport: set remoteEndpoint for received packets
Change-Id: I0d600d94e41a67c2d58ec10cde3cb6c13f619771
Refs: #3262
2015-11-26 02:49:27 +01:00
Davide Pesavento 762912d711 face: use the correct macro to declare classes final
Change-Id: I7f07d49a4b622ea1207b34d0c4a0f830a0141783
2015-11-26 02:40:51 +01:00
Alexander Afanasyev bd916ad7fc docs: Predefine missing DECL_FINAL macro in doxygen configuration file
Change-Id: Ic7e161bba091b49fe507f913259f53f44d49e862
2015-11-25 17:26:29 -08:00
Eric Newberry 4c3e6b89a1 face: NDNLPv2 fragmentation and reassembly
refs #3171

Change-Id: If29035b697b904ee49cb86d9248be488657c6f9e
2015-11-13 15:47:59 -07:00
Junxiao Shi 8c0500fd97 table: fix Measurements::get(Fib::s_emptyEntry) crash
refs #3275

Change-Id: Ie630111a3421f470756412896154f8a51f60d23d
2015-11-11 08:30:16 -07:00
Junxiao Shi da93f1fd0c face: LpFace counters
FaceCounters for LpFace consist of LinkService::Counters and
Transport::Counters. Old FaceCounters class from 2014 face architecture is
renamed as OldFaceCounters, and can be wrapped with new FaceCounters class.
OldFaceCounters is only used in old Face subclasses.

This commit also updates existing face test suites to use new FaceCounters,
updates ForwarderStatus so that it does not rely on FaceCounters,
and moves the logic of copying face properties and counters into management
structs from face system into FaceManager.

refs #3177

Change-Id: I587e8a32fa72bac3af9d750b2c88342740aa08d6
2015-11-11 06:13:16 -07:00
Junxiao Shi 57df288f5b face: LinkService and Transport counters
refs #3177

Change-Id: Idc495c58c3103dae5f01a2b6ebbff47a2c4a5d2b
2015-11-11 06:12:35 -07:00
Junxiao Shi 52e8540a86 fw: increase initial suppression interval in BestRouteStrategy2
refs #3230

Change-Id: I27217a01c066e90f65b5000a29991c938042a810
2015-11-11 06:06:58 -07:00
Davide Pesavento 077df8fbb6 tests: delete unused SimpleNotification class
Change-Id: I6e574146d335f05a247ec25d0c9bd355c955d945
Refs: #2144
2015-11-11 02:27:58 +01:00
Davide Pesavento 8728a25f1d face: override Transport::beforeChangePersistency in all subclasses
This commit also adds the final specifier to some Transport
subclasses in order to improve code generation.

Change-Id: If2979fa1614476a98019ba79cee3961663fc447b
Refs: #3318
2015-11-10 13:07:10 +01:00
Junxiao Shi d5134a7cd4 tests: defer face deallocation in Face/TestTcp and Face/TestWebSocket
Deallocating face immediately at face closing would cause a Signal object
in the transport to be destructed during its execution, which is disallowed.

refs #3322

Change-Id: I4eb23f34305cfecf7d2122e94454a97353707818
2015-11-08 07:53:24 -07:00
Davide Pesavento 47ab029798 face: deduplicate callback typedefs between Channel and ProtocolFactory
This should have been part of commit 1d7e7afd38

Change-Id: I61623152180d4df288fc7dd3c225518e438d2bda
Refs: #3258
2015-11-04 19:49:58 +01:00
Davide Pesavento ed89ccc521 build: enable -Wextra by default
Change-Id: I1e6783fca6530741bf4b81dd13613a6b4235290a
Refs: #3293
2015-11-02 17:44:30 +01:00
Yukai Tu 16aabbcc3b face: TcpTransport
Change-Id: I3ff898225ad1b0c1178490f389048944e24a9f1b
Refs: #3166
2015-10-27 17:16:07 +01:00
Davide Pesavento 9c7c79f2eb tests: fix "defined but not used" build error with gcc-5
Change-Id: If0cce184f88d76333956e5957db91d5b03e16d39
Refs: #2767
2015-10-27 17:07:40 +01:00
Junxiao Shi a044be7ed9 face: refactor NullFace as LinkService+Transport
refs #3278

Change-Id: I424f70f9402823d58d097671bab8c0c2dc4f2d3b
2015-10-27 07:48:11 -07:00
Yukai Tu 2d6d5637c0 face: WebSocketTransport
Change-Id: I28db9cd6f828e4a9fe5895bb7a6152cca5baa9fc
Refs: #3169, #3160
2015-10-26 11:06:08 -07:00
Junxiao Shi 5b8a2b2128 face: change Transport static properties initialization
Transport constructor now initializes static properties to invalid values.
Subclass constructor must explicitly set every static property.

refs #3259

Change-Id: I7ac3819694e0772c33a8a5d573e260f0eb944bff
2015-10-26 10:56:42 -07:00
Alexander Afanasyev abb307c9c5 docs: Fix doxygen links in release notes and displayed version
Change-Id: Ic1ee22e2607f5ab11c38a9adcaabc27a602c65ae
Refs: #3252
2015-10-26 10:11:02 -07:00
Alexander Afanasyev ba81830e81 docs+build: Prepare release of version 0.4.0 (beta2)
Change-Id: I9c9fe4a9f43d31be9e60fd743699f8729d1ccc4c
Refs: #3252
2015-10-22 11:34:58 -07:00
Alexander Afanasyev b755e9d5a7 docs: Fixing doxygen warnings
Change-Id: Ic85f86f4de8224e2fa5d1c41f6afb0f367af5b37
Refs: #3210
2015-10-22 11:34:56 -07:00
Davide Pesavento c8a66d3530 tests: delete pointless assert
size_t is an unsigned type, therefore the comparison is always true.

Change-Id: I851fa0d59569ebc8e2572b1938020aadabb05f27
2015-10-21 17:28:13 +02:00
Junxiao Shi 1354611277 face: Transport::getMtu
refs #3253

Change-Id: Ia4c5cfe210a99b798ce7d05f74ebdd7cfab214f4
2015-10-14 19:33:07 -07:00
Davide Pesavento 1d7e7afd38 face+mgmt: simplify factories and FaceManager using C++11 features
Change-Id: I113a4c15ef82bff705f61f31b170f49727bc3794
Refs: #3258
2015-10-13 16:28:52 +02:00
Junxiao Shi 6535f1ed28 face: InternalForwarderTransport & InternalClientTransport
InternalForwarderTransport and InternalClientTransport are a pair of forwarder-side
and client-side transports that can be connected with each other, so that link-layer
packets sent by one transport can be received by the other.

They are used together with LpFace, GenericLinkService, and ndn::Face to replace
InternalFace and InternalClientFace used by NFD management.

They also replace TopologyForwarderTransport and TopologyClientTransport used by
TopologyTester of forwarding unit tests.

refs #3225

Change-Id: I5b6b579c43dfd0b1b9def5100be2ce516219cb74
2015-10-10 05:36:34 -07:00
Eric Newberry a1939ba993 face: GenericLinkService drops IDLE packets
refs #3249

Change-Id: I3d16bcf29f4858049d1040a3e421e1c7151b3fed
2015-10-09 21:28:19 -07:00
Alexander Afanasyev 964d4598ef tests: Fix compilation against boost 1.59
Change-Id: Id539021a6c317425b162be33d220e2a8fe574899
2015-10-09 13:03:19 -07:00
Junxiao Shi 747b67d38f build: downgrade keyword-macro from an error to a warning with clang
refs #3235

Change-Id: I48c95d8dd3e767b551618f7ec7fffc33fbd30fd6
2015-10-05 16:42:41 -07:00
Yanbiao Li d7c9636078 rib: redesign of remote prefix registration
Change-Id: I8418de6d5bb9615af898df5dbf9ed4cc2cb6a43a
Refs: #3211, #2413
2015-10-04 20:58:52 -07:00
Junxiao Shi 94735f99cb core: delete NotificationStream
nfd::NotificationStream is no longer necessary because NFD Management
has switched to ndn::util::NotificationStream from ndn-cxx.

refs #2144

Change-Id: I30678c58dea4ea0b41c88a0ef7e660b116579e44
2015-10-04 13:33:50 -07:00
Minsheng Zhang 9c903e063e table: fix PriorityFifoPolicy memory leak
Change-Id: I1bd7d75b3a24b854a0a07e1fa197ef793f66192f
Refs: #3236
2015-10-04 12:17:43 -05:00
Davide Pesavento f485d89f16 build: disable clang's unused-local-typedef warning
This commit also enables color diagnostics on release builds.

Change-Id: I75d898ac1f3cf48097850f0cda807e3bee1cd206
Refs: #3209
2015-10-03 01:57:41 +02:00
Alexander Afanasyev f9572e8439 build: Fix compilation with boost 1.59
Change-Id: Ib2f72a770effa4a35ad6d21585ddc1043a89ac02
Refs: #3227
2015-10-01 16:20:58 -07:00
Alexander Afanasyev 687dba8614 docs+build: Prepare release of version 0.4.0
Change-Id: Ibd3129da74afa24a35115789a517e562f0a12639
Refs: #3178
2015-09-27 19:34:56 -07:00
Spyridon Mastorakis d374c406b2 daemon: display extended exception information in top-level catch
Change-Id: I471023fc23ffaebe04d9668426b4c1b03e4912cb
Refs: #2541
2015-09-27 11:36:42 -07:00
Junxiao Shi 259d0d876f Merge branch 'feature-lp' into master
Change-Id: I2efd0bf044c07b8cdaf03ab62a9b6b71a76b8b09
2015-09-26 19:35:42 -07:00
Junxiao Shi 40cb61c6bd mgmt: LpFace faces/enable-local-control workaround
In this temporary workaround,
faces/enable-local-control enables all local fields in GenericLinkService,
and faces/disable-local-control disables all local fields in GenericLinkService.

This commit also modifies FaceTable::remove to retain shared_ptr<Face>
until signal execution is complete.

refs #3226

Change-Id: I3513e97ec2af87df94dbf57a7256b895ed9d2103
2015-09-26 14:38:38 -07:00
Junxiao Shi 643b36b814 face: receive LpPacket in InternalClientFace
refs #3225

Change-Id: Ia37cfb941f00c612fc265594dac33cf13c6ad32c
2015-09-26 14:38:31 -07:00
Yukai Tu 0a49d34342 face: UdpTransport
Change-Id: I54f43248785437cdf951d50099e46e9689962a75
Refs: #3168
2015-09-26 14:38:22 -07:00
Yukai Tu 74c895d316 face: UnixStreamTransport
Change-Id: Iaab3c09887d7167ab9024ba871162367bf835197
Refs: #3165
2015-09-26 14:38:13 -07:00
Junxiao Shi 5e5e445182 fw: Nack in pipelines and best-route strategy
* in PIT out-record, add last incoming Nack field
* create incoming Nack pipeline
* create outgoing Nack pipeline
* modify Interest loop pipeline to send Nack upon duplicate Nonce
* in strategy API, add after receive Nack trigger and send Nack action
* in best-route strategy, send Nack-NoRoute before rejecting pending Interest
* in best-route strategy, process incoming Nack

Other changes include:

* Pit::find
* StrategyTester saved arguments structs
* TopologyTester transmit at Transport level

refs #3156

Change-Id: I7868561c0838231083d471261200aeb280cc6e9d
2015-09-26 14:38:03 -07:00
Eric Newberry 86d3187d9b face: GenericLinkService encoding/decoding
refs #3104

Change-Id: I26e83cd1dd5dc87ebdc040105ab1bad4afdba5f7
2015-09-26 14:37:51 -07:00
Eric Newberry a98bf93a25 face: Refactor Face as LinkService+Transport
LpFace: new Face implementation
LpFaceWrapper: allows new Face system to work with old Face system

Eventually, LpFace will be renamed to Face and LpFaceWrapper will be removed.

refs #3088 #3179

Change-Id: Ia4ad7c84631e65b444d4f24e1d7593392927c8db
2015-09-26 13:40:17 -07:00
Davide Pesavento ec2a698301 Remove illegal std::to_string definition and use ndn::to_string in its place
Change-Id: I81481fea3267bde669c45df182e0aea8ccd1a188
Refs: #3214
2015-09-21 01:17:16 +02:00
Davide Pesavento 01f8dba914 Use make_unique where appropriate
Change-Id: I30c9f0fb2033a810df73a1c9147fcf09d610f763
Refs: #3093
2015-09-19 21:56:34 +02:00
Davide Pesavento d2856a41ef Stop including <ndn-cxx/common.hpp>
It is considered an implementation detail, therefore its presence
and content should not be relied upon by other projects.

Change-Id: I7e53ecadf65336c8e9500481ff3a532761bac1f1
Refs: #2098
2015-09-19 21:30:47 +02:00
Alexander Afanasyev 441ba2175e daemon: Properly handle exception from NetworkMonitor when the platform doesn't support it
Change-Id: I713a6b6ebe4ac1e49f939325c7372954cb28e159
Refs: #3195
2015-09-17 16:50:56 -07:00
Alexander Afanasyev 435d705138 build: Fix compilation warnings/errors with clang-700.0.72 (apple LLVM 7.0.0)
Change-Id: Iedbebae03740a5d779c84e78d22b74dd9b9009f7
Refs: #3209
2015-09-17 15:10:25 -07:00
Junxiao Shi 06a29459dc docs: delete NRD manpage from toctree
refs #2489

Change-Id: I98bf2bbd6895b1c64c3cd4dc24abc493969a0de4
2015-09-10 06:08:25 -07:00
Alexander Afanasyev 483c43396c Merge feature branch 'mgmt-refactoring'
Change-Id: I3f122ede5bcfbad40800d8dae440dfea887bb10e
Refs: #2107
2015-09-08 18:41:01 -07:00
Alexander Afanasyev ecbf584299 mgmt refactoring: Correct ForwarderStatus publishing
Change-Id: I8207af814757b5f4ce3ea9b8bb66d7f5a369af2f
Refs: #2107
2015-09-08 17:25:23 -07:00
Vince Lehman 63ab1bb27a mgmt: Add tables.network_region section in config file to populate NetworkRegionTable
refs: #3159

Change-Id: If049eea2baf64a22abc9437d3ec117dd0d27bbab
2015-09-07 21:50:11 -07:00
Yanbiao Li 6704a4a6e4 mgmt refactoring: StrategyChoiceManager
Change-Id: Ib6df3f627070a3b6d4777f8efbe30e601e4c1512
Refs: #2107
2015-09-07 19:00:41 -07:00
Yanbiao Li 7cec7eafce mgmt refactoring: ForwarderStatusServer (renamed StatusServer)
Change-Id: I83aceca49e02f49553c9b17e16d6b50fb93e32de
Refs: #2107
2015-09-07 19:00:30 -07:00
Yanbiao Li 711c793171 mgmt refactoring: FibManager
Change-Id: Ied235d025cbe5059545c6482bfed0f38f987fdeb
Refs: #2107
2015-09-07 19:00:20 -07:00
Yanbiao Li 73860e3397 mgmt refactoring: FaceManager
Change-Id: I292a3e3d702746d6e946a2844e6f88f64cd711a4
Refs: #2107
2015-09-07 19:00:07 -07:00
Yanbiao Li 698f4fea3a mgmt refactoring: ManagerBase
Change-Id: I0710297f352723874d05092d091128b02b3747a2
Refs: #2107
2015-09-07 18:59:01 -07:00
Yanbiao Li 4ee73d42a4 mgmt refactoring: Refactor InternalFace
InternalFace is now exclusively for internal use by NFD's forwarding
pipelines.  A separate InternalClientFace has been introduced, intended
to be used by the NFD internal applications, including FIB, Face, RIB
manager, and others.

Change-Id: I4a06b9d05b1613a456c6267582091924557d73be
Refs: #2107
2015-09-07 18:58:48 -07:00
Yanbiao Li 36f3500d21 mgmt refactoring: Remove legacy code
Change-Id: Ib443ff3d45f9c49edee59d79c42a932017fc66ec
Refs: #2107
2015-09-07 18:58:34 -07:00
Joao Pereira c6184cdb3e tools: Extend nfdc to allow creation of permanent faces
Change-Id: If108fc3c7ae2ba1adab50269db3a23b426553b56
Refs: #2993
2015-09-04 20:22:01 -07:00
Yukai Tu 8149d1077b mgmt: Process FacePersistency in FaceManager
Change-Id:I3a93bd658d40f3d77f7790b72e8873646ecc7990
Refs: #2991
2015-09-04 10:44:24 -07:00
Junxiao Shi 0355e9fd06 fw: Forwarder processes Link for mobility
This commit also adds NetworkRegionTable to store producer region names,
and checks packets are well-formed before entering forwarding pipelines.

refs #3034, #3155

Change-Id: I8de4c482e8a289b922be70139675bc4661f9a301
2015-09-02 07:24:53 -07:00
Alexander Afanasyev 2fc649bfc6 docs+build: Prepare release of version 0.3.4
Change-Id: I7e0276ce210cf5322fd5f3195821b3edee74fc64
Refs: #3132
2015-08-31 09:10:26 -07:00
Junxiao Shi 67ba8d28df fw: rename BroadcastStrategy to MulticastStrategy
BroadcastStrategy is temporarily retained for backwards compatibility.

This commit also updates nfd.conf and ndn-autoconfig to use MulticastStrategy
in place of BroadcastStrategy.

refs #3011

Change-Id: I011f1cf75db26b3c93552f8322a0bba4ce8dd033
2015-08-21 21:21:28 -07:00
Yukai Tu 375dcb0bd6 face: minimal UDP permanent face
Change-Id: I44f652b95c911667107fd30829c7ce6e5acab706
Refs: #2989
2015-08-18 15:04:21 -07:00
Junxiao Shi 0e092aee5c mgmt: revert router name configuration options
This reverts commit ee7c8441c8.
That implementation introduces a global static variable which conflicts with ndnSIM.

refs #3026

Change-Id: I803e2ab497f71ec259d96d7b094ba0d04718c344
2015-08-18 15:03:15 -07:00
Vince Lehman faa5c0cd3c fw: Correct log message in onContentStoreHit
refs: #3114

Change-Id: I918cffc5d0551484b4cc31a4b7d6aeb73b8969ae
2015-08-18 15:02:25 -07:00
Spyridon Mastorakis 149e02cf7d Enhance exception throwing with Boost Exception library
Change-Id: I471023fc23ffaebe04d9668426b4c1b03e4919aa
Refs: #2541
2015-08-17 16:17:33 -07:00
Alexander Afanasyev a714792b03 docs: Remove nrd manpage
Change-Id: Ib6185c5e32ccbe01ea3803e2e9fb50749ffc9bfe
Refs: #2489
2015-08-09 23:51:06 -07:00
Alexander Afanasyev 66c569ddcc mgmt: Fix compilation and test cases when dropping privileges is not supported
Change-Id: I7da7eca3e5019dd5a7ed20b26f6e0c3260a03850
Refs: #3064, #2447
2015-08-09 23:45:13 -07:00
Alexander Afanasyev 3f41ade02d daemon: Reload face_system section of the config file when NIC configuration changes
The main desired effect of the reloading is re-creation of multicast
faces, e.g., when a new interface appears in the system.

Change-Id: I8384e5f96285ddca363981c92e1b6de39e0072ef
Refs: #2460
2015-08-07 12:17:14 -07:00
Minsheng Zhang 0315269228 table: add CS policy LRU
Change-Id: Ief9e3d993782730069cedc8a99b8011d5d18ce7c
refs: #2219
2015-08-04 12:32:08 -07:00
Stumble 62b19a6c09 docs: add spec of prefixes that are automaticly registered upon discovery of hub
Change-Id: I26a19e4c0f3608e0f159801e63e201d2d376d0ed
Refs: #2718
2015-08-03 18:15:07 -07:00
Yukai Tu 7c90e6dfea face: ProtocolFactory::createFace with FacePersistency
Change-Id: If02510bd631e9aaa63b3cca89ced31a42e192ded
Refs: #2989
2015-07-29 23:50:25 +08:00
Joao Pereira 4e274ac915 nfd-status-http-server: erroneous <!DOCTYPE html> display
refs: #3019

Change-Id: I9b400446c12ed1b6b0899dced0d9b4aff8720d4c
2015-07-23 11:54:52 -04:00
Vince Lehman ee7c8441c8 mgmt: Add router name configuration options
refs: #3026

Change-Id: I44250476e7e7f25cbc2b40d6a59f64b55872b24a
2015-07-17 19:06:24 -07:00
Vince Lehman c1dfdb44da rib: Accept KeyChain in RibManager constructor
refs: #2390

Change-Id: I45c9aae4bb111d75de63dcbcba4b3e6296eb2426
2015-07-17 08:18:28 -07:00
Alexander Afanasyev a4527cc837 ci: Fix TravisCI script
Change-Id: Ic5d725eb825b7db71735f865852685830dacfffd
Refs: #3041
2015-07-15 22:39:20 +08:00
hwyuan 8082993f7f table: Remove useless boolean in NameTree::const_iterator::operator++
Refs: #2808

Change-Id: Ief819d46a4c44eede5e1fecb951fb3e6002ad409
2015-07-12 19:41:38 -07:00
Alexander Afanasyev b81cff966e ci: Enable automatic dependency installation in Jenkins scripts
This commit also unifies TravisCI dependency installation using Jenkins
scripts.

Change-Id: Ia7bae2e2f31e781c07acea729d61fa07345760ab
Refs: #2843
2015-07-12 10:50:31 +08:00
Yukai Tu 731f0d70fa face: replace isOnDemand with FacePersistency
Change-Id: Ie6995b2d03bbb90faad158de2b055f72dd9ba73d
Refs: #2989
2015-07-09 07:46:52 -07:00
Joao Pereira 08f07016a3 ci: build ndn-cxx as shared library
refs #2992

Change-Id: Ia65a5d1868d2a63b30adf3bd496be071bc57dd6b
2015-07-08 03:52:25 -07:00
Alexander Afanasyev 2666473042 docs+build: Prepare release of version 0.3.3
Change-Id: Ia53f820fb60e8a9ed5da0ac1667b8d10ef79c414
Refs: #2812
2015-07-01 11:23:12 -07:00
Joao Pereira 5b6deaea18 docs: Fix indentation in nfdc manpage
refs #2995

Change-Id: I154b1ccc73022f59ff8166d4353ee3a23dc75215
2015-06-30 16:03:20 -07:00
Yukai Tu 971d3c2b09 tools: Simplify nfd-status using SegmentFetcher
refs #2456

Change-Id: I5beb402b211717816ae11d3474b41ade15c7418c
2015-06-29 09:47:43 -07:00
Alexander Afanasyev dbe4f9fefe tests: Fix compilation errors because of changes ndn-cxx library
Change-Id: I10fb7eb366a03c2e06e6d2efefdde8a9dd0da724
Refs: #2951
2015-06-28 11:24:51 -07:00
Alexander Afanasyev 692842d6ad rib: Avoid deprecated nfd::CommandOptions::setSigningIdentity method
Change-Id: Id98538d96368c67ac1db939e0ad0fd43ec0c6ab9
Refs: #2893
2015-06-23 14:26:45 -07:00
Minsheng Zhang cb6e05f2dd table: add CS policy interface
Change-Id: I1946fe03ca00150b1ff9f08acae48c01bc569904
Refs: #1207
2015-06-12 10:03:17 -05:00
Junxiao Shi 5620fb2ac9 tools: deprecate ndn-tlv-peek and ndn-tlv-poke
refs #2817

Change-Id: Iee198533659320bf2e9219b92195e06a3ba2b25f
2015-06-07 20:59:38 -07:00
Junxiao Shi 965d3a4e72 fw: AccessStrategy avoid loop back new Interest
refs #2831

Change-Id: I1680fd62cdf8f11eaa7817dd6d4b7794c305c5eb
2015-06-01 06:55:23 -07:00
Eric Newberry 187ade8566 contrib: Add unit file and instructions for systemd
refs #1586

Change-Id: I06b91804fc8b8613560ef98687307f56262689fb
2015-05-15 14:43:31 -07:00
Alexander Afanasyev 2d1b64066c docs: Add missing item in the release notes for version 0.3.2
Change-Id: Iba4f70c2125a702905e11c1db7846495ef377a97
Refs: #2618
2015-05-12 21:15:06 -07:00
Alexander Afanasyev ed808ab2c9 docs+build: Prepare release of version 0.3.2
Change-Id: I43223e09c2201c7d3185a3d8929a691ae963c5d1
Refs: #2618
2015-05-12 13:36:59 -07:00
Junxiao Shi 7b0f4d1dd8 fw: AccessStrategy extends measurements lifetime
refs #2452

Change-Id: I79ffcc65cb222854c163c5df339bb1061785a518
2015-05-12 13:36:59 -07:00
Alexander Afanasyev 483d652d95 build: Disable precompiled headers on OS X with clang < 6.1.0
Change-Id: I4e88f35d6e649eb5b2eefef868ac29576e293877
Refs: #2804
2015-05-12 13:36:59 -07:00
Alexander Afanasyev 1c85221192 build: Update waf to version 1.8.9 (with custom patches)
https://github.com/cawka/waf/tree/2a098b1e9bc626c19cbd47c1f670758c17edf54c

Change-Id: I1e6c352f6ffa272e896391b983fee4cca7cdf8a6
Refs: #2792
2015-05-06 14:51:38 -07:00
Wentao Shang d397d7773c face: switch to non-throwing version of websocketpp APIs
Change-Id: I0291dff14373cadeec16d44c73d9db43011fff4b
Refs: #2630
2015-04-29 18:20:27 -07:00
Vince Lehman f91ab74da9 rib: Stop removed namespace from inheriting ancestor route
refs: #2757

Change-Id: I9f9e18109f0d8ee45571d23a6eea7f254302a56f
2015-04-27 10:00:14 -05:00
Davide Pesavento db9d37edab Fix several "defined but not used" warnings with gcc-5
GCC 5 is able to prove that in some translation units the static Logger
instance is defined but never used, and generates an unused variable
warning for each one of them. These warnings become fatal errors when
building in debug mode, due to -Werror.

Silence the compiler by not declaring the unused variables.

refs #2767

Change-Id: Icacc579d917d660582221ef090954ec827f46149
2015-04-24 10:25:56 -07:00
Alexander Afanasyev ce81230b09 build: Emulate std::to_string when it is missing
Change-Id: I4a08cf4abe7a2064a0c53d29582cbb761a1d131f
Refs: #2743
2015-04-14 23:37:03 -07:00
Mathias Gibbens 802c092d1a face: Use C version of snprintf
Change-Id: I18f85f6debda47af17a4006699f1283dc75b735d
Refs: #2299
2015-04-14 14:47:20 -07:00
Junxiao Shi e8f4246e13 docs: update Planned Features - face enhancements
refs #2617

Change-Id: I64dd36025bf1baf0f93a631d02c7d2a6754c6eba
2015-04-06 21:37:28 -07:00
Alexander Afanasyev cdb8f364c1 build: Tweak default pkg-config search paths
Change-Id: Id9b656104b00fd18c9302165b0eeeffd17f6c87a
Fixes: #2711
2015-03-31 17:19:35 -07:00
Alexander Afanasyev e06b627f31 build: Update waf to version 1.8.8-dev (with custom patches)
https://github.com/cawka/waf/tree/8f714a523d3b8c66f2949aaa8db91d6f7be55e55

This patch also ensures that unused-local-typedef warning does not
generate errors.

Change-Id: I024438c338d0455df11508779c10a2737d25caab
Refs: #2209, #2657
2015-03-26 14:36:02 -05:00
multicast proxy d6474640da tools: Fix hanging of nfdc on wrong input
Change-Id: I4fd4fb95d3dee72f5e0b8bc2435f7fffca87e5e3
Refs: #2690
2015-03-26 14:36:02 -05:00
Vince Lehman 9dcfc40f21 rib: Fix TestFibUpdates/EraseFace on Ubuntu 14.04 32-bit
Change-Id: I1381bc3eb813a1afad9b666fba30688216ee38dc
Refs: #2697
2015-03-26 12:34:26 -07:00
Davide Pesavento 2231ab526f Get rid of the last use of ndn::dns in NFD
Change-Id: I9a3188379a4755f5535af05a860a2e3a12ddc8ba
Refs: #2422
2015-03-19 13:13:25 -07:00
mzhang4 eab7249b74 table: change ContentStore lookup API to allow async implementations
refs: #2411

Change-Id: Ifbb4179c34cf10a7913f8113a2f9238476d8eafa
2015-03-19 04:59:33 -07:00
Davide Pesavento 292e5e1436 face: use move semantics for sockets where possible
Change-Id: I2af595073f862c570c1ce0dcb3717f3d2b9cfd71
Refs: #2613
2015-03-17 21:32:49 -07:00
taylorchu 5ae2877796 build: make wscript compatible with python3
Change-Id: I5b29d85d0b758ec2d154eb71a2637cd73658807a
Refs: #2625
2015-03-17 16:45:27 -07:00
Vince Lehman 76c751ce80 rib: Perform FIB updates before modifying RIB
refs: #1941

Change-Id: I1457f71ddd1c120daae48308d5cc02a7c0ecf93d
2015-03-13 19:57:39 -07:00
Junxiao Shi e4eec13108 face: avoid deprecated Block::fromBuffer overloads
This commit also does some cleanups in NDNLP PartialMessageStore.

refs #2553

Change-Id: I6a74929e58d38bde1a9ac365f7d5c42862d37592
2015-03-13 15:40:49 -07:00
Davide Pesavento 6ad890a098 face: Stop using shared_ptr to manage acceptors
This commit also includes a major cleanup of all channels.

Change-Id: I10db9709e0cba6a0691a86482c60b5dbb2956f68
Refs: #2613
2015-03-11 22:04:40 +01:00
Alexander Afanasyev 8896478926 build: Update version number to 0.3.1
Change-Id: Ibbb64815f3d334c830bee734928813bbf99308bf
Refs: #2588
2015-03-03 20:10:59 -08:00
Alexander Afanasyev 58ad5d4dd7 docs: Prepare release notes for version 0.3.1
Change-Id: Ic7ff46a119f1dd5b898338ddc6673262aef026e0
Refs: #2588
2015-03-03 12:30:28 -08:00
Wentao Shang ce07470031 face: update websocketpp to version 0.5.1
Change-Id: Id5ce36532d30c7d37da466762b335b740e67ad67
2015-03-02 21:07:34 -08:00
Junxiao Shi ebaf7b61fc table: delete nfd::cs::skip_list::Entry
This type is part of the old ContentStore implementation,
which should have been deleted during the merge.

refs #2254

Change-Id: Ib64ee8a65b39bd191d8bdcf4e71ebd5460d342a9
2015-03-02 10:40:03 -08:00
Junxiao Shi 083f778321 face: no exceptions in NDNLP PartialMessageStore
refs #2261

Change-Id: I711502be23bb4b3691eb44fc63332ffd0bfb8d34
2015-03-01 20:46:11 -07:00
Junxiao Shi 78926c9083 face/rib/tools: avoid deprecate Block::fromBuffer overloads
refs #2553

Change-Id: I32ea424ab7547f59fea2fca70ad6f41cd90bab58
2015-02-28 23:02:31 -07:00
Alexander Afanasyev e84044e87d tests: Fix segfault in TableNameTree test suite when all test logs are enabled
Change-Id: I0acb886d38a09b764cb3e324490a7c52b945d4fa
Refs: #2564
2015-02-27 11:31:19 -08:00
Davide Pesavento 9427941781 face: refactor handling of LinkType face trait
This commit also includes some cleanups, fixes EthernetFace to report
the correct LinkType, and makes (get|set)Description non-virtual.

Change-Id: I53909d7bfa02a92641b523a766359413c966aae6
Refs: #2563
2015-02-27 15:12:16 +01:00
Davide Pesavento 13b76f0937 face: copy also the link type in copyStatusTo
Change-Id: I3787210328f326fd788e7f0f3e23493e4dfa9ddd
Refs: #2563
2015-02-26 18:45:19 +01:00
Davide Pesavento be40fb1e56 face: Introduce Face-specific logging macros
Change-Id: I169065de664d4c4394ccd08673bbe1f881c4d7e0
Refs: #2450
2015-02-26 18:42:59 +01:00
Junxiao Shi 684fa0f89d fw: use RetxSuppressionExponential in best-route
Retransmission suppression algorithm of best route strategy
is changed from fixed interval to exponential backoff.
This is a semantical change which requires an increment of the
strategy's version number from 2 to 3.
Version 2 is not retained because it's mostly same as version 3.

refs #1913

Change-Id: I0f18511a3b96384b071024864e638ae3b3ec7080
2015-02-23 21:39:57 -07:00
Davide Pesavento 0e97a97603 table: Reduce priority of DeadNonceList log messages
Change-Id: Id0419b9c38ec693b6111ce5b8f91a6d1aa04f705
2015-02-23 14:57:19 -08:00
Vince Lehman ff8b39746b rib: Change register/unregister logging to INFO
refs: #2547

Change-Id: Iedf72cb9c9f36742ea43650f8cdd4a9450c987de
2015-02-23 12:45:26 -08:00
Junxiao Shi 35b16b1984 table: ContentStore recognizes CachingPolicy-NoCache
refs #2185

Change-Id: Id3dab8936c4dafc96c5d8933d7e75c6cc2e31ff2
2015-02-21 21:42:11 -07:00
Spyridon Mastorakis d0381c05a6 tests: Change to updated naming conventions
Change-Id: I9351c669282c3c02fd533237489beeb10fe7d15e
Refs: #2497
2015-02-21 13:02:47 -08:00
Minsheng Zhang 60d06d8770 tools: change prefix of routable-prefixes packet to under /localhop/nfd
refs #2512

Change-Id: Ib399e61b3d7b84f7993a5b887ff6b5b7c3e93a45
2015-02-20 16:49:15 -06:00
Junxiao Shi 0d6d036e4f docs: change prefix of routable-prefixes packet to under /localhop/nfd
refs #2479

Change-Id: I49c02bbfe5eed282c33ecfe99ce8b1894a1b7d23
2015-02-20 08:21:16 -08:00
Chengyu Fan addecff68b management: clarify the inconsistency in UDP face timeouts in nfd.conf
refs #2473

Change-Id: Iceeda5f03bc426dfab1e67cf508996d3fe96ac42
2015-02-18 07:18:29 -08:00
Alexander Afanasyev 4d384fcce5 tests: Revert changes to s_normalUid/s_normalGid in MgmtGeneralConfigSection test suite
If changes to s_normalUid/s_normalGid are not reverted, the subsequent call
to PrivilegeHelper::drop() will throw exception if test cases run by an
unprivileged user.

Change-Id: I27e8b159d61e1b5f6dd21879f36ed63667f5c045
Refs: #2521
2015-02-17 09:22:29 -08:00
Junxiao Shi faf3eb0823 fw: register strategy with macro
refs #2410

Change-Id: Ifa79c194c58d0ebe1bca6236fc0a47debe2da05e
2015-02-16 22:30:16 -07:00
Junxiao Shi 73b909a514 fw: RetxSuppressionExponential
refs #1913

Change-Id: I9bb2bae8d7600722920534f646cc8056b3d4843a
2015-02-16 16:23:28 -08:00
Alexander Afanasyev a4ff44ce6f face: Update code to work with updated LocalControlHeader implementation
Change-Id: I3a73269ad30cfd8d7e366115aae08728f17c3b17
Refs: #2183
2015-02-16 11:40:06 -08:00
Alexander Afanasyev 90c20face8 face: Properly handle error conditions in UdpChannel::newPeer
Change-Id: Ia34eb738a6cc8977bbcba91f0055fe4623df4d32
Refs: #2516
2015-02-15 12:43:57 -08:00
Alexander Afanasyev baba2535e1 face: Remove Tcp|UdpChannel::connect overloads that perform DNS resolution
Change-Id: Ib5da2a43d1e33654940aa42f568b6a604c171e3e
Refs: #2422
2015-02-15 12:43:57 -08:00
Alexander Afanasyev c3ea5a7886 rib: Use only a forward declaration of RibManager in the header of Nrd class
Change-Id: I8a681dc9a75ac8cdabc289e685ec6a505cfb5aac
2015-02-15 12:43:57 -08:00
Alexander Afanasyev 2bda6f8d9c daemon: Replace shared_ptr with unique_ptr in Nfd
Change-Id: I97d39ddb793abfe4552002c94778b95e6b96f869
Refs: #2496
2015-02-15 12:43:57 -08:00
Alexander Afanasyev f08a7376e9 daemon+rib: Merge nrd and nfd into a single process (separate threads)
Change-Id: I41952d5b8ee29f109130c570e0d13ccad6970d2f
Refs: #2489
2015-02-15 12:43:49 -08:00
Alexander Afanasyev 63df436e5f core: Make global random generator thread-local
Change-Id: Ib17ea05592445cf99af9726ef7799ead813ca0fe
Refs: #2489
2015-02-15 11:58:52 -08:00
Alexander Afanasyev 6b34ab9cec core: Make logger thread-safe
Change-Id: Ic45dc0912da9c2e3f074d3f74921bfe33741bf63
Refs: #2489
2015-02-14 12:26:32 -08:00
Alexander Afanasyev 5d57f97fa7 core: Make global io_service and scheduler thread-local
Change-Id: I3d6b6cd3ca7a6e53b0dc0f4cae7a2f3270c7fd50
Refs: #2489
2015-02-14 12:25:19 -08:00
Alexander Afanasyev 9cfeecaa2f core: Prevent exception throwing when dropping privileges is not supported and not requested
The exception still be thrown, if config file requests privilege dropping.

Change-Id: I856207958354410fa45da7ccc73b46b99f74d9e7
Refs: #2515
2015-02-12 16:44:24 -08:00
Alexander Afanasyev 6f570de8d7 core: Make PrivilegeHeper::drop|raise no-op operations on platforms that do not support drop/elevation of privileges
Change-Id: I13b53ba27cee59d58b816d060501499517e6dc37
2015-02-11 20:59:09 -08:00
Alexander Afanasyev 31367925c6 rib: Refactor initialization of NRD instance
This commit also makes Face used inside NRD be adaptive to nfd.conf.
More specifically, it will use the same unix socket path as specified in
face_system.unix section.  If this section is not present, it will use
the same tcp port as specified in face_system.tcp section.  If tcp
section is also absent, nrd will abort execution.

Change-Id: I48f75ddf972f259055cd61824e3c228ca1d6a639
Refs: #2496
2015-02-11 16:13:26 -08:00
Alexander Afanasyev 31c781e453 daemon: Refactor initialization of NFD instance
Change-Id: Ie4181a0b65e249c7067a11e941dcea77f010e4b1
Refs: #2496
2015-02-10 19:12:05 -08:00
Alexander Afanasyev 8269a05874 core: Allow customization of Logger and LoggerFactory
Change-Id: I48a8217ab4cfb34ce2993f11a26266723d8d2923
Refs: #2433
2015-02-10 19:12:04 -08:00
Alexander Afanasyev 95ff7112aa tests: Fix compilation due to refactoring of EncodingImpl in ndn-cxx library
Change-Id: I3b96dd01fef810dfd2cd57d910a46f137a13879e
Refs: #2494
2015-02-10 19:11:33 -08:00
Alexander Afanasyev c0273e3505 core: Extend ConfigFile to support passing a parsed ConfigSection
Change-Id: I955220c08d8e6ed07c77d82149f6ff3ae48b2b12
Refs: #2495
2015-02-09 13:33:45 -08:00
Junxiao Shi a788e25e70 fw: rename RetransmissionSuppression to RetxSuppressionFixed
This commit also declares RetxSuppression base class as the API
for any retransmission suppression decision algorithms,
so that other algorithms can be introduced.

refs #1913

Change-Id: I5539565d2dd238d1421f5bd828fde4ecfba0a820
2015-02-04 06:56:03 -08:00
Alexander Afanasyev 3056e08c9e docs: Update link to the right version of developer's guide
Change-Id: I6a39507df56141d648728bebc9f6305584ecb067
2015-02-03 16:00:31 -08:00
Alexander Afanasyev 7c10b3bdc8 docs: Prepare release notes for version 0.3.0
Change-Id: If0ae14cbf97ee3d9b92a3467d0b6592c10e66698
Refs: #2462, #2352, #2209
2015-02-02 19:21:57 -08:00
Junxiao Shi 5af9bd3d6d table: reduce implicit digest computation in ContentStore
refs #1706

Change-Id: Ic6c4c25f2ef722b9ee37e22362ad57a434bbf821
2015-02-02 15:37:34 -08:00
Alexander Afanasyev ba3f79ec4f tools: Ensure that ndn-autoconfig quits after successful discovery in non-daemon mode
Change-Id: Ifde24e1800faba630cafb7b04d034b916a6c069d
Refs: #2469
2015-02-02 15:37:20 -08:00
Davide Pesavento 66ff0989c5 face: cleanup log messages in all faces and print fail reason
Change-Id: I405198b375a0317663d29810ee87922a19edccaa
Refs: #2450
2015-02-02 17:59:02 +01:00
Alexander Afanasyev e46279dc83 tools: Daemon mode for ndn-autoconfig (re-run detection when connectivity changes)
Change-Id: I3cb870b13ba60d255162862c7dd0053ec5b578c4
Refs: #2417
2015-01-31 21:16:39 -08:00
Yanbiao Li de88b46ac1 rib: recognize /localhop/nfd HUB prefix in RemoteRegistrator
Change-Id: If4d29b17e381f121d025ee8a9a52466a68e46a83
refs: #2412
2015-01-30 23:28:29 -08:00
Davide Pesavento 9a090a0f91 EthernetFace: report packets dropped by the kernel if debug is enabled
Change-Id: I8b0f9774c4ad785da476aba88f0b6a212256bf51
Refs: #2441
2015-01-30 03:55:23 +01:00
Steve DiBenedetto 8919abe4c4 core: set FreshnessPeriod on segment publisher Data
refs #2438

Change-Id: Ibf46dad33b0483f0716bbfef6697d73cc00a117b
2015-01-29 11:52:31 -08:00
Alexander Afanasyev 748e9892da build: Fix misdetection of privilege drop/elevation functions
Now detection uses an explicit code fragment

Change-Id: I209f8623f3db4f1c3574c09eb2770decc554a2e4
Refs: #2419
2015-01-28 15:43:59 -08:00
Alexander Afanasyev bda8366ada tools: ndn-autoconfig: Register also /localhop/nfd prefix towards the hub
Change-Id: Ia5f9ac5514470070160d32ed8883d3fa04d33e10
Refs: #2416
2015-01-28 14:17:46 -08:00
Alexander Afanasyev 2a655f70a1 tools: Refactoring ndn-autoconfig implementation
Change-Id: Ib92942ba40f04aaee83479177b9ba5d32a09af04
Refs: #2421
2015-01-28 14:17:10 -08:00
Alexander Afanasyev 262203b644 build: Support tools with multiple translation units
Change-Id: I95c7ec4c0923e59b2652c6bba4ed2c0f00aa71da
Refs: #2344
2015-01-27 18:14:10 -08:00
Alexander Afanasyev 49343f6fab build: Add conditional compilation
Two conditionals are introduced in this commit:
- if <ifaddrs.h> is not available, NetworkInterface helper will always return
  an empty set of interfaces
- If dropping/elevating effective user/group is not supported, an error
  will be thrown if used (e.g., if general.user or general.group is
  configured)

Both conditionals are necessary on Android platform.

Change-Id: Ib360e03514af97ed2d68032fbcbe279a8dc84682
2015-01-27 18:13:50 -08:00
Alexander Afanasyev 5d4c977f64 core: Use C version of snprintf
Change-Id: I7d6b6ce3bce7be2df8d004bbbf18bea43e8079d0
Refs: #2299
2015-01-27 11:05:45 -08:00
Alexander Afanasyev 76818632e0 build: Several updates of the build scripts
- Update of waf script (based on custom fork https://github.com/cawka/waf)

- Redesign the way default compile flags are determined.

  This includes a small semantical change with flag processing:
  * there are now "general" compiler and link flags. These are added (if
    supported) even if CXXFLAGS and/or LINKFLAGS environmental variables
    are set.
  * optimization/debug-mode flags that are applied only if CXXFLAGS
    and/or LINKFLAGS environmental variables are not set.

Change-Id: I6affeed08cc49bca28f076839e40ff790e57437b
Refs: #2209
2015-01-27 11:05:45 -08:00
Alexander Afanasyev d7bb88b53a tools: Fix broken link to documentation in NFD status web page
Change-Id: Ic47a1c2be6ccc185b9ff8b67c863a356a63746fe
Refs: #2405
2015-01-27 11:05:13 -08:00
Alexander Afanasyev 0e156df634 face: Remove unnecessary use of DNS resolver in (Udp|Tcp|WebSocket)Factory
Change-Id: Idbc743fe4c7d567a09acccef98fe6de26f8295f0
Refs: #2422
2015-01-27 09:24:35 -08:00
Junxiao Shi a37405dbd8 face: fix NDNLP PartialMessage cleanup scheduling
refs #2414

Change-Id: Ida9e47e41c4dde9b3ee0ee7003fc4aaa79ea55df
2015-01-26 15:05:26 -07:00
Junxiao Shi 80ee7cb931 fw: access strategy
refs #1999

Change-Id: I5fc284d7ae82ed933bf5937d5c687885e73c3e0a
2015-01-24 21:44:20 -07:00
Junxiao Shi fbf783450c rib+tools: subscribe to FaceMonitor notifications using connect
refs #2350

Change-Id: I1b1b33cdcc3638c7344b6c690f928aff25aa5c8c
2015-01-23 14:46:41 -07:00
Junxiao Shi 04cf5a99d9 Merge branch 'feature-cs' into master
refs #2254

Change-Id: Iafd4b8d51477fc11340156cc65c2732923e16354
2015-01-22 17:35:49 -07:00
Vince Lehman 7c7d33a4b5 rib: Insert RIB command prefixes into RIB
refs: #2312

Change-Id: I9452f60d4c2162ad265603d3d5d44f083452ec58
2015-01-22 10:39:36 -08:00
Junxiao Shi 85d17fcaed table: ContentStore benchmark
refs #2254

Change-Id: I422a7e6d4ca3ad17db2465460e67b8cd2130fd36
2015-01-21 22:34:03 -07:00
Vince Lehman 218be0a884 rib: Rename FaceEntry to Route
refs: #2159

Change-Id: Ia324a47816cac514dacc4a69a29fd30d08932e5b
2015-01-21 15:33:34 -08:00
Junxiao Shi 6316220d36 fw: fix NccStrategy loop back to sole downstream
refs #1998

Change-Id: I81c089f67aa6278a4fcb42ec79a32eed065e19f5
2015-01-21 14:26:21 -08:00
Chengyu Fan 5010123d5c tools: fix bug that nfdc register does not terminate if FaceUri canonization fails
refs #2397

Change-Id: I8c1dce00cfbf4926ead7c4794d02158e43008000
2015-01-21 11:24:27 -07:00
Junxiao Shi fc20696c59 table: ContentStore enumeration
refs #2254

Change-Id: Ic440afea2197f12f7720adb559b836d08e864bed
2015-01-20 12:16:43 -07:00
Chengyu Fan 4381fb6b11 core: use ndn::dns from ndn-cxx
refs #2207

Change-Id: Ice97c9203283b5b89982049cb29c0ccfed0ef422
2015-01-19 23:08:52 -08:00
Alexander Afanasyev 319f2c8dbc src: Update copyright notices for files modified in 2015
Change-Id: Ia52e6e891a06fcc7ace06eafd2fffecd7bd55a95
Refs: #2352
2015-01-19 21:45:21 -08:00
Hila Ben Abraham 6cdbdfc5ff tools: ndn-autoconfig: canonize FaceUri before creating face
refs: #2387

Change-Id: I4d5682206cd44c93f61d28b5ae3bca60d5086277
2015-01-19 12:30:14 -08:00
Junxiao Shi 192af1f71c fw: abstract retransmission suppression logic
Consumer retransmission suppression logic of best-route v2 strategy
is abstracted into RetransmissionSuppression class, so that it can
be reused in other strategies.

refs #2377

Change-Id: I7de2c2d0e60c5ad3467e24283e9b03bd03f65bdc
2015-01-19 10:50:32 -07:00
Junxiao Shi 5640ec8934 table: better ContentStore findRightmost algorithm
refs #2254

Change-Id: Ib8f473f0cce1a1636b600a98494292499d71972e
2015-01-15 21:43:55 -07:00
Junxiao Shi b283128b6f table: use UnitTestTimeFixture in DeadNonceList test suite
refs #2359

Change-Id: I8ccec1970d89268b0550b8b10e87ebd2d594c25e
2015-01-09 19:26:16 -08:00
Junxiao Shi 35353963db table: MeasurementsAccessor findLongestPrefixMatch & findExactMatch
This commit also improves unit testing of MeasurementsAccessor,
and changes signature of MeasurementsAccessor constructor.

refs #2314

Change-Id: Ie0494628c6d3faac0473bc4cfb21998f89270aaf
2015-01-09 14:04:43 -08:00
Junxiao Shi 1e46be30e4 core: rename nfd::EventId to nfd::scheduler::EventId
refs #2298

Change-Id: I5d4f4c5234fd370666e81a8a8e7d312694a6ad5d
2015-01-09 09:52:56 -07:00
Junxiao Shi 767cb33632 table: Measurements::findLongestPrefixMatch(pit::Entry)
refs #2314

Change-Id: Iebe80240760b22b573da1e6d23b43273ff3efbeb
2015-01-08 09:35:49 -07:00
Junxiao Shi b30c7b0596 table: accept predicate in Measurements::findLongestPrefixMatch
This commit also deletes unused Measurements::s_defaultLifetime constant.

refs #2314

Change-Id: I6ffce7dee828f1f9aa47099777df6ee0615ce4f1
2015-01-07 23:52:58 -08:00
Junxiao Shi c099ddb587 face: replace EventEmitter usage with Signal
refs #2300

Change-Id: I17d0d65d2c474b17dd9f23f271a6144b0b4fbc07
2015-01-06 20:50:15 -07:00
Junxiao Shi a22a217261 face: fix overhead estimation in NDNLP slicer
refs #2317

Change-Id: I1b2ec985a075083386c7117494478666eb28802e
2015-01-06 12:07:44 -08:00
Alexander Afanasyev c91ebfa900 table: Allow iteration over CS entries
Change-Id: I23bf0da9a853de70187c9e72a0f7a5cb98107fbd
Refs: #2340
2015-01-06 10:50:27 -08:00
Alexander Afanasyev 8934c4212a table: Ensure that Cs::erase removes the item from the cleanup index
Change-Id: Iefe658904829fa662c4854c38a5d57dad5e80222
Refs: #2348
2015-01-06 10:50:27 -08:00
Alexander Afanasyev 750fa1cf86 table: Allow iteration over PIT entries
Change-Id: If48d7f827ccb5df0480cfa27bd2f3db4e3f796fa
Refs: #2339
2015-01-06 10:50:27 -08:00
Alexander Afanasyev 09fc3d9df8 table: Ensure Fib::const_iterator is default and copy constructible
This functionality is necessary for ndnSIM python bindings and is
technically required by ForwardIterator C++ concept
(http://en.cppreference.com/w/cpp/concept/ForwardIterator)

Change-Id: Ibe0812c3a2cf05840cd3e83b941cc52affe2ac65
Refs: #2338
2015-01-06 10:50:27 -08:00
Alexander Afanasyev eae4f80d2c face: Limit exposure of EthernetFace implementation
It seems that gcc 4.6 on Ubuntu 12.04 has some issue with
std::unordered_map in EthernetFace implementation, causing it segfault
in some cases.

Change-Id: I0c5a3be66e357e2bd83841d833d601c2fba6936a
Refs: #2347
2015-01-06 10:48:00 -08:00
Junxiao Shi 39ef261a29 table: StrategyInfoHost stores multiple StrategyInfo of distinct types
refs #2240

Change-Id: I25062260e3bb4f2f36989305431d4b718d320505
2015-01-04 04:55:45 -08:00
Steve DiBenedetto 158f73fce2 docs: Update config file instructions for disabling unix sockets
refs: #2190

Change-Id: Ie6001e561b5dd40813da95185c123935ee51baa4
2015-01-03 16:44:14 -07:00
Junxiao Shi 3cb4fc6778 fw: use UnitTestTimeFixture in NCC test case
This commit also changes StrategyTester<S>::onAction to use Signal.

refs #2163

Change-Id: Icd30cfa640972c53efdd8c7f7164b7eb9fc34c1e
2014-12-30 06:54:19 -08:00
Davide Pesavento f8b41eb1b1 face: Fix ioctl() calls on platforms where libpcap uses /dev/bpf*
Change-Id: I2ed2cacf4915458d9b95f0a07beda46039aaa39d
Refs: #2327, #2328
2014-12-30 03:14:33 +01:00
Davide Pesavento 4147c002ec build: disable EthernetFace only with boost 1.56.0, not later versions.
The regression has been fixed in boost version 1.57.0

Change-Id: I187c523b2a715c0fd00ff438840f4275c7c55a64
Refs: #1922
2014-12-23 17:45:01 -08:00
Davide Pesavento 8eb9957db6 face: Support MTU larger than 1500 in EthernetFace (for jumbo frames)
Change-Id: Id784315569e11794dceaceffb4bb0af21b69be44
Refs: #2305
2014-12-19 19:14:36 +01:00
Alexander Afanasyev c5173de511 face: Don't crash when attempting to create UdpFace over a half-working connection
Change-Id: Ib32128074f8dfe834fde033517325f994d648767
Refs: #2311
2014-12-18 13:12:42 -08:00
Yanbiao Li b9d439d202 rib: remote prefix registration
resolve 3 bugs:

There are redundant registrations/unregistrations if loading the
config file multiple times.

Remote registration/unregistration will fail if localhop_security
is enabled.

Unstable RemoteRegistrator/UnregisterAdvanced test case.

Change-Id: I4437292e9f6c0e340c761ef7556a9bdc703ac06c
refs: #2294
2014-12-16 22:58:56 -08:00
Chengyu Fan b94af7c82f mgmt: Allow only canonical FaceUri in faces/create command
refs #1910

Change-Id: I89a84cd8584d5a718bcc85db05cc337b4b4f8f73
2014-12-16 21:47:07 -08:00
Alexander Afanasyev 508411efb5 docs: Installation instruction updates
- Suggest checking out master branch in install instructions
- Add a note to run `./waf distclean` after change of dependencies

Change-Id: Ia4ee122986840815968920bf3ba14a9892c25363
Refs: #2136, #1980
2014-12-16 13:34:52 -08:00
Junxiao Shi e5e1e250cd docs: list pkg-config as a compilation dependency
This commit also updates supported OS versions in INSTALL.rst.

refs #2191

Change-Id: I5e00c2b4f3755be571d2842cc19915c3e3a06af9
2014-12-16 06:29:54 -07:00
Junxiao Shi a938818047 table: rewrite ContentStore
This is the first of a series of commits that rewrites the ContentStore
with a cleaner design.

refs #2254

Change-Id: I6595dca63137760d2283934a8f311a14dc2183bf
2014-12-15 21:48:30 -07:00
Junxiao Shi 27533da4f1 core: scheduler::ScopedEventId
refs #2295

Change-Id: I17bc949882bebadbf4d19aaede4c634a12121787
2014-12-15 20:44:47 -08:00
Alexander Afanasyev 7e14816e85 core: Add a warning comment for listNetworkInterfaces() function
Change-Id: I2d0edaa4fced667cd79d8f7170c4a2968abd0390
Refs: #2292
2014-12-15 17:49:06 -08:00
Junxiao Shi 49e11e797e fw: give strategy access to FaceTable
refs #2272
Change-Id: I1a390dac1da8489adcffb71d488b3b8a52d257bd
2014-12-15 11:31:01 -08:00
Junxiao Shi 1e064171da fw: use Signal in FaceTable
refs #2272

Change-Id: I831963b8311c257178ad0da16d62e48b476bfee3
2014-12-15 11:30:55 -08:00
Chengyu Fan 27be0b0d41 tools: nfdc accepts FaceUri in all commands
refs #1995

Change-Id: Ifd05eb835bdf86d6e44bca4f8fe1c973ddb7a6ee
2014-12-13 15:33:57 -08:00
Junxiao Shi 1c93cae6c5 fw: add override specifier to Strategy triggers
refs #2281

Change-Id: I5357ac6a93260492900d24c8955fdd7397ef2d27
2014-12-12 06:47:59 -08:00
Steve DiBenedetto cd4ee5fcb4 mgmt,rib: check command length before accessing verb
refs: #2151

Change-Id: I0e67fd4b4df10d842648797ed42771af7c53a938
2014-12-09 00:12:43 -07:00
Junxiao Shi ac7b437cdb table/face: fix unused variable warnings in NameTree and NDNLP Slicer
refs #2290, #2287

Change-Id: I40f80f4c8a9fe830edafeada2bbd0b881194d0a3
2014-12-15 07:33:22 -08:00
Junxiao Shi 584a569a26 fw: use UnitTestClock in BestRouteStrategy2 test
refs #2160

Change-Id: I555337ecd913f73f93116455079a1a83ff7dfbc3
2014-12-14 17:39:19 -08:00
Alexander Afanasyev 70aaf8ad81 face: Prevent infinite loop in TcpFactory and UdpFactory
Change-Id: Idd694bc08033c524f3c0e569ed74341aa33fce31
Refs: #2292
2014-12-14 17:32:29 -08:00
Alexander Afanasyev 6077b39ae5 build+ci: Fixing compilation and CI scripts
Change-Id: If3c5fe06f19b5aaddc1ee8c7b73b2b3de4c45892
Refs: #2288
2014-12-14 15:05:45 -08:00
Matteo Sammarco 66df974ce8 face: implement NDNLP fragmentation in EthernetFace
Change-Id: I5b9ff271087ca0b2d5ee38be2f77911cfe9283f4
Refs: #1209
2014-12-08 06:35:09 -08:00
Junxiao Shi e368d999a1 table: simplify Measurements with C++11 features
This commit also changes TableMeasurements test suite to use UnitTestTimeFixture.

refs #2100

Change-Id: I6af9fbae435fb50d26f6ec54abc7219680c8ade8
2014-12-07 19:56:27 -07:00
Hila Ben Abraham 2ef995772b tools: display nfd software verion in nfd-status-http-server and nfd-status
refs #1916

Change-Id: I0ba272d4ba9314d483776526d05eaf0f2393dbac
2014-12-06 23:32:34 -08:00
Junxiao Shi afbd74d9f1 core: eliminate MapValueIterator in favor of boost::adaptors::map_values
refs #2239

Change-Id: Ifcc03513b1cbe580de12725baa4338f822a71417
2014-12-04 03:39:16 -08:00
Junxiao Shi 5ccd0c27fd table: use boost::iterator_range in NameTree
refs #2155

Change-Id: I14efacf26aa1143177038fff3cf20d9d845f2c68
2014-12-04 01:41:45 -08:00
Junxiao Shi 4b2e6cb321 table: fix Fib::removeNextHopFromAllEntries invalidating NameTree iterator
refs #2177

Change-Id: I19b8234d94b804273404176d6751a91f082653b7
2014-12-03 10:36:27 -08:00
Davide Pesavento 7726ae5182 face: make EthernetFace more robust against errors.
We now call .fail() instead of throwing an exception.

Also modernize the code with some C++11 features.
In particular, std::unique_ptr is now used to manage
the pcap instance.

Change-Id: I91200ff9ab64ddb2d86f082647043e42ca85f538
Refs: #1984
2014-12-02 20:35:27 +01:00
Junxiao Shi 75ab6b765f fw: use LimitedIo in FwForwarder/SimpleExchange test case
refs #2161

Change-Id: I1aedfe9d75d8aabdb6b096170d5c8b697f812d16
2014-11-30 21:50:27 -08:00
Alexander Afanasyev 6db058c4af build: Embed setting of PKG_CONFIG_PATH variable to commonly used values
Change-Id: I8f70e1bedad13f77bbd40ab53d2e31717836a667
Refs: #2178
2014-11-29 17:52:47 -08:00
Junxiao Shi 60607c734d table: make NameTree enumeration usable with range-based for
NameTree::fullEnumerate and NameTree::partialEnumerate are changed
to return a type usable with range-based for.

NameTree enumeration test cases are also simplified.

refs #2155

Change-Id: I315d9502d2194670aa7054ab956ededefb0c7ca0
2014-11-29 10:35:06 -08:00
Junxiao Shi 2bf8d2a703 table: pit::FaceRecord uses DEFAULT_INTEREST_LIFETIME from ndn-cxx
refs #2202

Change-Id: If3988f34006d0f5e86aa801774f3a9be15bfa9b8
2014-11-29 10:26:15 -08:00
Junxiao Shi 455581daa7 fw: use UnitTestClock in Forwarder persistent loop test case
refs #2162

Change-Id: Ibbf1d5fa615e4275a86caf64f79890d40cb09a77
2014-11-29 10:24:22 -08:00
Junxiao Shi 759f7060e3 build: disable assertions in release builds
refs #2139

Change-Id: Id4cc0b360848d06a0d1e5759cf2017cd1b4227ec
2014-11-29 10:19:22 -07:00
Junxiao Shi 2e0db686bd cs-smoketest: data.wireEncode() before CS insert
refs #2217

Change-Id: Id93d8ab5df4228cf156c53f21891c9b9efb64698
2014-11-27 21:22:27 -07:00
Yanbiao Li c17de8379b rib: remote prefix registration
Change-Id: I0ee01317c213380481eed5c3a13cc19fb0b897ee
Refs: #2056
2014-11-26 21:24:58 -08:00
Davide Pesavento 10783f221d EthernetFace: avoid putting the NIC in promiscuous mode if possible.
Try to use the PACKET_ADD_MEMBERSHIP socket option and the
SIOCADDMULTI ioctl, and only if they fail or are not available
we fall back to promiscuous mode.

Change-Id: Ib534e161ff86ca855e084240b94a166bc4d33ce1
Refs: #1278
2014-11-23 23:38:09 +01:00
Davide Pesavento b499a601b5 core: ignore non-Ethernet AF_LINK addresses when enumerating NICs.
Also modernize the code with some C++11 features.

Change-Id: Ibd29b39c37fdce8f87f917ab0cf48750e631e76c
2014-11-22 20:15:28 -08:00
Junxiao Shi 2b73ca3216 table: make NameTree::findAllMatches usable with range-based for
refs #2155

Change-Id: I298825145cf544faaeeb9e558f6deb6703d434c0
2014-11-19 09:30:08 -08:00
Junxiao Shi 376f73762a tests: use DummyClientFace from ndn-cxx
refs #2186

Change-Id: Ie6f959b846202f201514d757d12d96921fc19bd6
2014-11-19 06:03:28 -08:00
Chengyu Fan ab205c20e6 mgmt: respond Nack when query is invalid
refs #1993

Change-Id: I21e398cd7b2e562b7dc759a89f6e668960e72c41
2014-11-18 11:10:37 -07:00
Alexander Afanasyev ec3e4fc305 tests: Removing usage of deprecated MetaInfo::TYPE_* constants
Change-Id: I475ff8e73e8a7f0478ce62e9a54654aa4ff74e41
Refs: #2128, #1993
2014-11-18 11:56:30 -05:00
Steve DiBenedetto dbcb1a1192 mgmt: remove listen option from unix channel configuration
refs: #2188

Change-Id: I11adf075b03eab3d22f8160e5d619e3ed445dd29
2014-11-17 12:24:44 -07:00
Junxiao Shi 70db992dd1 core: simplify Logger with C++11 features
refs #2146

Change-Id: I6ad9e7281c8a6b60c46b51de727bcddded42ba3d
2014-11-16 21:17:16 -07:00
Junxiao Shi b2bcbcd866 table: simplify PIT with C++11 features
refs #2100

Change-Id: I1159761d9439f0a2ff9f6463f89f39372a696e48
2014-11-14 15:03:18 -08:00
Junxiao Shi a1937bf54c core: use FaceUri from ndn-cxx
refs #2143

Change-Id: Ida06daf406f941a699c9f1013450951db3cd28e9
2014-11-14 12:44:55 -08:00
Junxiao Shi 913806d047 fw: fix clang compilation error in best-route v2 test case
refs #2179

Change-Id: Ibee6e9c27fd3a0aae7bd1611428f986cff1d1df0
2014-11-14 11:45:10 -07:00
Chengyu Fan 320d23334f mgmt: Implement Query Operation in FaceManager
refs #1993

Change-Id: Ieb59bb68bfe839242d1cdd0dd7e3a079a8a0c8de
2014-11-14 03:56:25 -08:00
Junxiao Shi cd55cde10d tools/tests: fix compilation errors caused by bind and placeholders
refs #2175

Change-Id: I65eadb0d0ccf468c3d478236335dbf09aa4dcc71
2014-11-13 16:03:24 -07:00
Junxiao Shi 21303afdf1 common.hpp: delete boost::scoped_ptr
refs #2154

Change-Id: I56730705418a1a10a02b2a0148b8edbf5828f99e
2014-11-12 21:40:36 -07:00
Junxiao Shi 8e273cac72 rib+tools: avoid deprecated ndn::nfd::Controller(Face&) constructor
refs #2039

Change-Id: I8fde413a9f38b18d00b71878b623f0eeb3551b09
2014-11-12 00:42:29 -07:00
Alexander Afanasyev 3651fd75f7 tests: Marking some cs test cases with expected failures
The marked test cases are failing because of the changes with implicit
digest processing.

Change-Id: I6827223c53f576d4377998339cc0e122ae81e52d
Refs: #2157, #1640
2014-11-10 10:41:47 -08:00
Alexander Afanasyev 689f0e9d52 tools+core: Moving Network class implementation to core
Change-Id: I312b827215c8ec3d13aff61584f162125fc48d2a
Refs: #2153
2014-11-09 19:17:11 -08:00
Junxiao Shi 838c4f1a2a table: simplify StrategyChoice with C++11 features
refs #2100

Change-Id: If0082c8561d706df86e92c14cb87762962ff200b
2014-11-09 19:16:07 -08:00
Junxiao Shi 7c7c136dc4 fw: fix best-route v2 strategy test case
refs #2126

Change-Id: I9badfb011385097f7f32c2a7ead3f25e5e8ee032
2014-11-09 17:56:15 -08:00
Junxiao Shi 3a8b1b5add table: simplify dead nonce list with C++11 features
refs #2100

Change-Id: I095bae18f47f4d1c85830fb9ceb87053fe3529e7
2014-11-09 09:47:55 -07:00
Junxiao Shi 56a21bf34a table: simplify FIB with C++11 features
refs #2100

Change-Id: I293044ae321b9a1d7c07a34f631c49c791c7856d
2014-11-07 14:35:01 -08:00
Junxiao Shi 39cd633013 face: use MAX_NDN_PACKET_SIZE constant from ndn-cxx
refs #2099

Change-Id: I46331436e0605f77f6b6ac7b49d50fe1570817b8
2014-11-07 04:20:15 -08:00
Junxiao Shi 3ffe66d4ef core: use ethernet::Address from ndn-cxx
refs #2142

Change-Id: I1258a0a1cadbedb31c506c69c84b7906a61fc761
2014-11-06 20:27:23 -08:00
Wentao Shang 6990e4c7b8 face: drop WebSocket message if the size is larger than maximum NDN packet size
Change-Id: I8e2bd81bbd0d4ba3598ab7c16a3125189b38ca4f
refs: #2081
2014-11-06 19:33:09 -07:00
Junxiao Shi 1f30aac8a2 fw: redesign best-route v2 strategy test case
New test case doesn't require exact timing, so that it's less likely
to fail on a busy/slow system.

refs #2126

Change-Id: I87fc34df40911de56e5acd2b5e5ff6f03c928ecf
2014-11-06 19:32:38 -07:00
Steve DiBenedetto c0640f5e97 mgmt: add config file-based strategy selection
refs: #2053

Change-Id: I76b5945768403578651429ca3170f29d9e66ad54
2014-11-05 09:52:54 -07:00
Alexander Afanasyev b4bac92547 tools: Fix status-http-server hanging when nfd-status output is >64k
Refs: #2121

Change-Id: I84382bc01891cd1c7e52912f9a6ef2c131e1046a
2014-11-04 15:37:41 -08:00
Alexander Afanasyev 4e88e07f76 ci: Make sure we build NFD with tests and precompiled headers
Change-Id: I0f867124bdc76e688152340bcca2f0c2691bd9b2
2014-11-03 13:54:08 -08:00
Junxiao Shi cf1e6e7465 core: use EventEmitter from ndn-cxx
Deleting EventEmitter in core/.

refs #2117

Change-Id: Ieab631c0b3101e313a0af44af7085bcf090596b0
2014-11-02 21:38:22 -07:00
Wentao Shang 306df5eeac build: compile websocketpp in C++11
Change-Id: Iad6a34f2b081030c4806ecc2b8f732206bd80d7a
Refs: #1930, #2082
2014-10-31 19:05:20 -07:00
Davide Pesavento ab1e8f2497 build: Always build in C++11 mode.
This commit also includes update of websocketpp submodule, as the
previous version has compilation problems on OSX with XCode 6.1

Change-Id: I8c9670d0026d840838d77e610e50679ee5ede7a5
Refs: #1930, #2082
2014-10-29 23:53:23 -07:00
Felix Rabe 35eefdfa1a INSTALL.md: Uppercase
Change-Id: I0847869c88c91c5173b85f677dfd3257af9fe4b2
2014-10-27 13:39:58 -07:00
Alexander Afanasyev 4d4e725233 ci: Embedding CI build and test running script
This commit also unifies build and test scripts for Jenkins and Travis CI

Change-Id: Ieaf2d8793c2320a23ce9958c9cf06b3abd4d500f
2014-10-26 18:24:45 -07:00
Alexander Afanasyev 4cf4170b75 table: Evict unsolicited Data in FIFO order
Change-Id: Iba97441e3e23e686da0612810b09108090e64aca
Refs: #2043
2014-10-20 10:38:10 -04:00
Junxiao Shi 67f11acf5c all: avoid usage of deprecated namespace ndn::Tlv
refs #2079

Change-Id: I3d8748929706726b55fe1a9a0f6ae00857ea3547
2014-10-20 06:52:36 -07:00
Junxiao Shi a110f268c7 fw: use dead Nonce list in pipelines
refs #1953

Change-Id: I0faef2a985b03fe96387c2e0181588713550b9ce
2014-10-19 20:50:48 -07:00
Chengyu Fan dae253025c nfdc: ensure FaceUri is in canonical form
refs #1909

Change-Id: If0560c03f3cafe3cd3a181246a7c185e07ade1ca
2014-10-19 14:08:30 -06:00
Chengyu Fan 9942cea529 tools, tests: replace FaceFlags with individual fields
refs #1992

Change-Id: Ic635deb5c6c03f2eba4c440357ca435a46a91588
2014-10-14 11:24:09 -06:00
Chengyu Fan 27d570a089 tools: Display face attribute fields instead of FaceFlags
refs #1991

Change-Id: I413db0afd77ceaa1549fcd11d6cb832fff02020b
2014-10-11 10:32:30 -06:00
Tai-Lin Chu 6687aabbc2 mgmt: allow omitted FaceId in faces/create command
Change-Id: I27655e8b7e67dce88e787a0b4b18fe34cafbf5d5
Refs: #2031
2014-10-09 18:18:22 -07:00
Junxiao Shi 8bfd56d051 fw: NccStrategy proper detection for new PIT entry
A PIT entry during straggler timer should be treated as new PIT entry
for strategy purposes.

refs #1971

Change-Id: I1156630ac0635f8e311a4f18400c5d7b535e3f20
2014-10-09 16:57:11 -07:00
Junxiao Shi 15539105df fw: optimize FwNccStrategy/FavorRespondingUpstream test case
This test case previously relies on precise timing, and the slack is 3ms
in the worst case. Failure rate is high if system is slow.
This commit optimizes this tests case with several operation-limited
io runs, so that it doesn't rely on precise timing.

refs #2037

Change-Id: I80b87d830dcf8d87fce511e79eb9349f75c1c34d
2014-10-09 16:13:00 -07:00
Chengyu Fan f9c2bb19fe mgmt: replace FaceFlags with individual fields
refs #1992

Change-Id: I41d55b3227c916a253705aaeefbe66c7c18e22a9
2014-10-08 21:56:38 -06:00
Steve DiBenedetto 77c8751576 mgmt: update strategy-choice/set to return a versioned strategy name
refs: #1972

Change-Id: I1616574a4643884dac050d240b771423ec2a0846
2014-10-08 11:53:53 -07:00
Steve DiBenedetto b4336c2e0a test: move general config section test to tests/daemon/mgmt
refs: #1997

Change-Id: I9639226825d2145c5ffe7724ed52743c5b492a14
2014-10-08 11:29:24 -07:00
Junxiao Shi 0e42c574ed table: dead Nonce list
refs #1953

Change-Id: I65eb2346716dd47bcf1850c832e37e5354042fd0
2014-10-07 16:32:51 -07:00
Wentao Shang 98733147f5 face: detect websocket connection failure using ping/pong messages.
Change-Id: I66ef6a3921a56f1bb8e49fb6fdb4fa14b6a379c7
Refs: #1903
2014-10-05 14:57:46 -07:00
Wentao Shang b1c1a83db3 face: update websocketpp submodule to version 0.3.0
Change-Id: Ifc92b49a92cf7c76d1751105abf35ab9da6bfd8f
Refs: #1903
2014-10-01 12:26:35 -07:00
Alexander Afanasyev 60d06387da table: Remove operator== for Exclude, which is now a part of the library
Change-Id: I7b6d80cff6200e2c7d7d8529d2736bc275f1b6e7
2014-09-22 07:38:03 -07:00
Junxiao Shi e93d6a3401 table: allow strategy versioning
refs #1893

Change-Id: I44eb8dd319d737d786b6ce6f753ae2f9076cf9c1
2014-09-08 14:09:01 -07:00
Junxiao Shi 82e7f58c4f fw: NccStrategy remembers only best face
refs #1961

Strategy::beforeSatisfyPendingInterest is renamed to
Strategy::beforeSatisfyInterest, so as to match the semantics of this trigger.
This is a backwards-incompatible change that requires function renaming in
all subclasses of Strategy class.

LimitedIo::afterOp gets a bugfix that allows it to be invoked out of
LimitedIo::run without leaving io_service unusable.

Change-Id: Ia4c632beb62c554724b83846a3d6358ae08779ad
2014-09-07 15:21:02 -07:00
Alexander Afanasyev 3b21fa3258 build: Fix build error with python3
Change-Id: Ie90c6a9856b2616131ff9c0c3916aede1978ea94
Refs: #1302
2014-09-02 19:43:10 -07:00
Alexander Afanasyev c2642ca20c tools: Small formatting correction in plain text output of nfd-status
Change-Id: I7657d10ce91ce7f90d264296e69b87179c08c1a7
2014-09-02 18:54:31 -07:00
Yingdi Yu 7b0e9cf792 tools: Publish /localhop/ndn-autoconf/routable-prefixes from ndn-autoconfig-server
Change-Id: I2902b91cebf1f4b8ac1a7dabedb0f0cbd0a13b24
Refs: #1954
2014-09-02 11:01:24 -07:00
Davide Pesavento 3f5655fce5 face: Fix spurious assertion failure in StreamFace
Change-Id: Id487ae8d01ab3dc0ffa647dc69ff594f8a1d3c12
Refs: #1856
2014-08-30 21:45:23 +02:00
Alexander Afanasyev 86bc91ae56 face: Allow trailing slash for UDP and TCP FaceUri's
Change-Id: I472bfdaf1e032f70dbba24a0d5a3117f198a526d
Refs: #1944
2014-08-28 22:29:16 -07:00
Alexander Afanasyev 2075788ffc docs: Update to generate proper google analytics code
This commit also includes minor doxygen style improvement.

Change-Id: I5ced859c0759a2fd0240068296949067f9ac4c46
2014-08-26 13:52:52 -07:00
494 changed files with 42848 additions and 32063 deletions

No files matched your search

+1
View File
@@ -5,3 +5,4 @@
**/*.pyc
build/
VERSION
unit-tests.conf
Executable
+10
View File
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -e
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
for file in "$DIR"/.jenkins.d/*; do
[[ -f $file && -x $file ]] || continue
echo "Run: $file"
"$file"
done
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
if has OSX $NODE_LABELS; then
if has OSX-10.8 $NODE_LABELS; then
EXTRA_FLAGS=--c++11
fi
set -x
brew update
brew upgrade
brew install boost pkg-config cryptopp $EXTRA_FLAGS
brew cleanup
fi
if has Ubuntu $NODE_LABELS; then
BOOST_PKG=libboost-all-dev
if has Ubuntu-12.04 $NODE_LABELS; then
BOOST_PKG=libboost1.48-all-dev
fi
set -x
sudo apt-get update -qq -y
sudo apt-get -qq -y install build-essential pkg-config $BOOST_PKG \
libcrypto++-dev libsqlite3-dev libpcap-dev
fi
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
set -x
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
pushd ${CACHE_DIR:-/tmp} >/dev/null
INSTALLED_VERSION=$((cd ndn-cxx && git rev-parse HEAD) 2>/dev/null || echo NONE)
sudo rm -Rf ndn-cxx-latest
git clone --depth 1 git://github.com/named-data/ndn-cxx ndn-cxx-latest
LATEST_VERSION=$((cd ndn-cxx-latest && git rev-parse HEAD) 2>/dev/null || echo UNKNOWN)
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
sudo rm -Rf ndn-cxx
mv ndn-cxx-latest ndn-cxx
else
sudo rm -Rf ndn-cxx-latest
fi
sudo rm -Rf /usr/local/include/ndn-cxx
sudo rm -f /usr/local/lib/libndn-cxx*
sudo rm -f /usr/local/lib/pkgconfig/libndn-cxx*
pushd ndn-cxx >/dev/null
./waf configure -j1 --color=yes --enable-shared --disable-static --without-osx-keychain
./waf -j1 --color=yes
sudo ./waf install -j1 --color=yes
popd >/dev/null
popd >/dev/null
if has Linux $NODE_LABELS; then
sudo ldconfig
elif has FreeBSD $NODE_LABELS; then
sudo ldconfig -a
fi
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -x
set -e
git submodule init
git submodule sync
git submodule update
# Cleanup
sudo ./waf -j1 --color=yes distclean
# Configure/build in optimized mode with tests and precompiled headers
./waf -j1 --color=yes configure --with-tests
./waf -j1 --color=yes build
# Cleanup
sudo ./waf -j1 --color=yes distclean
# Configure/build in optimized mode without tests and with precompiled headers
./waf -j1 --color=yes configure
./waf -j1 --color=yes build
# Cleanup
sudo ./waf -j1 --color=yes distclean
# Configure/build in debug mode
if [[ "$JOB_NAME" == *"code-coverage" ]]; then
COVERAGE="--with-coverage"
fi
./waf -j1 --color=yes configure --debug --with-tests --without-pch $COVERAGE
./waf -j1 --color=yes build
# (tests will be run against debug version)
# Install
sudo ./waf -j1 --color=yes install
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -x
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
# Prepare environment
rm -Rf ~/.ndnx ~/.ndn
if has OSX $NODE_LABELS; then
security unlock-keychain -p "named-data"
sudo chgrp admin /dev/bpf*
sudo chmod g+rw /dev/bpf*
fi
if has Linux $NODE_LABELS; then
sudo setcap cap_net_raw,cap_net_admin=eip `pwd`/build/unit-tests-core || true
sudo setcap cap_net_raw,cap_net_admin=eip `pwd`/build/unit-tests-daemon || true
sudo setcap cap_net_raw,cap_net_admin=eip `pwd`/build/unit-tests-rib || true
fi
ndnsec-keygen "/tmp/jenkins/$NODE_NAME" | ndnsec-install-cert -
# Run unit tests
# Core
if [[ -n $XUNIT ]]; then
./build/unit-tests-core -l all -- --log_format2=XML --log_sink2=build/xunit-core-report.xml
sudo ./build/unit-tests-core -t TestPrivilegeHelper -l all -- --log_format2=XML --log_sink2=build/xunit-core-sudo-report.xml
./build/unit-tests-daemon -l all -- --log_format2=XML --log_sink2=build/xunit-daemon-report.xml
./build/unit-tests-rib -l all -- --log_format2=XML --log_sink2=build/xunit-rib-report.xml
else
./build/unit-tests-core -l test_suite
sudo ./build/unit-tests-core -t TestPrivilegeHelper -l test_suite
./build/unit-tests-daemon -l test_suite
./build/unit-tests-rib -l test_suite
fi
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -x
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
if [[ "$JOB_NAME" == *"code-coverage" ]]; then
BASE="`pwd | sed -e 's|/|\\\/|g'`\\"
(cd build && gcovr -x -f $BASE/core -f $BASE/daemon -f $BASE/rib -r ../ -o coverage.xml ./)
fi
+33
View File
@@ -0,0 +1,33 @@
CONTINUOUS INTEGRATION SCRIPTS
==============================
Environment Variables Used in Build Scripts
-------------------------------------------
- `NODE_LABELS`: the variable defines a list of OS properties. The set values are used by the
build scripts to select proper behavior for different OS.
The list should include at least `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
Possible values for Linux OS:
* `[OS_TYPE]`: `Linux`
* `[DISTRO_TYPE]`: `Ubuntu`
* `[DISTRO_VERSION]`: `Ubuntu-12.04`, `Ubuntu-14.04`, `Ubuntu-15.04`
Possible values of OSX OS:
* `[OS_TYPE]`: `OSX`
* `[DISTRO_TYPE]`: `OSX` (can be absent)
* `[DISTRO_VERSION]`: `OSX-10.10`, `OSX-10.9`, `OSX-10.8`, `OSX-10.7`
- `JOB_NAME`: optional variable to define type of the job. Depending on the defined job type,
the build scripts can perform different tasks.
Possible values:
* empty: default build process
* `code-coverage` (Linux OS is assumed): build process with code coverage analysis
- `CACHE_DIR`: the variable defines a path to folder containing cached files from previous builds,
e.g., a compiled version of ndn-cxx library. If not set, `/tmp` is used.
+9
View File
@@ -0,0 +1,9 @@
has() {
local p=$1
shift
local x
for x in "$@"; do
[[ "${x}" == "${p}" ]] && return 0
done
return 1
}
+5 -33
View File
@@ -1,4 +1,4 @@
# For Ubuntu only
sudo: true
language: cpp
os:
- linux
@@ -8,36 +8,8 @@ notifications:
email:
on_success: always
on_failure: always
before_install:
- travis_retry sudo apt-get update
- travis_retry sudo apt-get install -qq libssl-dev libpcap-dev libboost1.48-all-dev libcrypto++-dev libsqlite3-dev
- travis_retry git clone --depth 1 git://github.com/named-data/ndn-cxx ndn-cxx
- cd ndn-cxx
- ./waf configure
- ./waf -j1
- sudo ./waf install
- sudo ldconfig
- cd ..
- ndnsec-keygen /tmp/key | ndnsec-install-cert -
script:
- ./waf configure --with-tests
- ./waf -j1
- sudo ./waf install
- ./build/unit-tests-core
- ./build/unit-tests-daemon
- ./build/unit-tests-rib
# Tutorial for setting up notifications:
# http://docs.travis-ci.com/user/notifications/
# Here's a simple example for email notifications:
#
# notifications:
# email:
# recipients:
# - one@example.com
# - other@example.com
# on_success: [always|never|change] # default: change
# on_failure: [always|never|change] # default: always
#
# There are also other types of notifications available, including:
# IRC, Campfire, Flowdock, HipChat, and Webhook.
# For more infomation about notifications, please visit the link above.
- if [[ $TRAVIS_OS_NAME == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-12.04"; fi
- if [[ $TRAVIS_OS_NAME == osx ]]; then export NODE_LABELS="OSX OSX-10.10"; fi
- echo $NODE_LABELS
- ./.jenkins
+3 -2
View File
@@ -8,13 +8,14 @@ from waflib import Configure
BOOST_ASIO_HAS_KQUEUE_CHECK = '''
#include <boost/asio.hpp>
#if defined(BOOST_ASIO_HAS_KQUEUE) and BOOST_VERSION >= 105600
#error "Ethernet face support cannot be enabled on this platform"
#if defined(BOOST_ASIO_HAS_KQUEUE) and BOOST_VERSION == 105600
#error "Ethernet face support cannot be enabled on this platform with boost 1.56"
#endif
'''
@Configure.conf
def check_asio_pcap_support(conf):
# https://svn.boost.org/trac/boost/ticket/10367
if conf.check_cxx(msg='Checking if Ethernet face support can be enabled',
fragment=BOOST_ASIO_HAS_KQUEUE_CHECK,
features='cxx', use='BOOST', mandatory=False):
+216 -76
View File
@@ -30,15 +30,15 @@ When using this tool, the wscript will look like:
Options are generated, in order to specify the location of boost includes/libraries.
The `check_boost` configuration function allows to specify the used boost libraries.
It can also provide default arguments to the --boost-static and --boost-mt command-line arguments.
It can also provide default arguments to the --boost-mt command-line arguments.
Everything will be packaged together in a BOOST component that you can use.
When using MSVC, a lot of compilation flags need to match your BOOST build configuration:
- you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined.
Errors: C4530
- boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC
So before calling `conf.check_boost` you might want to disabling by adding:
conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
So before calling `conf.check_boost` you might want to disabling by adding
conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
Errors:
- boost might also be compiled with /MT, which links the runtime statically.
If you have problems with redefined symbols,
@@ -52,24 +52,55 @@ import sys
import re
from waflib import Utils, Logs, Errors
from waflib.Configure import conf
from waflib.TaskGen import feature, after_method
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib', '/usr/lib/x86_64-linux-gnu', '/usr/lib/i386-linux-gnu', '/usr/local/ndn/lib']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include', '/usr/local/ndn/include']
BOOST_LIBS = ['/usr/lib/x86_64-linux-gnu', '/usr/lib/i386-linux-gnu',
'/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
BOOST_VERSION_FILE = 'boost/version.hpp'
BOOST_VERSION_CODE = '''
#include <iostream>
#include <boost/version.hpp>
int main() { std::cout << BOOST_LIB_VERSION << ":" << BOOST_VERSION << std::endl; }
'''
BOOST_SYSTEM_CODE = '''
BOOST_ERROR_CODE = '''
#include <boost/system/error_code.hpp>
int main() { boost::system::error_code c; }
'''
PTHREAD_CODE = '''
#include <pthread.h>
static void* f(void*) { return 0; }
int main() {
pthread_t th;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&th, &attr, &f, 0);
pthread_join(th, 0);
pthread_cleanup_push(0, 0);
pthread_cleanup_pop(0);
pthread_attr_destroy(&attr);
}
'''
BOOST_THREAD_CODE = '''
#include <boost/thread.hpp>
int main() { boost::thread t; }
'''
BOOST_LOG_CODE = '''
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
int main() {
using namespace boost::log;
add_common_attributes();
add_console_log(std::clog, keywords::format = "%Message%");
BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl;
}
'''
# toolsets from {boost_dir}/tools/build/v2/tools/common.jam
PLATFORM = Utils.unversioned_sys_platform()
detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
@@ -101,34 +132,37 @@ BOOST_TOOLSETS = {
def options(opt):
opt = opt.add_option_group('Boost Options')
opt.add_option('--boost-includes', type='string',
default='', dest='boost_includes',
help='''path to the directory where the boost includes are, e.g., /path/to/boost_1_55_0/stage/include''')
help='''path to the directory where the boost includes are,
e.g., /path/to/boost_1_55_0/stage/include''')
opt.add_option('--boost-libs', type='string',
default='', dest='boost_libs',
help='''path to the directory where the boost libs are, e.g., /path/to/boost_1_55_0/stage/lib''')
opt.add_option('--boost-static', action='store_true',
default=False, dest='boost_static',
help='link with static boost libraries (.lib/.a)')
help='''path to the directory where the boost libs are,
e.g., path/to/boost_1_55_0/stage/lib''')
opt.add_option('--boost-mt', action='store_true',
default=False, dest='boost_mt',
help='select multi-threaded libraries')
opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
help='''select libraries with tags (dgsyp, d for debug), see doc Boost, Getting Started, chapter 6.1''')
help='''select libraries with tags (gd for debug, static is automatically added),
see doc Boost, Getting Started, chapter 6.1''')
opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
opt.add_option('--boost-toolset', type='string',
default='', dest='boost_toolset',
help='force a toolset e.g. msvc, vc90, gcc, mingw, mgw45 (default: auto)')
help='force a toolset e.g. msvc, vc90, \
gcc, mingw, mgw45 (default: auto)')
py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
opt.add_option('--boost-python', type='string',
default=py_version, dest='boost_python',
help='select the lib python with this version (default: %s)' % py_version)
help='select the lib python with this version \
(default: %s)' % py_version)
@conf
def __boost_get_version_file(self, d):
if not d:
return None
dnode = self.root.find_dir(d)
if dnode:
return dnode.find_node(BOOST_VERSION_FILE)
@@ -141,18 +175,15 @@ def boost_get_version(self, d):
if node:
try:
txt = node.read()
except (OSError, IOError):
except EnvironmentError:
Logs.error("Could not read the file %r" % node.abspath())
else:
re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M)
m1 = re_but1.search(txt)
re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+(\\d+)', re.M)
m2 = re_but2.search(txt)
if m1 and m2:
return (m1.group(1), m2.group(1))
return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":")
@conf
@@ -160,7 +191,7 @@ def boost_get_includes(self, *k, **kw):
includes = k and k[0] or kw.get('includes', None)
if includes and self.__boost_get_version_file(includes):
return includes
for d in Utils.to_list(self.environ.get('INCLUDE', '')) + BOOST_INCLUDES:
for d in self.environ.get('INCLUDE', '').split(';') + BOOST_INCLUDES:
if self.__boost_get_version_file(d):
return d
if includes:
@@ -195,7 +226,9 @@ def __boost_get_libs_path(self, *k, **kw):
path = self.root.find_dir(libs)
files = path.ant_glob('*boost_*')
if not libs or not files:
for d in Utils.to_list(self.environ.get('LIB', [])) + BOOST_LIBS:
for d in self.environ.get('LIB', '').split(';') + BOOST_LIBS:
if not d:
continue
path = self.root.find_dir(d)
if path:
files = path.ant_glob('*boost_*')
@@ -226,15 +259,10 @@ def boost_get_libs(self, *k, **kw):
according to the parameters
'''
path, files = self.__boost_get_libs_path(**kw)
t = []
if kw.get('mt', False):
t.append('mt')
if kw.get('abi', None):
t.append(kw['abi'])
tags = t and '(-%s)+' % '-'.join(t) or ''
files = sorted(files, key=lambda f: (len(f.name), f.name), reverse=True)
toolset = self.boost_get_toolset(kw.get('toolset', ''))
toolset_pat = '(-%s[0-9]{0,3})+' % toolset
version = '(-%s)+' % self.env.BOOST_VERSION
toolset_pat = '(-%s[0-9]{0,3})' % toolset
version = '-%s' % self.env.BOOST_VERSION
def find_lib(re_lib, files):
for file in files:
@@ -248,28 +276,110 @@ def boost_get_libs(self, *k, **kw):
name = name[3:]
return name[:name.rfind('.')]
libs = []
for lib in Utils.to_list(k and k[0] or kw.get('lib', None)):
py = (lib == 'python') and '(-py%s)+' % kw['python'] or ''
# Trying libraries, from most strict match to least one
for pattern in ['boost_%s%s%s%s%s' % (lib, toolset_pat, tags, py, version),
'boost_%s%s%s%s' % (lib, tags, py, version),
'boost_%s%s%s' % (lib, tags, version),
# Give up trying to find the right version
'boost_%s%s%s%s' % (lib, toolset_pat, tags, py),
'boost_%s%s%s' % (lib, tags, py),
'boost_%s%s' % (lib, tags)]:
self.to_log('Trying pattern %s' % pattern)
file = find_lib(re.compile(pattern), files)
if file:
libs.append(format_lib_name(file.name))
break
else:
self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
self.fatal('The configuration failed')
def match_libs(lib_names, is_static):
libs = []
lib_names = Utils.to_list(lib_names)
if not lib_names:
return libs
t = []
if kw.get('mt', False):
t.append('-mt')
if kw.get('abi', None):
t.append('%s%s' % (is_static and '-s' or '-', kw['abi']))
elif is_static:
t.append('-s')
tags_pat = t and ''.join(t) or ''
ext = is_static and self.env.cxxstlib_PATTERN or self.env.cxxshlib_PATTERN
ext = ext.partition('%s')[2] # remove '%s' or 'lib%s' from PATTERN
return path.abspath(), libs
for lib in lib_names:
if lib == 'python':
# for instance, with python='27',
# accepts '-py27', '-py2', '27' and '2'
# but will reject '-py3', '-py26', '26' and '3'
tags = '({0})?((-py{2})|(-py{1}(?=[^0-9]))|({2})|({1}(?=[^0-9]))|(?=[^0-9])(?!-py))'.format(tags_pat, kw['python'][0], kw['python'])
else:
tags = tags_pat
# Trying libraries, from most strict match to least one
for pattern in ['boost_%s%s%s%s%s$' % (lib, toolset_pat, tags, version, ext),
'boost_%s%s%s%s$' % (lib, tags, version, ext),
# Give up trying to find the right version
'boost_%s%s%s%s$' % (lib, toolset_pat, tags, ext),
'boost_%s%s%s$' % (lib, tags, ext),
'boost_%s%s$' % (lib, ext),
'boost_%s' % lib]:
self.to_log('Trying pattern %s' % pattern)
file = find_lib(re.compile(pattern), files)
if file:
libs.append(format_lib_name(file.name))
break
else:
self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
self.fatal('The configuration failed')
return libs
return path.abspath(), match_libs(kw.get('lib', None), False), match_libs(kw.get('stlib', None), True)
@conf
def _check_pthread_flag(self, *k, **kw):
'''
Computes which flags should be added to CXXFLAGS and LINKFLAGS to compile in multi-threading mode
Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3,
boost/thread.hpp will trigger a #error if -pthread isn't used:
boost/config/requires_threads.hpp:47:5: #error "Compiler threading support
is not turned on. Please set the correct command line options for
threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)"
Based on _BOOST_PTHREAD_FLAG(): https://github.com/tsuna/boost.m4/blob/master/build-aux/boost.m4
'''
var = kw.get('uselib_store', 'BOOST')
self.start_msg('Checking the flags needed to use pthreads')
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# (none): in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -lpthreads: AIX (must check this before -lpthread)
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads)
# -pthreads: Solaris/GCC
# -mthreads: MinGW32/GCC, Lynx/GCC
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# -lpthread: GNU Linux, etc.
# --thread-safe: KAI C++
if Utils.unversioned_sys_platform() == "sunos":
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"]
else:
boost_pthread_flags = ["", "-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread",
"-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"]
for boost_pthread_flag in boost_pthread_flags:
try:
self.env.stash()
self.env['CXXFLAGS_%s' % var] += [boost_pthread_flag]
self.env['LINKFLAGS_%s' % var] += [boost_pthread_flag]
self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False)
self.end_msg(boost_pthread_flag)
return
except self.errors.ConfigurationError:
self.env.revert()
self.end_msg('None')
@conf
def check_boost(self, *k, **kw):
@@ -282,7 +392,10 @@ def check_boost(self, *k, **kw):
if not self.env['CXX']:
self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
params = {'lib': k and k[0] or kw.get('lib', None)}
params = {
'lib': k and k[0] or kw.get('lib', None),
'stlib': kw.get('stlib', None)
}
for key, value in self.options.__dict__.items():
if not key.startswith('boost_'):
continue
@@ -297,42 +410,53 @@ def check_boost(self, *k, **kw):
self.env.BOOST_VERSION = versions[0]
self.env.BOOST_VERSION_NUMBER = int(versions[1])
self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000,
int(versions[1]) / 100 % 1000,
int(versions[1]) % 100))
int(versions[1]) / 100 % 1000,
int(versions[1]) % 100))
if Logs.verbose:
Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
if not params['lib']:
if not params['lib'] and not params['stlib']:
return
if 'static' in kw or 'static' in params:
Logs.warn('boost: static parameter is deprecated, use stlib instead.')
self.start_msg('Checking boost libs')
suffix = params.get('static', None) and 'ST' or ''
path, libs = self.boost_get_libs(**params)
self.env['%sLIBPATH_%s' % (suffix, var)] = [path]
self.env['%sLIB_%s' % (suffix, var)] = libs
path, libs, stlibs = self.boost_get_libs(**params)
self.env['LIBPATH_%s' % var] = [path]
self.env['STLIBPATH_%s' % var] = [path]
self.env['LIB_%s' % var] = libs
self.env['STLIB_%s' % var] = stlibs
self.end_msg('ok')
if Logs.verbose:
Logs.pprint('CYAN', ' path : %s' % path)
Logs.pprint('CYAN', ' libs : %s' % libs)
Logs.pprint('CYAN', ' shared libs : %s' % libs)
Logs.pprint('CYAN', ' static libs : %s' % stlibs)
def has_shlib(lib):
return params['lib'] and lib in params['lib']
def has_stlib(lib):
return params['stlib'] and lib in params['stlib']
def has_lib(lib):
return has_shlib(lib) or has_stlib(lib)
if has_lib('thread'):
# not inside try_link to make check visible in the output
self._check_pthread_flag(k, kw)
def try_link():
if 'system' in params['lib']:
self.check_cxx(
fragment=BOOST_SYSTEM_CODE,
use=var,
execute=False,
)
if 'thread' in params['lib']:
self.check_cxx(
fragment=BOOST_THREAD_CODE,
use=var,
execute=False,
)
if has_lib('system'):
self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False)
if has_lib('thread'):
self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False)
if has_lib('log'):
if not has_lib('thread'):
self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS']
if has_shlib('log'):
self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK']
self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)
if params.get('linkage_autodetect', False):
self.start_msg("Attempting to detect boost linkage flags")
toolset = self.boost_get_toolset(kw.get('toolset', ''))
if toolset in ['vc']:
if toolset in ('vc',):
# disable auto-linking feature, causing error LNK1181
# because the code wants to be linked against
self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
@@ -356,14 +480,14 @@ def check_boost(self, *k, **kw):
try:
try_link()
self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var]))
e = None
exc = None
break
except Errors.ConfigurationError as exc:
except Errors.ConfigurationError as e:
self.env.revert()
e = exc
exc = e
if e is not None:
self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=e)
if exc is not None:
self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=exc)
self.fatal('The configuration failed')
else:
self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain")
@@ -376,3 +500,19 @@ def check_boost(self, *k, **kw):
self.end_msg("Could not link against boost libraries using supplied options")
self.fatal('The configuration failed')
self.end_msg('ok')
@feature('cxx')
@after_method('apply_link')
def install_boost(self):
if install_boost.done or not Utils.is_win32 or not self.bld.cmd.startswith('install'):
return
install_boost.done = True
inst_to = getattr(self, 'install_path', '${BINDIR}')
for lib in self.env.LIB_BOOST:
try:
file = self.bld.find_file(self.env.cxxshlib_PATTERN % lib, self.env.LIBPATH_BOOST)
self.bld.install_files(inst_to, self.bld.root.find_node(file))
except:
continue
install_boost.done = False
+63
View File
@@ -0,0 +1,63 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
from waflib.Configure import conf
OVERRIDE = '''
class Base
{
virtual void
f(int a);
};
class Derived : public Base
{
virtual void
f(int a) override;
};
'''
@conf
def check_override(self):
self.check_cxx(msg='Checking for override specifier',
fragment=OVERRIDE,
define_name='HAVE_CXX_OVERRIDE',
features='cxx', mandatory=False)
FINAL = '''
class Base
{
virtual void
f(int a);
};
class Derived : public Base
{
virtual void
f(int a) final;
};
'''
@conf
def check_final(self):
self.check_cxx(msg='Checking for final specifier on method',
fragment=FINAL,
define_name='HAVE_CXX_FINAL',
features='cxx', mandatory=False)
CLASS_FINAL = '''
class A final
{
};
'''
@conf
def check_class_final(self):
self.check_cxx(msg='Checking for final specifier on class',
fragment=CLASS_FINAL,
define_name='HAVE_CXX_CLASS_FINAL',
features='cxx', mandatory=False)
def configure(conf):
conf.check_override()
conf.check_final()
conf.check_class_final()
+3 -5
View File
@@ -1,10 +1,6 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
#
# Copyright (c) 2014, Regents of the University of California
#
# GPL 3.0 license, see the COPYING.md file for more information
from waflib import TaskGen
from waflib import TaskGen, Logs
def options(opt):
opt.add_option('--with-coverage', action='store_true', default=False, dest='with_coverage',
@@ -12,6 +8,8 @@ def options(opt):
def configure(conf):
if conf.options.with_coverage:
if not conf.options.debug:
conf.fatal("Code coverage flags require debug mode compilation (add --debug)")
conf.check_cxx(cxxflags=['-fprofile-arcs', '-ftest-coverage', '-fPIC'],
linkflags=['-fprofile-arcs'], uselib_store='GCOV', mandatory=True)
+152 -31
View File
@@ -1,57 +1,58 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
#
# Copyright (c) 2014, Regents of the University of California
#
# GPL 3.0 license, see the COPYING.md file for more information
from waflib import Logs, Configure
from waflib import Logs, Configure, Utils
def options(opt):
opt.add_option('--debug', '--with-debug', action='store_true', default=False, dest='debug',
help='''Compile in debugging mode without all optimizations (-O0)''')
opt.add_option('--with-c++11', action='store_true', default=False, dest='use_cxx11',
help='''Enable C++11 mode (experimental, may not work)''')
help='''Compile in debugging mode without optimizations (-O0 or -Og)''')
def configure(conf):
areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
defaultFlags = []
if conf.options.use_cxx11:
defaultFlags += ['-std=c++0x', '-std=c++11']
cxx = conf.env['CXX_NAME'] # CXX_NAME represents generic name of the compiler
if cxx == 'gcc':
flags = GccFlags()
elif cxx == 'clang':
flags = ClangFlags()
else:
defaultFlags += ['-std=c++03', '-Wno-variadic-macros', '-Wno-c99-extensions']
flags = CompilerFlags()
Logs.warn('The code has not yet been tested with %s compiler' % cxx)
defaultFlags += ['-pedantic', '-Wall', '-Wno-long-long', '-Wno-unneeded-internal-declaration']
areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
# General flags are always applied (e.g., selecting C++11 mode)
generalFlags = flags.getGeneralFlags(conf)
conf.add_supported_cxxflags(generalFlags['CXXFLAGS'])
conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
conf.env.DEFINES += generalFlags['DEFINES']
# Debug or optimized CXXFLAGS and LINKFLAGS are applied only if the
# corresponding environment variables are not set.
# DEFINES are always applied.
if conf.options.debug:
conf.define('_DEBUG', 1)
defaultFlags += ['-O0',
'-Og', # gcc >= 4.8
'-g3',
'-fcolor-diagnostics', # clang
'-fdiagnostics-color', # gcc >= 4.9
'-Werror',
'-Wno-error=maybe-uninitialized', # Bug #1560
]
extraFlags = flags.getDebugFlags(conf)
if areCustomCxxflagsPresent:
missingFlags = [x for x in defaultFlags if x not in conf.env.CXXFLAGS]
missingFlags = [x for x in extraFlags['CXXFLAGS'] if x not in conf.env.CXXFLAGS]
if len(missingFlags) > 0:
Logs.warn("Selected debug mode, but CXXFLAGS is set to a custom value '%s'"
% " ".join(conf.env.CXXFLAGS))
Logs.warn("Default flags '%s' are not activated" % " ".join(missingFlags))
else:
conf.add_supported_cxxflags(defaultFlags)
else:
defaultFlags += ['-O2', '-g']
if not areCustomCxxflagsPresent:
conf.add_supported_cxxflags(defaultFlags)
extraFlags = flags.getOptimizedFlags(conf)
if not areCustomCxxflagsPresent:
conf.add_supported_cxxflags(extraFlags['CXXFLAGS'])
conf.add_supported_linkflags(extraFlags['LINKFLAGS'])
conf.env.DEFINES += extraFlags['DEFINES']
@Configure.conf
def add_supported_cxxflags(self, cxxflags):
"""
Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
"""
self.start_msg('Checking allowed flags for c++ compiler')
if len(cxxflags) == 0:
return
self.start_msg('Checking supported CXXFLAGS')
supportedFlags = []
for flag in cxxflags:
@@ -60,3 +61,123 @@ def add_supported_cxxflags(self, cxxflags):
self.end_msg(' '.join(supportedFlags))
self.env.CXXFLAGS = supportedFlags + self.env.CXXFLAGS
@Configure.conf
def add_supported_linkflags(self, linkflags):
"""
Check which linkflags are supported by compiler and add them to env.LINKFLAGS variable
"""
if len(linkflags) == 0:
return
self.start_msg('Checking supported LINKFLAGS')
supportedFlags = []
for flag in linkflags:
if self.check_cxx(linkflags=['-Werror', flag], mandatory=False):
supportedFlags += [flag]
self.end_msg(' '.join(supportedFlags))
self.env.LINKFLAGS = supportedFlags + self.env.LINKFLAGS
class CompilerFlags(object):
def getGeneralFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
def getDebugFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['_DEBUG']}
def getOptimizedFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in optimized mode"""
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['NDEBUG']}
class GccBasicFlags(CompilerFlags):
"""
This class defines basic flags that work for both gcc and clang compilers
"""
def getDebugFlags(self, conf):
flags = super(GccBasicFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-O0',
'-g3',
'-pedantic',
'-Wall',
'-Wextra',
'-Werror',
'-Wno-unused-parameter',
'-Wno-error=maybe-uninitialized', # Bug #1615
]
return flags
def getOptimizedFlags(self, conf):
flags = super(GccBasicFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-O2',
'-g',
'-pedantic',
'-Wall',
'-Wextra',
'-Wno-unused-parameter',
]
return flags
class GccFlags(GccBasicFlags):
def getGeneralFlags(self, conf):
flags = super(GccFlags, self).getGeneralFlags(conf)
version = tuple(int(i) for i in conf.env['CC_VERSION'])
if version < (4, 6, 0):
conf.fatal('The version of gcc you are using (%s) is too old.\n' %
'.'.join(conf.env['CC_VERSION']) +
'The minimum supported gcc version is 4.6.0.')
elif version < (4, 7, 0):
flags['CXXFLAGS'] += ['-std=c++0x']
else:
flags['CXXFLAGS'] += ['-std=c++11']
if version < (4, 8, 0):
flags['DEFINES'] += ['_GLIBCXX_USE_NANOSLEEP'] # Bug #2499
return flags
def getDebugFlags(self, conf):
flags = super(GccFlags, self).getDebugFlags(conf)
version = tuple(int(i) for i in conf.env['CC_VERSION'])
if version < (5, 1, 0):
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
flags['CXXFLAGS'] += ['-Og', # gcc >= 4.8
'-fdiagnostics-color', # gcc >= 4.9
]
return flags
def getOptimizedFlags(self, conf):
flags = super(GccFlags, self).getOptimizedFlags(conf)
version = tuple(int(i) for i in conf.env['CC_VERSION'])
if version < (5, 1, 0):
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
return flags
class ClangFlags(GccBasicFlags):
def getGeneralFlags(self, conf):
flags = super(ClangFlags, self).getGeneralFlags(conf)
flags['CXXFLAGS'] += ['-std=c++11']
if Utils.unversioned_sys_platform() == 'darwin':
flags['CXXFLAGS'] += ['-stdlib=libc++']
flags['LINKFLAGS'] += ['-stdlib=libc++']
return flags
def getDebugFlags(self, conf):
flags = super(ClangFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
'-Wno-error=unneeded-internal-declaration', # Bug #1588
'-Wno-error=deprecated-register',
'-Wno-error=keyword-macro', # Bug #3235
]
return flags
def getOptimizedFlags(self, conf):
flags = super(ClangFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
return flags
+1 -1
View File
@@ -85,7 +85,7 @@ class doxygen(Task.Task):
# Override with any parameters passed to the task generator
if getattr(self.generator, 'pars', None):
for k, v in self.generator.pars.iteritems():
for k, v in self.generator.pars.items():
self.pars[k] = v
self.doxy_inputs = getattr(self, 'doxy_inputs', [])
+5
View File
@@ -67,6 +67,11 @@ def options(opt):
def configure(conf):
if (conf.options.with_pch and conf.env['COMPILER_CXX'] in PCH_COMPILER_OPTIONS.keys()):
if Utils.unversioned_sys_platform() == "darwin" and conf.env['CXX_NAME'] == 'clang':
version = tuple(int(i) for i in conf.env['CC_VERSION'])
if version < (6, 1, 0):
# Issue #2804
return
conf.env.WITH_PCH = True
flags = PCH_COMPILER_OPTIONS[conf.env['COMPILER_CXX']]
conf.env.CXXPCH_F = flags[0]
+30
View File
@@ -0,0 +1,30 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
#
# Copyright (c) 2014, Regents of the University of California
#
# GPL 3.0 license, see the COPYING.md file for more information
from waflib import Configure
IS_DEFAULT_CONSTRUCTIBLE_CHECK = '''
#include <type_traits>
static_assert(std::is_default_constructible<int>::value, "");
'''
IS_MOVE_CONSTRUCTIBLE_CHECK = '''
#include <type_traits>
static_assert(std::is_move_constructible<int>::value, "");
'''
def configure(conf):
if conf.check_cxx(msg='Checking for std::is_default_constructible',
fragment=IS_DEFAULT_CONSTRUCTIBLE_CHECK,
features='cxx', mandatory=False):
conf.define('HAVE_IS_DEFAULT_CONSTRUCTIBLE', 1)
conf.env['HAVE_IS_DEFAULT_CONSTRUCTIBLE'] = True
if conf.check_cxx(msg='Checking for std::is_move_constructible',
fragment=IS_MOVE_CONSTRUCTIBLE_CHECK,
features='cxx', mandatory=False):
conf.define('HAVE_IS_MOVE_CONSTRUCTIBLE', 1)
conf.env['HAVE_IS_MOVE_CONSTRUCTIBLE'] = True
+4 -4
View File
@@ -36,8 +36,8 @@ def checkWebsocket(self, **kw):
# Looking for the following:
# static int const major_version = 0;
# static int const minor_version = 3;
# static int const patch_version = 0;
# static int const minor_version = 5;
# static int const patch_version = 1;
version = [None, None, None]
@@ -59,10 +59,10 @@ def checkWebsocket(self, **kw):
self.end_msg('.'.join(self.env['WEBSOCKET_VERSION']))
self.env['INCLUDES_WEBSOCKET'] = websocketDir.parent.abspath()
self.env['HAVE_WEBSOCKET'] = True
self.define('HAVE_WEBSOCKET', 1)
self.define('_WEBSOCKETPP_CPP11_STL_', 1)
except Errors.WafError as error:
if isMandatory:
@@ -71,7 +71,7 @@ def checkWebsocket(self, **kw):
Logs.warn(' git submodule init && git submodule update')
Logs.warn('Otherwise, manually download and extract websocketpp library:')
Logs.warn(' mkdir websocketpp')
Logs.warn(' curl -L https://github.com/zaphoyd/websocketpp/tarball/65cc3765a892ee5928160ba478178e747233aa6c > websocket.tar.gz')
Logs.warn(' curl -L https://github.com/zaphoyd/websocketpp/archive/0.5.1.tar.gz > websocket.tar.gz')
Logs.warn(' tar zxf websocket.tar.gz -C websocketpp/ --strip 1')
Logs.warn('Alternatively, WebSocket support can be disabled with --without-websocket')
self.fatal("The configuration failed")
+18 -1
View File
@@ -18,7 +18,7 @@ volunteers.
* Lixia Zhang <http://www.cs.ucla.edu/~lixia/>
## All project authors and contributors and their affiliations:
## Main project authors and their affiliations:
* University of California, Los Angeles
@@ -62,4 +62,21 @@ volunteers.
* Syed Obaid Amin <http://obaidamin.weebly.com/>
* Vince Lehman <vslehman@memphis.edu>
* Minsheng Zhang <mzhang4@memphis.edu>
* Lan Wang <http://www.cs.memphis.edu/~lanwang/>
## Project contributors
The following is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS,
people who have reported bugs, submitted patches, and implemented new features
in the library:
* Tai-Lin Chu <https://www.linkedin.com/pub/tai-lin-chu/55/5b2/669>
* Spyridon Mastorakis <http://cs.ucla.edu/~mastorakis/>
* Eric Newberry <http://ericnewberry.com>
* Yukai Tu <tuyukai1994@gmail.com>
* João Pereira <http://website.jpereira.co.uk>
* Mathias Gibbens <gibmat@cs.arizona.edu>
* Yanbiao Li <https://www.linkedin.com/pub/yanbiao-li/24/7a1/4ba>
* Weiwei Liu <https://www.linkedin.com/in/weiweiliu10>
* Spencer Lee <https://www.linkedin.com/in/spenlee>
+30
View File
@@ -1,3 +1,33 @@
NFD is licensed under conditions of GNU General Public License version 3 or later.
NFD relies on third-party software and libraries, licensed under the following licenses:
- ndn-cxx library is licensed under conditions of
[GNU Lesser General Public License version 3](https://github.com/named-data/ndn-cxx/blob/master/COPYING.md).
- Boost libraries licensed under conditions of
[Boost Software License 1.0](http://www.boost.org/users/license.html)
- CryptoPP library is licensed under conditions of
[Boost Software License 1.0](http://www.boost.org/users/license.html)
- SQLite is in [public domain](http://www.sqlite.org/copyright.html)
- WebSocket++ library licensed under conditions of
[BSD license](https://github.com/zaphoyd/websocketpp/blob/ac5d7ea5af9734de965688b54a7860259887b537/COPYING)
- Libpcap library licensed under conditions of
[a 3-clause BSD license](http://www.tcpdump.org/license.html).
- waf build system is licensed under conditions of
[BSD license](https://github.com/named-data/ndn-cxx/blob/master/waf)
The GPL license is provided below in this file. For more information about these licenses, see
http://www.gnu.org/licenses/
----------------------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
==========================
Version 3, 29 June 2007
+1 -1
View File
@@ -1,5 +1,5 @@
NFD Installation Instructions
=============================
See [`docs/install.rst`](https://github.com/named-data/NFD/blob/master/docs/INSTALL.rst)
See [`docs/INSTALL.rst`](https://github.com/named-data/NFD/blob/master/docs/INSTALL.rst)
for detailed NFD installation instructions.
+8 -12
View File
@@ -4,17 +4,15 @@ Notes for NFD developers
Requirements
------------
Contributions to NFD must be licensed under GPL 3.0 or compatible license. If you are
choosing GPL 3.0, please use the following license boilerplate in all `.hpp` and `.cpp`
files:
Include the following license boilerplate into all `.hpp` and `.cpp` files:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) [Year(s)], [Copyright Holder(s)].
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -29,13 +27,11 @@ Include the following license boilerplate into all `.hpp` and `.cpp` files:
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
////// [optional part] //////
*
* \author Author's Name <email@domain>
* \author Other Author's Name <another.email@domain>
////// [end of optional part] //////
*/
If you are affiliated to an NSF-supported NDN project institution, please use the [NDN Team License
Boilerplate](http://redmine.named-data.net/projects/nfd/wiki/NDN_Team_License_Boilerplate_(NFD)).
Recommendations
---------------
+1
View File
@@ -0,0 +1 @@
docs/release-notes-latest.rst
+3
View File
@@ -0,0 +1,3 @@
# Enable ndn-autoconfig to run in parallel with NFD. Disabled by default
# enabled=true
enabled=false
+78 -24
View File
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -40,15 +40,58 @@
#define PROTECTED_WITH_TESTS_ELSE_PRIVATE private
#endif
/** \def DECL_OVERRIDE
* \brief expands to 'override' if compiler supports 'override' specifier,
* otherwise expands to nothing
*/
#ifdef HAVE_CXX_OVERRIDE
#define DECL_OVERRIDE override
#else
#define DECL_OVERRIDE
#endif
/** \def DECL_FINAL
* \brief expands to 'final' if compiler supports 'final' specifier on method,
* otherwise expands to nothing
*/
#ifdef HAVE_CXX_FINAL
#define DECL_FINAL final
#else
#define DECL_FINAL
#endif
/** \def DECL_CLASS_FINAL
* \brief expands to 'final' if compiler supports 'final' specifier on class,
* otherwise expands to nothing
*/
#ifdef HAVE_CXX_CLASS_FINAL
#define DECL_CLASS_FINAL final
#else
#define DECL_CLASS_FINAL
#endif
#include <cstddef>
#include <cstdint>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <queue>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <ndn-cxx/common.hpp>
#include <ndn-cxx/interest.hpp>
#include <ndn-cxx/data.hpp>
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/encoding/block.hpp>
#include <ndn-cxx/lp/nack.hpp>
#include <ndn-cxx/util/backports.hpp>
#include <ndn-cxx/util/face-uri.hpp>
#include <ndn-cxx/util/signal.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/asio.hpp>
@@ -56,39 +99,50 @@
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/throw_exception.hpp>
namespace nfd {
using std::size_t;
using boost::noncopyable;
using boost::scoped_ptr;
using ndn::shared_ptr;
using ndn::weak_ptr;
using ndn::enable_shared_from_this;
using ndn::make_shared;
using ndn::static_pointer_cast;
using ndn::dynamic_pointer_cast;
using ndn::const_pointer_cast;
using ndn::function;
using ndn::bind;
using ndn::ref;
using ndn::cref;
using std::shared_ptr;
using std::unique_ptr;
using std::weak_ptr;
using std::make_shared;
using ndn::make_unique;
using std::enable_shared_from_this;
using std::static_pointer_cast;
using std::dynamic_pointer_cast;
using std::const_pointer_cast;
using std::function;
using std::bind;
using std::ref;
using std::cref;
using ndn::to_string;
using ndn::Interest;
using ndn::Data;
using ndn::Name;
using ndn::PartialName;
using ndn::Exclude;
using ndn::Link;
using ndn::Block;
using ndn::util::FaceUri;
namespace tlv {
using namespace ndn::Tlv;
}
// Don't write "namespace tlv = ndn::tlv", because NFD can add other members into this namespace.
using namespace ndn::tlv;
} // namespace tlv
namespace lp = ndn::lp;
namespace name = ndn::name;
namespace time = ndn::time;
namespace signal = ndn::util::signal;
} // namespace nfd
+27 -38
View File
@@ -7,23 +7,17 @@ when they die.
Initial setup
-------------
Edit `net.named-data.nfd` and `net.named-data.nrd` correcting paths for `nfd` and `nfd`
binaries, configuration file, and log files.
Edit `net.named-data.nfd` correcting paths for `nfd` binary, configuration and log files.
# Copy launchd.plist for nfd (forwarding daemon)
# Copy launchd.plist for NFD
sudo cp net.named-data.nfd.plist /Library/LaunchDaemons/
sudo chown root /Library/LaunchDaemons/net.named-data.nfd.plist
# Copy launchd.plist for nrd (RIB management daemon)
sudo cp net.named-data.nrd.plist /Library/LaunchDaemons/
sudo chown root /Library/LaunchDaemons/net.named-data.nrd.plist
### Assumptions in the default scripts
* `nfd` and `nrd` are installed into `/usr/local/bin`
* `nfd` is installed into `/usr/local/bin`
* Configuration file is `/usr/local/etc/ndn/nfd.conf`
* `nfd` will be run as root
* `nrd` will be run as user `ndn` and group `ndn`
* Log files will be written to `/usr/local/var/log/ndn` folder, which is owned by user `ndn`
### Creating users
@@ -62,29 +56,24 @@ Folder `/usr/local/var/log/ndn` should be created and assigned proper user and g
sudo mkdir -p /usr/local/var/log/ndn
sudo chown -R ndn:ndn /usr/local/var/log/ndn
`HOME` directories for `nfd` and `nrd` should be created and configured with correct
library's config file and contain proper NDN security credentials for signing Data
packets. This is necessary since default private key storage on OSX (`osx-keychain`) does
not support non-interactive access, and file-based private key storage needs to be used:
`HOME` directory for `nfd` should be created and configured with correct library's config file
and contain proper NDN security credentials for signing Data packets. This is necessary since
default private key storage on OSX (`osx-keychain`) does not support non-interactive access,
and file-based private key storage needs to be used:
# Generate self-signed NDN certificate for nfd (owned by root)
sudo mkdir -p /usr/local/var/lib/ndn/nfd/.ndn
sudo sh -c 'echo tpm=file > /usr/local/var/lib/ndn/nfd/.ndn/client.conf'
sudo HOME=/usr/local/var/lib/ndn/nfd ndnsec-keygen /localhost/daemons/nfd | \
sudo HOME=/usr/local/var/lib/ndn/nfd ndnsec-install-cert -
# Generate self-signed NDN certificate for nrd (owned by ndn)
sudo mkdir -p /usr/local/var/lib/ndn/nrd/.ndn
sudo chown -R ndn:ndn /usr/local/var/lib/ndn/nrd
sudo -u ndn -g ndn sh -c 'echo tpm=file > /usr/local/var/lib/ndn/nrd/.ndn/client.conf'
sudo -u ndn -g ndn HOME=/usr/local/var/lib/ndn/nrd ndnsec-keygen /localhost/daemons/nrd | \
sudo -u ndn -g ndn HOME=/usr/local/var/lib/ndn/nrd ndnsec-install-cert -
# Create HOME and generate self-signed NDN certificate for nfd
sudo -s -- ' \
mkdir -p /usr/local/var/lib/ndn/nfd/.ndn; \
export HOME=/usr/local/var/lib/ndn/nfd; \
echo tpm=tpm-file > /usr/local/var/lib/ndn/nfd/.ndn/client.conf; \
ndnsec-keygen /localhost/daemons/nfd | ndnsec-install-cert -; \
'
### Configuring NFD's security
NFD sample configuration allows anybody to create faces, add nexthops to FIB,
and set strategy choice for namespaces. While such settings could be a good start, it is
generally not a good idea to run NFD in this mode.
NFD sample configuration allows anybody to create faces, add nexthops to FIB, and set strategy
choice for namespaces. While such settings could be a good start, it is generally not a good
idea to run NFD in this mode.
While thorough discussion about security configuration of NFD is outside the scope of this
document, at least the following change should be done to nfd.conf in authorize section:
@@ -93,7 +82,7 @@ document, at least the following change should be done to nfd.conf in authorize
{
authorize
{
certfile certs/localhost_daemons_nrd.ndncert
certfile certs/localhost_daemons_nfd.ndncert
privileges
{
faces
@@ -114,25 +103,25 @@ document, at least the following change should be done to nfd.conf in authorize
}
While this configuration still allows management of faces and updating strategy choice by
anybody, only NFD's RIB Manager Daemon (`nrd`) is allowed to manage FIB.
anybody, only NFD's RIB Manager (i.e., NFD itself) is allowed to manage FIB.
As the final step to make this configuration work, nrd's self-signed certificate needs to
be exported into `localhost_daemons_nrd.ndncert` file:
As the final step to make this configuration work, NFD's self-signed certificate needs to
be exported into `localhost_daemons_nfd.ndncert` file:
sudo mkdir /usr/local/etc/ndn/certs
sudo sh -c 'sudo -u ndn -g ndn HOME=/usr/local/var/lib/ndn/nrd \
ndnsec-dump-certificate -i /localhost/daemons/nrd \
> /usr/local/etc/ndn/certs/localhost_daemons_nrd.ndncert'
sudo -s -- '\
mkdir -p /usr/local/etc/ndn/certs || true; \
export HOME=/usr/local/var/lib/ndn/nfd; \
ndnsec-dump-certificate -i /localhost/daemons/nfd > \
/usr/local/etc/ndn/certs/localhost_daemons_nfd.ndncert; \
'
Enable auto-start
-----------------
sudo launchctl load -w /Library/LaunchDaemons/net.named-data.nfd.plist
sudo launchctl load -w /Library/LaunchDaemons/net.named-data.nrd.plist
Disable auto-start
------------------
sudo launchctl unload -w /Library/LaunchDaemons/net.named-data.nfd.plist
sudo launchctl unload -w /Library/LaunchDaemons/net.named-data.nrd.plist
@@ -1,25 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd" >
<plist version='1.0'>
<dict>
<key>Label</key><string>net.named-data.nrd</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/nrd</string>
<string>--config</string>
<string>/usr/local/etc/ndn/nfd.conf</string>
</array>
<key>UserName</key><string>ndn</string>
<key>GroupName</key><string>ndn</string>
<key>EnvironmentVariables</key>
<dict>
<key>HOME</key><string>/usr/local/var/lib/ndn/nrd</string>
</dict>
<key>Debug</key><true/>
<key>Disabled</key><true/>
<key>KeepAlive</key><true/>
<key>StandardErrorPath</key><string>/usr/local/var/log/ndn/nrd.log</string>
<key>ProcessType</key><string>Background</string>
</dict>
</plist>
+130
View File
@@ -0,0 +1,130 @@
Starting NFD on Linux with systemd
==================================
Newer versions of Ubuntu (starting with 15.04) and some other Linux distributions, including Debian
use systemd to start system daemons, monitor their health, and restart them when they die.
Initial setup
-------------
* Edit `nfd.service`, correcting the paths to the `nfd` executable, configuration, and
``HOME`` directories.
* Copy the systemd config file for NFD to the proper directory
sudo cp nfd.service /etc/systemd/system
* Reload the systemd manager configuration
sudo systemctl daemon-reload
### Assumptions in the default scripts
* `nfd` is installed into `/usr/local/bin`
* Configuraton file is `/usr/local/etc/ndn/nfd.conf`
* `nfd` will be run as root
* Log files will be written to `/usr/local/var/log/ndn` folder, which is owned by user `ndn`
### Creating users
If the `ndn` user and group do not exist, they need to be manually created.
# Create group `ndn`
sudo addgroup --system ndn
# Create user `ndn`
sudo adduser --system \
--disabled-login \
--ingroup ndn \
--home /nonexistent \
--gecos "NDN User" \
--shell /bin/false \
ndn
### Creating folders
Folder `/usr/local/var/log/ndn` should be created and assigned proper user and group:
sudo mkdir -p /usr/local/var/log/ndn
sudo chown -R ndn:ndn /usr/local/var/log/ndn
`HOME` directory for `nfd` should be created prior to starting. This is necessary to manage
unique security credentials for the daemon.
# Create HOME and generate self-signed NDN certificate for nfd
sudo sh -c ' \
mkdir -p /usr/local/var/lib/ndn/nfd/.ndn; \
export HOME=/usr/local/var/lib/ndn/nfd; \
ndnsec-keygen /localhost/daemons/nfd | ndnsec-install-cert -; \
'
### Configuring NFD's security
NFD sample configuration allows anybody to create faces, add nexthops to FIB, and set
strategy choice for namespaces. While such settings could be a good start, it is
generally not a good idea to run NFD in this mode.
While thorough discussion about the security configuration of NFD is outside the scope of
this document, at least the following change should be done in ``nfd.conf`` in the
authorize section:
authorizations
{
authorize
{
certfile certs/localhost_daemons_nfd.ndncert
privileges
{
faces
fib
strategy-choice
}
}
authorize
{
certfile any
privileges
{
faces
strategy-choice
}
}
}
While this configuration still allows the management of faces and updating strategy choice by
anyone, only NFD's RIB Manager (i.e., NFD itself) is allowed to manage FIB.
As the final step to make this configuration work, nfd's self-signed certificate needs to
be exported into the `localhost_daemons_nfd.ndncert` file:
sudo sh -c '\
mkdir -p /usr/local/etc/ndn/certs || true; \
export HOME=/usr/local/var/lib/ndn/nfd; \
ndnsec-dump-certificate -i /localhost/daemons/nfd > \
/usr/local/etc/ndn/certs/localhost_daemons_nfd.ndncert; \
'
Enable auto-start
-----------------
After copying the provided upstart script, auto-start of the `nfd` daemon can be enabled with:
sudo systemctl enable nfd
To manually start it, use the following command:
sudo systemctl start nfd
Disable auto-start
------------------
To stop the `nfd` daemon, use the following command:
sudo systemctl stop nfd
To permanently stop the `nfd` daemon and disable it from being automatically started on reboot,
disable the service:
sudo systemctl disable nfd
+42
View File
@@ -0,0 +1,42 @@
# Copyright (c) 2015, Regents of the University of California,
# Arizona Board of Regents,
# Colorado State University,
# University Pierre & Marie Curie, Sorbonne University,
# Washington University in St. Louis,
# Beijing Institute of Technology,
# The University of Memphis.
#
# This file is part of NFD (Named Data Networking Forwarding Daemon).
# See AUTHORS.md for complete list of NFD authors and contributors.
#
# NFD is free software: you can redistribute it and/or modify it under the terms
# of the GNU General Public License as published by the Free Software Foundation,
# either version 3 of the License, or (at your option) any later version.
#
# NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
#
# Author: Eric Newberry <enewberry@email.arizona.edu>
[Unit]
Description=NDN Forwarding Daemon
Documentation=man:nfd man:nfdc man:nfd-status
Wants=network-online.target
After=network-online.target
[Service]
Environment=HOME=/usr/local/var/lib/ndn/nfd
ExecStart=/usr/local/bin/nfd --config /usr/local/etc/ndn/nfd.conf
ExecStartPost=/bin/sh -ec 'sleep 2; if [ -f /usr/local/etc/ndn/nfd-init.sh ]; then . /usr/local/etc/ndn/nfd-init.sh; fi'
Restart=on-failure
ProtectSystem=full
PrivateTmp=yes
PrivateDevices=yes
ProtectHome=yes
[Install]
WantedBy=multi-user.target
+26 -45
View File
@@ -8,26 +8,18 @@ when they die.
Initial setup
-------------
Edit `nfd.conf` and `nrd.conf` correcting paths for `nfd` and `nfd` binaries,
configuration file, and log files.
* Edit `nfd.conf` correcting paths for `nfd` binary, configuration and log files.
# Copy upstart config file for nfd (forwarding daemon)
sudo cp nfd.conf /etc/init/
* Copy upstart config file for NFD
# Copy upstart config file for nrd (RIB management daemon)
sudo cp nrd.conf /etc/init/
# Copy upstart config file for nfd-watcher (will restart NFD when network change detected)
sudo cp nfd-watcher.conf /etc/init/
sudo cp nfd.conf /etc/init/
### Assumptions in the default scripts
* `nfd` and `nrd` are installed into `/usr/local/bin`
* `nfd` is installed into `/usr/local/bin`
* Configuration file is `/usr/local/etc/ndn/nfd.conf`
* `nfd` will be run as root
* `nrd` will be run as user `ndn` and group `ndn`
* Log files will be written to `/usr/local/var/log/ndn` folder, which is owned by user `ndn`
* Whenever network connectivity changes, both `nfd` and `nrd` are restarted
### Creating users
@@ -53,19 +45,15 @@ Folder `/usr/local/var/log/ndn` should be created and assigned proper user and g
sudo mkdir -p /usr/local/var/log/ndn
sudo chown -R ndn:ndn /usr/local/var/log/ndn
`HOME` directories for `nfd` and `nrd` should be created prior to starting. This is
necessary to manage unique security credentials for the deamons.
`HOME` directory for `nfd` should be created prior to starting. This is necessary to manage
unique security credentials for the deamon.
# Create HOME and generate self-signed NDN certificate for nfd
sudo mkdir -p /usr/local/var/lib/ndn/nfd/.ndn
sudo HOME=/usr/local/var/lib/ndn/nfd ndnsec-keygen /localhost/daemons/nfd | \
sudo HOME=/usr/local/var/lib/ndn/nfd ndnsec-install-cert -
# Create HOME and generate self-signed NDN certificate for nrd
sudo mkdir -p /usr/local/var/lib/ndn/nrd/.ndn
sudo chown -R ndn:ndn /usr/local/var/lib/ndn/nrd
sudo -u ndn -g ndn HOME=/usr/local/var/lib/ndn/nrd ndnsec-keygen /localhost/daemons/nrd | \
sudo -u ndn -g ndn HOME=/usr/local/var/lib/ndn/nrd ndnsec-install-cert -
sudo -s -- ' \
mkdir -p /usr/local/var/lib/ndn/nfd/.ndn; \
export HOME=/usr/local/var/lib/ndn/nfd; \
ndnsec-keygen /localhost/daemons/nfd | ndnsec-install-cert -; \
'
### Configuring NFD's security
@@ -81,7 +69,7 @@ section:
{
authorize
{
certfile certs/localhost_daemons_nrd.ndncert
certfile certs/localhost_daemons_nfd.ndncert
privileges
{
faces
@@ -102,43 +90,36 @@ section:
}
While this configuration still allows management of faces and updating strategy choice by
anybody, only NFD's RIB Manager Daemon (`nrd`) is allowed to manage FIB.
anybody, only NFD's RIB Manager (i.e., NFD itself) is allowed to manage FIB.
As the final step to make this configuration work, nrd's self-signed certificate needs to
be exported into `localhost_daemons_nrd.ndncert` file:
As the final step to make this configuration work, nfd's self-signed certificate needs to
be exported into `localhost_daemons_nfd.ndncert` file:
sudo mkdir /usr/local/etc/ndn/certs
sudo sh -c 'sudo -u ndn -g ndn HOME=/usr/local/var/lib/ndn/nrd \
ndnsec-dump-certificate -i /localhost/daemons/nrd \
> /usr/local/etc/ndn/certs/localhost_daemons_nrd.ndncert'
sudo -s -- '\
mkdir -p /usr/local/etc/ndn/certs || true; \
export HOME=/usr/local/var/lib/ndn/nfd; \
ndnsec-dump-certificate -i /localhost/daemons/nfd > \
/usr/local/etc/ndn/certs/localhost_daemons_nfd.ndncert; \
'
Enable auto-start
-----------------
After copying the provided upstart scripts, `nfd` and `nrd` daemons will automatically run
after the reboot. To manually start them, use the following commands:
After copying the provided upstart script, `nfd` daemon will automatically run after the reboot.
To manually start them, use the following commands:
sudo start nfd
# nrd will be automatically started by upstart
Note that an additional upstart job, ``nfd-watcher``, will automatically monitor for
network connectivity changes, such as when network interface gets connected, disconnected,
or IP addresses of the network interface get updated. When ``nfd-watcher`` detects the
event, it will restart `nfd` and `nrd`.
Disable auto-start
------------------
To stop `nrd` and `nfd` daemon, use the following commands:
To stop `nfd` daemon, use the following commands:
sudo stop nfd
# nrd will be automatically stopped by upstart
Note that as long as upstart files are present in `/etc/init/`, the daemons will
automatically start after the reboot. To permanently stop `nfd` and `nrd` daemons, delete
Note that as long as upstart files are present in `/etc/init/`, the daemon will
automatically start after the reboot. To permanently stop `nfd` daemon, delete
the upstart files:
sudo rm /etc/init/nfd.conf
sudo rm /etc/init/nrd.conf
sudo rm /etc/init/nfd-watcher.conf
-13
View File
@@ -1,13 +0,0 @@
# nfd-watcher.conf
#
# Restarting NDN Forwarding Daemon on network connectivity changes
start on (net-device-up or
net-device-removed or
net-device-changed)
task
script
status nfd | grep -q start/ || stop
restart nfd
end script
+9
View File
@@ -14,4 +14,13 @@ env HOME=/usr/local/var/lib/ndn/nfd
export HOME
exec /usr/local/bin/nfd --config /usr/local/etc/ndn/nfd.conf 2>> /usr/local/var/log/ndn/nfd.log
post-start script
if [ -f /usr/local/etc/ndn/nfd-init.sh ]; then
sleep 2 # post-start is executed just after nfd process starts, but there is no guarantee
# that all initialization has been finished
. /usr/local/etc/ndn/nfd-init.sh
fi
end script
post-stop exec sleep 2
-22
View File
@@ -1,22 +0,0 @@
# nrd.conf
#
# NDN RIB Manager Daemon
description "NDN RIB Manager Daemon"
start on started nfd
stop on stopping nfd
respawn
respawn limit unlimited
setuid ndn
setgid ndn
pre-start exec sleep 2
script
export HOME=/usr/local/var/lib/ndn/nrd
/usr/local/bin/nrd --config /usr/local/etc/ndn/nfd.conf 2>> /usr/local/var/log/ndn/nrd.log
end script
post-stop exec sleep 2
+58
View File
@@ -0,0 +1,58 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_CORE_ALGORITHM_HPP
#define NFD_CORE_ALGORITHM_HPP
#include "common.hpp"
#include <boost/concept/requires.hpp>
namespace nfd {
/** \brief finds the last element satisfying a predicate
* \tparam It BidirectionalIterator
* \tparam Pred UnaryPredicate
*
* \return Iterator to the last element satisfying the condition,
* or \p last if no such element is found.
*
* Complexity: at most \p last-first invocations of \p p
*/
template<typename It, typename Pred>
BOOST_CONCEPT_REQUIRES(
((boost::BidirectionalIterator<It>))
((boost::UnaryPredicate<Pred, typename std::iterator_traits<It>::value_type>)),
(It)
)
find_last_if(It first, It last, Pred p)
{
std::reverse_iterator<It> firstR(first), lastR(last);
auto found = std::find_if(lastR, firstR, p);
return found == firstR ? last : std::prev(found.base());
}
} // namespace nfd
#endif // NFD_CORE_ALGORITHM_HPP
+51 -38
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,7 +21,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "config-file.hpp"
#include "logger.hpp"
@@ -30,7 +31,10 @@
namespace nfd {
NFD_LOG_INIT("ConfigFile");
ConfigFile::ConfigFile(UnknownConfigSectionHandler unknownSectionCallback)
: m_unknownSectionCallback(unknownSectionCallback)
{
}
void
ConfigFile::throwErrorOnUnknownSection(const std::string& filename,
@@ -42,7 +46,7 @@ ConfigFile::throwErrorOnUnknownSection(const std::string& filename,
msg += filename;
msg += ": no module subscribed for section \"" + sectionName + "\"";
throw ConfigFile::Error(msg);
BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
}
void
@@ -54,9 +58,21 @@ ConfigFile::ignoreUnknownSection(const std::string& filename,
// do nothing
}
ConfigFile::ConfigFile(UnknownConfigSectionHandler unknownSectionCallback)
: m_unknownSectionCallback(unknownSectionCallback)
bool
ConfigFile::parseYesNo(const ConfigSection::value_type& option,
const std::string& sectionName)
{
auto value = option.second.get_value<std::string>();
if (value == "yes") {
return true;
}
else if (value == "no") {
return false;
}
BOOST_THROW_EXCEPTION(Error("Invalid value \"" + value + "\" for option \"" +
option.first + "\" in \"" + sectionName + "\" section"));
}
void
@@ -75,7 +91,7 @@ ConfigFile::parse(const std::string& filename, bool isDryRun)
{
std::string msg = "Failed to read configuration file: ";
msg += filename;
throw Error(msg);
BOOST_THROW_EXCEPTION(Error(msg));
}
parse(inputFile, isDryRun, filename);
inputFile.close();
@@ -88,7 +104,6 @@ ConfigFile::parse(const std::string& input, bool isDryRun, const std::string& fi
parse(inputStream, isDryRun, filename);
}
void
ConfigFile::parse(std::istream& input, bool isDryRun, const std::string& filename)
{
@@ -102,42 +117,40 @@ ConfigFile::parse(std::istream& input, bool isDryRun, const std::string& filenam
msg << "Failed to parse configuration file";
msg << " " << filename;
msg << " " << error.message() << " line " << error.line();
throw Error(msg.str());
BOOST_THROW_EXCEPTION(Error(msg.str()));
}
process(isDryRun, filename);
}
void
ConfigFile::process(bool isDryRun, const std::string& filename)
ConfigFile::parse(const ConfigSection& config, bool isDryRun, const std::string& filename)
{
m_global = config;
process(isDryRun, filename);
}
void
ConfigFile::process(bool isDryRun, const std::string& filename) const
{
BOOST_ASSERT(!filename.empty());
// NFD_LOG_DEBUG("processing..." << ((isDryRun)?("dry run"):("")));
if (m_global.begin() == m_global.end())
{
std::string msg = "Error processing configuration file: ";
msg += filename;
msg += " no data";
throw Error(msg);
if (m_global.begin() == m_global.end()) {
std::string msg = "Error processing configuration file: ";
msg += filename;
msg += " no data";
BOOST_THROW_EXCEPTION(Error(msg));
}
for (const auto& i : m_global) {
try {
ConfigSectionHandler subscriber = m_subscriptions.at(i.first);
subscriber(i.second, isDryRun, filename);
}
for (ConfigSection::const_iterator i = m_global.begin(); i != m_global.end(); ++i)
{
const std::string& sectionName = i->first;
const ConfigSection& section = i->second;
SubscriptionTable::iterator subscriberIt = m_subscriptions.find(sectionName);
if (subscriberIt != m_subscriptions.end())
{
ConfigSectionHandler subscriber = subscriberIt->second;
subscriber(section, isDryRun, filename);
}
else
{
m_unknownSectionCallback(filename, sectionName, section, isDryRun);
}
catch (const std::out_of_range&) {
m_unknownSectionCallback(filename, i.first, i.second, isDryRun);
}
}
}
}
+60 -21
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,7 +21,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NFD_CORE_CONFIG_FILE_HPP
#define NFD_CORE_CONFIG_FILE_HPP
@@ -47,7 +48,6 @@ typedef function<void(const std::string& /*filename*/,
class ConfigFile : noncopyable
{
public:
class Error : public std::runtime_error
{
public:
@@ -55,10 +55,10 @@ public:
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
explicit
ConfigFile(UnknownConfigSectionHandler unknownSectionCallback = throwErrorOnUnknownSection);
static void
@@ -73,12 +73,32 @@ public:
const ConfigSection& section,
bool isDryRun);
/**
* \brief parse a config option that can be either "yes" or "no"
*
* \return true if "yes", false if "no"
* \throw Error the value is neither "yes" nor "no"
*/
static bool
parseYesNo(const ConfigSection::value_type& option,
const std::string& sectionName);
/**
* \brief parse a numeric (integral or floating point) config option
*
* \return the numeric value of the parsed option
* \throw Error the value cannot be converted to the specified type
*/
template <typename T>
static typename std::enable_if<std::is_arithmetic<T>::value, T>::type
parseNumber(const ConfigSection::value_type& option,
const std::string& sectionName);
/// \brief setup notification of configuration file sections
void
addSectionHandler(const std::string& sectionName,
ConfigSectionHandler subscriber);
/**
* \param filename file to parse
* \param isDryRun true if performing a dry run of configuration, false otherwise
@@ -91,7 +111,7 @@ public:
/**
* \param input configuration (as a string) to parse
* \param isDryRun true if performing a dry run of configuration, false otherwise
* \param filename optional convenience argument to provide more detailed error messages
* \param filename logical filename of the config file, can appear in error messages
* \throws ConfigFile::Error if file not found
* \throws ConfigFile::Error if parse error
*/
@@ -101,28 +121,47 @@ public:
/**
* \param input stream to parse
* \param isDryRun true if performing a dry run of configuration, false otherwise
* \param filename optional convenience argument to provide more detailed error messages
* \param filename logical filename of the config file, can appear in error messages
* \throws ConfigFile::Error if parse error
*/
void
parse(std::istream& input, bool isDryRun, const std::string& filename);
private:
/**
* \param config ConfigSection that needs to be processed
* \param isDryRun true if performing a dry run of configuration, false otherwise
* \param filename logical filename of the config file, can appear in error messages
* \throws ConfigFile::Error if parse error
*/
void
process(bool isDryRun, const std::string& filename);
parse(const ConfigSection& config, bool isDryRun, const std::string& filename);
private:
void
process(bool isDryRun, const std::string& filename) const;
private:
UnknownConfigSectionHandler m_unknownSectionCallback;
typedef std::map<std::string, ConfigSectionHandler> SubscriptionTable;
SubscriptionTable m_subscriptions;
std::map<std::string, ConfigSectionHandler> m_subscriptions;
ConfigSection m_global;
};
template <typename T>
inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type
ConfigFile::parseNumber(const ConfigSection::value_type& option,
const std::string& sectionName)
{
auto value = option.second.get_value<std::string>();
try {
return boost::lexical_cast<T>(value);
}
catch (const boost::bad_lexical_cast&) {
BOOST_THROW_EXCEPTION(Error("Invalid value \"" + value + "\" for option \"" +
option.first + "\" in \"" + sectionName + "\" section"));
}
}
} // namespace nfd
#endif // NFD_CORE_CONFIG_FILE_HPP
+141
View File
@@ -0,0 +1,141 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_CORE_COUNTER_HPP
#define NFD_CORE_COUNTER_HPP
#include "common.hpp"
namespace nfd {
/** \brief represents a counter that encloses an integer value
*
* SimpleCounter is noncopyable, because increment should be called on the counter,
* not a copy of it; it's implicitly convertible to an integral type to be observed
*/
class SimpleCounter
{
public:
typedef uint64_t rep;
constexpr
SimpleCounter()
: m_value(0)
{
}
SimpleCounter(const SimpleCounter&) = delete;
SimpleCounter&
operator=(const SimpleCounter&) = delete;
/** \brief observe the counter
*/
operator rep() const
{
return m_value;
}
/** \brief replace the counter value
*/
void
set(rep value)
{
m_value = value;
}
protected:
rep m_value;
};
/** \brief represents a counter of number of packets
*
* \warning The counter value may wrap after exceeding the range of underlying integer type.
*/
class PacketCounter : public SimpleCounter
{
public:
/** \brief increment the counter by one
*/
PacketCounter&
operator++()
{
++m_value;
return *this;
}
// postfix ++ operator is not provided because it's not needed
};
/** \brief represents a counter of number of bytes
*
* \warning The counter value may wrap after exceeding the range of underlying integer type.
*/
class ByteCounter : public SimpleCounter
{
public:
/** \brief increase the counter
*/
ByteCounter&
operator+=(rep n)
{
m_value += n;
return *this;
}
};
/** \brief provides a counter that observes the size of a table
* \tparam T a type that provides a size() const member function
*/
template<typename T>
class SizeCounter
{
public:
typedef size_t rep;
constexpr
SizeCounter(const T& table)
: m_table(table)
{
}
SizeCounter(const SizeCounter&) = delete;
SizeCounter&
operator=(const SizeCounter&) = delete;
/** \brief observe the counter
*/
operator rep() const
{
return m_table.size();
}
private:
const T& m_table;
};
} // namespace nfd
#endif // NFD_CORE_COUNTER_HPP
-82
View File
@@ -1,82 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "ethernet.hpp"
#include <stdio.h>
namespace nfd {
namespace ethernet {
std::string
Address::toString(char sep) const
{
char s[18]; // 12 digits + 5 separators + null terminator
::snprintf(s, sizeof(s), "%02x%c%02x%c%02x%c%02x%c%02x%c%02x",
elems[0], sep, elems[1], sep, elems[2], sep,
elems[3], sep, elems[4], sep, elems[5]);
return std::string(s);
}
Address
Address::fromString(const std::string& str)
{
unsigned short temp[ADDR_LEN];
char sep[5][2]; // 5 * (1 separator char + 1 null terminator)
int n = 0; // num of chars read from the input string
// ISO C++98 does not support the 'hh' type modifier
/// \todo use SCNx8 (cinttypes) when we enable C++11
int ret = ::sscanf(str.c_str(), "%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%n",
&temp[0], &sep[0][0], &temp[1], &sep[1][0], &temp[2], &sep[2][0],
&temp[3], &sep[3][0], &temp[4], &sep[4][0], &temp[5], &n);
if (ret < 11 || static_cast<size_t>(n) != str.length())
return Address();
Address a;
for (size_t i = 0; i < ADDR_LEN; ++i)
{
// check that all separators are actually the same char (: or -)
if (i < 5 && sep[i][0] != sep[0][0])
return Address();
// check that each value fits into a uint8_t
if (temp[i] > 0xFF)
return Address();
a[i] = static_cast<uint8_t>(temp[i]);
}
return a;
}
std::ostream&
operator<<(std::ostream& o, const Address& a)
{
return o << a.toString();
}
} // namespace ethernet
} // namespace nfd
-167
View File
@@ -1,167 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NFD_CORE_ETHERNET_HPP
#define NFD_CORE_ETHERNET_HPP
#include "common.hpp"
#include <boost/array.hpp>
#define ETHERTYPE_NDN 0x8624
namespace nfd {
namespace ethernet {
const size_t ADDR_LEN = 6; ///< Octets in one Ethernet address
const size_t TYPE_LEN = 2; ///< Octets in Ethertype field
const size_t HDR_LEN = 14; ///< Total octets in Ethernet header (without 802.1Q tag)
const size_t TAG_LEN = 4; ///< Octets in 802.1Q tag (TPID + priority + VLAN)
const size_t MIN_DATA_LEN = 46; ///< Min octets in Ethernet payload (assuming no 802.1Q tag)
const size_t MAX_DATA_LEN = 1500; ///< Max octets in Ethernet payload
const size_t CRC_LEN = 4; ///< Octets in Ethernet frame check sequence
class Address : public boost::array<uint8_t, ADDR_LEN>
{
public:
/// Constructs a null Ethernet address (00:00:00:00:00:00)
Address();
/// Constructs a new Ethernet address with the given octets
Address(uint8_t a1, uint8_t a2, uint8_t a3,
uint8_t a4, uint8_t a5, uint8_t a6);
/// Constructs a new Ethernet address with the given octets
explicit
Address(const uint8_t octets[ADDR_LEN]);
/// Copy constructor
Address(const Address& address);
/// True if this is a broadcast address (ff:ff:ff:ff:ff:ff)
bool
isBroadcast() const;
/// True if this is a multicast address
bool
isMulticast() const;
/// True if this is a null address (00:00:00:00:00:00)
bool
isNull() const;
/**
* @brief Converts the address to a human-readable string
*
* @param sep A character used to visually separate the octets,
* usually ':' (the default value) or '-'
*/
std::string
toString(char sep = ':') const;
/**
* @brief Creates an Address from a string containing an Ethernet address
* in hexadecimal notation, with colons or hyphens as separators
*
* @param str The string to be parsed
* @return Always an instance of Address, which will be null
* if the parsing fails
*/
static Address
fromString(const std::string& str);
};
/// Returns the Ethernet broadcast address (ff:ff:ff:ff:ff:ff)
inline Address
getBroadcastAddress()
{
static Address bcast(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
return bcast;
}
/// Returns the default Ethernet multicast address for NDN
inline Address
getDefaultMulticastAddress()
{
static Address mcast(0x01, 0x00, 0x5E, 0x00, 0x17, 0xAA);
return mcast;
}
inline
Address::Address()
{
assign(0);
}
inline
Address::Address(uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6)
{
elems[0] = a1;
elems[1] = a2;
elems[2] = a3;
elems[3] = a4;
elems[4] = a5;
elems[5] = a6;
}
inline
Address::Address(const uint8_t octets[])
{
std::copy(octets, octets + size(), begin());
}
inline
Address::Address(const Address& address)
{
std::copy(address.begin(), address.end(), begin());
}
inline bool
Address::isBroadcast() const
{
return elems[0] == 0xFF && elems[1] == 0xFF && elems[2] == 0xFF &&
elems[3] == 0xFF && elems[4] == 0xFF && elems[5] == 0xFF;
}
inline bool
Address::isMulticast() const
{
return (elems[0] & 1) != 0;
}
inline bool
Address::isNull() const
{
return elems[0] == 0x0 && elems[1] == 0x0 && elems[2] == 0x0 &&
elems[3] == 0x0 && elems[4] == 0x0 && elems[5] == 0x0;
}
std::ostream&
operator<<(std::ostream& o, const Address& a);
} // namespace ethernet
} // namespace nfd
#endif // NFD_FACE_ETHERNET_HPP
-356
View File
@@ -1,356 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_CORE_EVENT_EMITTER_HPP
#define NFD_CORE_EVENT_EMITTER_HPP
#include "common.hpp"
namespace nfd {
struct empty
{
};
/** \class EventEmitter
* \brief provides a lightweight event system
*
* To declare an event:
* EventEmitter<TArgs> onEventName;
* To subscribe to an event:
* eventSource->onEventName += eventHandler;
* Multiple functions can subscribe to the same event.
* To trigger an event:
* onEventName(args);
* To clear event subscriptions:
* onEventName.clear();
*/
// four arguments
template<typename T1 = empty, typename T2 = empty,
typename T3 = empty, typename T4 = empty>
class EventEmitter : noncopyable
{
public:
/// represents a handler that can subscribe to the event
typedef function<void(const T1&, const T2&,
const T3&, const T4&)> Handler;
/// adds an subscription
void
operator+=(Handler handler);
/// returns true if there is no subscription,
/// otherwise returns false
bool
isEmpty();
/// clears all subscriptions
void
clear();
/// triggers the event
void
operator()(const T1& a1, const T2& a2, const T3& a3, const T4& a4);
private:
/// stores all subscribed handlers
std::vector<Handler> m_handlers;
};
// zero argument
template<>
class EventEmitter<empty, empty, empty, empty> : noncopyable
{
public:
typedef function<void()> Handler;
void
operator+=(Handler handler);
bool
isEmpty();
void
clear();
void
operator()();
private:
std::vector<Handler> m_handlers;
};
// one argument
template<typename T1>
class EventEmitter<T1, empty, empty, empty> : noncopyable
{
public:
typedef function<void(const T1&)> Handler;
void
operator+=(Handler handler);
bool
isEmpty();
void
clear();
void
operator()(const T1& a1);
private:
std::vector<Handler> m_handlers;
};
// two arguments
template<typename T1, typename T2>
class EventEmitter<T1, T2, empty, empty> : noncopyable
{
public:
typedef function<void(const T1&, const T2&)> Handler;
void
operator+=(Handler handler);
bool
isEmpty();
void
clear();
void
operator()(const T1& a1, const T2& a2);
private:
std::vector<Handler> m_handlers;
};
// three arguments
template<typename T1, typename T2, typename T3>
class EventEmitter<T1, T2, T3, empty> : noncopyable
{
public:
typedef function<void(const T1&, const T2&, const T3&)> Handler;
void
operator+=(Handler handler);
bool
isEmpty();
void
clear();
void
operator()(const T1& a1, const T2& a2, const T3& a3);
private:
std::vector<Handler> m_handlers;
};
// zero argument
inline void
EventEmitter<empty, empty, empty, empty>::operator+=(Handler handler)
{
m_handlers.push_back(handler);
}
inline bool
EventEmitter<empty, empty, empty, empty>::isEmpty()
{
return m_handlers.empty();
}
inline void
EventEmitter<empty, empty, empty, empty>::clear()
{
return m_handlers.clear();
}
inline void
EventEmitter<empty, empty, empty, empty>::operator()()
{
std::vector<Handler>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
(*it)();
if (m_handlers.empty()) // .clear has been called
return;
}
}
// one argument
template<typename T1>
inline void
EventEmitter<T1, empty, empty, empty>::operator+=(Handler handler)
{
m_handlers.push_back(handler);
}
template<typename T1>
inline bool
EventEmitter<T1, empty, empty, empty>::isEmpty()
{
return m_handlers.empty();
}
template<typename T1>
inline void
EventEmitter<T1, empty, empty, empty>::clear()
{
return m_handlers.clear();
}
template<typename T1>
inline void
EventEmitter<T1, empty, empty, empty>::operator()(const T1& a1)
{
typename std::vector<Handler>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
(*it)(a1);
if (m_handlers.empty()) // .clear has been called
return;
}
}
// two arguments
template<typename T1, typename T2>
inline void
EventEmitter<T1, T2, empty, empty>::operator+=(Handler handler)
{
m_handlers.push_back(handler);
}
template<typename T1, typename T2>
inline bool
EventEmitter<T1, T2, empty, empty>::isEmpty()
{
return m_handlers.empty();
}
template<typename T1, typename T2>
inline void
EventEmitter<T1, T2, empty, empty>::clear()
{
return m_handlers.clear();
}
template<typename T1, typename T2>
inline void
EventEmitter<T1, T2, empty, empty>::operator()
(const T1& a1, const T2& a2)
{
typename std::vector<Handler>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
(*it)(a1, a2);
if (m_handlers.empty()) // .clear has been called
return;
}
}
// three arguments
template<typename T1, typename T2, typename T3>
inline void
EventEmitter<T1, T2, T3, empty>::operator+=(Handler handler)
{
m_handlers.push_back(handler);
}
template<typename T1, typename T2, typename T3>
inline bool
EventEmitter<T1, T2, T3, empty>::isEmpty()
{
return m_handlers.empty();
}
template<typename T1, typename T2, typename T3>
inline void
EventEmitter<T1, T2, T3, empty>::clear()
{
return m_handlers.clear();
}
template<typename T1, typename T2, typename T3>
inline void
EventEmitter<T1, T2, T3, empty>::operator()
(const T1& a1, const T2& a2, const T3& a3)
{
typename std::vector<Handler>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
(*it)(a1, a2, a3);
if (m_handlers.empty()) // .clear has been called
return;
}
}
// four arguments
template<typename T1, typename T2, typename T3, typename T4>
inline void
EventEmitter<T1, T2, T3, T4>::operator+=(Handler handler)
{
m_handlers.push_back(handler);
}
template<typename T1, typename T2, typename T3, typename T4>
inline bool
EventEmitter<T1, T2, T3, T4>::isEmpty()
{
return m_handlers.empty();
}
template<typename T1, typename T2, typename T3, typename T4>
inline void
EventEmitter<T1, T2, T3, T4>::clear()
{
return m_handlers.clear();
}
template<typename T1, typename T2, typename T3, typename T4>
inline void
EventEmitter<T1, T2, T3, T4>::operator()
(const T1& a1, const T2& a2, const T3& a3, const T4& a4)
{
typename std::vector<Handler>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
(*it)(a1, a2, a3, a4);
if (m_handlers.empty()) // .clear has been called
return;
}
}
} // namespace nfd
#endif // NFD_CORE_EVENT_EMITTER_HPP
+56
View File
@@ -0,0 +1,56 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_CORE_EXTENDED_ERROR_MESSAGE_HPP
#define NFD_CORE_EXTENDED_ERROR_MESSAGE_HPP
#include <boost/exception/get_error_info.hpp>
namespace nfd {
template<typename E>
std::string
getExtendedErrorMessage(const E& exception)
{
std::ostringstream errorMessage;
errorMessage << exception.what();
const char* const* file = boost::get_error_info<boost::throw_file>(exception);
const int* line = boost::get_error_info<boost::throw_line>(exception);
const char* const* func = boost::get_error_info<boost::throw_function>(exception);
if (file && line) {
errorMessage << " [from " << *file << ":" << *line;
if (func) {
errorMessage << " in " << *func;
}
errorMessage << "]";
}
return errorMessage.str();
}
} // namespace nfd
#endif // NFD_CORE_EXTENDED_ERROR_MESSAGE_HPP
-163
View File
@@ -1,163 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "face-uri.hpp"
#include "core/logger.hpp"
#ifdef HAVE_LIBPCAP
#include "ethernet.hpp"
#endif // HAVE_LIBPCAP
#include <boost/regex.hpp>
NFD_LOG_INIT("FaceUri");
namespace nfd {
FaceUri::FaceUri(const std::string& uri)
{
if (!parse(uri)) {
throw Error("Malformed URI: " + uri);
}
}
FaceUri::FaceUri(const char* uri)
{
if (!parse(uri)) {
throw Error("Malformed URI: " + std::string(uri));
}
}
bool
FaceUri::parse(const std::string& uri)
{
m_scheme.clear();
m_host.clear();
m_isV6 = false;
m_port.clear();
m_path.clear();
static const boost::regex protocolExp("(\\w+\\d?)://([^/]*)(\\/[^?]*)?");
boost::smatch protocolMatch;
if (!boost::regex_match(uri, protocolMatch, protocolExp)) {
return false;
}
m_scheme = protocolMatch[1];
const std::string& authority = protocolMatch[2];
m_path = protocolMatch[3];
// pattern for IPv6 address enclosed in [ ], with optional port number
static const boost::regex v6Exp("^\\[([a-fA-F0-9:]+)\\](?:\\:(\\d+))?$");
// pattern for Ethernet address in standard hex-digits-and-colons notation
static const boost::regex etherExp("^\\[((?:[a-fA-F0-9]{1,2}\\:){5}(?:[a-fA-F0-9]{1,2}))\\]$");
// pattern for IPv4-mapped IPv6 address, with optional port number
static const boost::regex v4MappedV6Exp("^\\[::ffff:(\\d+(?:\\.\\d+){3})\\](?:\\:(\\d+))?$");
// pattern for IPv4/hostname/fd/ifname, with optional port number
static const boost::regex v4HostExp("^([^:]+)(?:\\:(\\d+))?$");
if (authority.empty()) {
// UNIX, internal
}
else {
boost::smatch match;
m_isV6 = boost::regex_match(authority, match, v6Exp);
if (m_isV6 ||
boost::regex_match(authority, match, etherExp) ||
boost::regex_match(authority, match, v4MappedV6Exp) ||
boost::regex_match(authority, match, v4HostExp)) {
m_host = match[1];
m_port = match[2];
}
else {
return false;
}
}
NFD_LOG_DEBUG("URI [" << uri << "] parsed into: " <<
m_scheme << ", " << m_host << ", " << m_port << ", " << m_path);
return true;
}
FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint)
{
m_isV6 = endpoint.address().is_v6();
m_scheme = m_isV6 ? "tcp6" : "tcp4";
m_host = endpoint.address().to_string();
m_port = boost::lexical_cast<std::string>(endpoint.port());
}
FaceUri::FaceUri(const boost::asio::ip::udp::endpoint& endpoint)
{
m_isV6 = endpoint.address().is_v6();
m_scheme = m_isV6 ? "udp6" : "udp4";
m_host = endpoint.address().to_string();
m_port = boost::lexical_cast<std::string>(endpoint.port());
}
FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint, const std::string& scheme)
: m_scheme(scheme)
{
m_isV6 = endpoint.address().is_v6();
m_host = endpoint.address().to_string();
m_port = boost::lexical_cast<std::string>(endpoint.port());
}
#ifdef HAVE_UNIX_SOCKETS
FaceUri::FaceUri(const boost::asio::local::stream_protocol::endpoint& endpoint)
: m_isV6(false)
{
m_scheme = "unix";
m_path = endpoint.path();
}
#endif // HAVE_UNIX_SOCKETS
FaceUri
FaceUri::fromFd(int fd)
{
FaceUri uri;
uri.m_scheme = "fd";
uri.m_host = boost::lexical_cast<std::string>(fd);
return uri;
}
#ifdef HAVE_LIBPCAP
FaceUri::FaceUri(const ethernet::Address& address)
: m_isV6(true)
{
m_scheme = "ether";
m_host = address.toString();
}
#endif // HAVE_LIBPCAP
FaceUri
FaceUri::fromDev(const std::string& ifname)
{
FaceUri uri;
uri.m_scheme = "dev";
uri.m_host = ifname;
return uri;
}
} // namespace nfd
-219
View File
@@ -1,219 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NFD_CORE_FACE_URI_H
#define NFD_CORE_FACE_URI_H
#include "common.hpp"
namespace nfd {
#ifdef HAVE_LIBPCAP
namespace ethernet {
class Address;
} // namespace ethernet
#endif // HAVE_LIBPCAP
/** \brief represents the underlying protocol and address used by a Face
* \sa http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#FaceUri
*/
class FaceUri
{
public:
class Error : public std::invalid_argument
{
public:
explicit
Error(const std::string& what)
: std::invalid_argument(what)
{
}
};
FaceUri();
/** \brief construct by parsing
*
* \param uri scheme://host[:port]/path
* \throw FaceUri::Error if URI cannot be parsed
*/
explicit
FaceUri(const std::string& uri);
// This overload is needed so that calls with string literal won't be
// resolved to boost::asio::local::stream_protocol::endpoint overload.
explicit
FaceUri(const char* uri);
/// exception-safe parsing
bool
parse(const std::string& uri);
public: // scheme-specific construction
/// construct tcp4 or tcp6 canonical FaceUri
explicit
FaceUri(const boost::asio::ip::tcp::endpoint& endpoint);
/// construct udp4 or udp6 canonical FaceUri
explicit
FaceUri(const boost::asio::ip::udp::endpoint& endpoint);
/// construct tcp canonical FaceUri with customized scheme
FaceUri(const boost::asio::ip::tcp::endpoint& endpoint, const std::string& scheme);
#ifdef HAVE_UNIX_SOCKETS
/// construct unix canonical FaceUri
explicit
FaceUri(const boost::asio::local::stream_protocol::endpoint& endpoint);
#endif // HAVE_UNIX_SOCKETS
/// create fd FaceUri from file descriptor
static FaceUri
fromFd(int fd);
#ifdef HAVE_LIBPCAP
/// construct ether canonical FaceUri
explicit
FaceUri(const ethernet::Address& address);
#endif // HAVE_LIBPCAP
/// create dev FaceUri from network device name
static FaceUri
fromDev(const std::string& ifname);
public: // getters
/// get scheme (protocol)
const std::string&
getScheme() const;
/// get host (domain)
const std::string&
getHost() const;
/// get port
const std::string&
getPort() const;
/// get path
const std::string&
getPath() const;
/// write as a string
std::string
toString() const;
public: // EqualityComparable concept
/// equality operator
bool
operator==(const FaceUri& rhs) const;
/// inequality operator
bool
operator!=(const FaceUri& rhs) const;
private:
std::string m_scheme;
std::string m_host;
/// whether to add [] around host when writing string
bool m_isV6;
std::string m_port;
std::string m_path;
friend std::ostream& operator<<(std::ostream& os, const FaceUri& uri);
};
inline
FaceUri::FaceUri()
: m_isV6(false)
{
}
inline const std::string&
FaceUri::getScheme() const
{
return m_scheme;
}
inline const std::string&
FaceUri::getHost() const
{
return m_host;
}
inline const std::string&
FaceUri::getPort() const
{
return m_port;
}
inline const std::string&
FaceUri::getPath() const
{
return m_path;
}
inline std::string
FaceUri::toString() const
{
std::ostringstream os;
os << *this;
return os.str();
}
inline bool
FaceUri::operator==(const FaceUri& rhs) const
{
return (m_scheme == rhs.m_scheme &&
m_host == rhs.m_host &&
m_isV6 == rhs.m_isV6 &&
m_port == rhs.m_port &&
m_path == rhs.m_path);
}
inline bool
FaceUri::operator!=(const FaceUri& rhs) const
{
return !(*this == rhs);
}
inline std::ostream&
operator<<(std::ostream& os, const FaceUri& uri)
{
os << uri.m_scheme << "://";
if (uri.m_isV6) {
os << "[" << uri.m_host << "]";
}
else {
os << uri.m_host;
}
if (!uri.m_port.empty()) {
os << ":" << uri.m_port;
}
os << uri.m_path;
return os;
}
} // namespace nfd
#endif // NFD_CORE_FACE_URI_H
+13 -10
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,9 +21,10 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "global-io.hpp"
#include <boost/thread/tss.hpp>
namespace nfd {
@@ -32,13 +34,14 @@ void
resetGlobalScheduler();
} // namespace scheduler
static shared_ptr<boost::asio::io_service> g_ioService;
static boost::thread_specific_ptr<boost::asio::io_service> g_ioService;
boost::asio::io_service&
getGlobalIoService()
{
if (!static_cast<bool>(g_ioService)) {
g_ioService = make_shared<boost::asio::io_service>();
if (g_ioService.get() == nullptr) {
g_ioService.reset(new boost::asio::io_service());
}
return *g_ioService;
}
+78 -82
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,10 +21,16 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "logger-factory.hpp"
#include <boost/range/adaptor/map.hpp>
#ifdef HAVE_CUSTOM_LOGGER
#error "This file should not be compiled when custom logger is used"
#endif
namespace nfd {
NFD_LOG_INIT("LoggerFactory");
@@ -65,44 +72,37 @@ LoggerFactory::parseLevel(const std::string& level)
// std::cerr << m_levelNames.begin()->first << std::endl;
LevelMap::const_iterator levelIt = m_levelNames.find(upperLevel);
if (levelIt != m_levelNames.end())
{
return levelIt->second;
}
try
{
uint32_t levelNo = boost::lexical_cast<uint32_t>(level);
if (levelIt != m_levelNames.end()) {
return levelIt->second;
}
try {
uint32_t levelNo = boost::lexical_cast<uint32_t>(level);
if ((boost::lexical_cast<uint32_t>(LOG_NONE) <= levelNo &&
levelNo <= boost::lexical_cast<uint32_t>(LOG_TRACE)) ||
levelNo == LOG_ALL)
{
return static_cast<LogLevel>(levelNo);
}
if ((boost::lexical_cast<uint32_t>(LOG_NONE) <= levelNo &&
levelNo <= boost::lexical_cast<uint32_t>(LOG_TRACE)) ||
levelNo == LOG_ALL) {
return static_cast<LogLevel>(levelNo);
}
catch (const boost::bad_lexical_cast& error)
{
}
throw LoggerFactory::Error("Unsupported logging level \"" +
level + "\"");
}
catch (const boost::bad_lexical_cast& error) {
}
BOOST_THROW_EXCEPTION(LoggerFactory::Error("Unsupported logging level \"" + level + "\""));
}
LogLevel
LoggerFactory::extractLevel(const ConfigSection& item, const std::string& key)
{
std::string levelString;
try
{
levelString = item.get_value<std::string>();
}
catch (const boost::property_tree::ptree_error& error)
{
}
try {
levelString = item.get_value<std::string>();
}
catch (const boost::property_tree::ptree_error& error) {
}
if (levelString.empty())
{
throw LoggerFactory::Error("No logging level found for option \"" + key + "\"");
}
if (levelString.empty()) {
BOOST_THROW_EXCEPTION(LoggerFactory::Error("No logging level found for option \"" + key + "\""));
}
return parseLevel(levelString);
}
@@ -126,58 +126,51 @@ LoggerFactory::onConfig(const ConfigSection& section,
// Forwarder WARN
// }
if (!isDryRun)
{
ConfigSection::const_assoc_iterator item = section.find("default_level");
if (item != section.not_found())
{
LogLevel level = extractLevel(item->second, "default_level");
setDefaultLevel(level);
}
else
{
setDefaultLevel(LOG_INFO);
}
if (!isDryRun) {
ConfigSection::const_assoc_iterator item = section.find("default_level");
if (item != section.not_found()) {
LogLevel level = extractLevel(item->second, "default_level");
setDefaultLevel(level);
}
for (ConfigSection::const_iterator item = section.begin();
item != section.end();
++item)
{
LogLevel level = extractLevel(item->second, item->first);
if (item->first == "default_level")
{
// do nothing
}
else
{
LoggerMap::iterator loggerIt = m_loggers.find(item->first);
if (loggerIt == m_loggers.end())
{
NFD_LOG_DEBUG("Failed to configure logging level for module \"" <<
item->first << "\" (module not found)");
}
else if (!isDryRun)
{
// std::cerr << "changing level for module " << item->first << " to " << level << std::endl;
loggerIt->second.setLogLevel(level);
}
}
else {
setDefaultLevel(LOG_INFO);
}
}
for (const auto& i : section) {
LogLevel level = extractLevel(i.second, i.first);
if (i.first == "default_level") {
// do nothing
}
else {
std::unique_lock<std::mutex> lock(m_loggersGuard);
LoggerMap::iterator loggerIt = m_loggers.find(i.first);
if (loggerIt == m_loggers.end()) {
lock.unlock();
NFD_LOG_DEBUG("Failed to configure logging level for module \"" <<
i.first << "\" (module not found)");
}
else if (!isDryRun) {
loggerIt->second.setLogLevel(level);
lock.unlock();
NFD_LOG_DEBUG("Changing level for module " << i.first << " to " << level);
}
}
}
}
void
LoggerFactory::setDefaultLevel(LogLevel level)
{
// std::cerr << "changing to default_level " << level << std::endl;
std::lock_guard<std::mutex> lock(m_loggersGuard);
m_defaultLevel = level;
for (LoggerMap::iterator i = m_loggers.begin(); i != m_loggers.end(); ++i)
{
// std::cerr << "changing " << i->first << " to default " << m_defaultLevel << std::endl;
i->second.setLogLevel(m_defaultLevel);
}
for (auto&& logger : m_loggers) {
// std::cerr << "changing " << i->first << " to default " << m_defaultLevel << std::endl;
logger.second.setLogLevel(m_defaultLevel);
}
}
Logger&
@@ -192,6 +185,8 @@ LoggerFactory::createLogger(const std::string& moduleName)
// std::cerr << "creating logger for " << moduleName
// << " with level " << m_defaultLevel << std::endl;
std::lock_guard<std::mutex> lock(m_loggersGuard);
std::pair<LoggerMap::iterator, bool> loggerIt =
m_loggers.insert(NameAndLogger(moduleName, Logger(moduleName, m_defaultLevel)));
@@ -201,11 +196,12 @@ LoggerFactory::createLogger(const std::string& moduleName)
std::list<std::string>
LoggerFactory::getModules() const
{
std::lock_guard<std::mutex> lock(m_loggersGuard);
std::list<std::string> modules;
for (LoggerMap::const_iterator i = m_loggers.begin(); i != m_loggers.end(); ++i)
{
modules.push_back(i->first);
}
for (const auto& loggerName : m_loggers | boost::adaptors::map_keys) {
modules.push_back(loggerName);
}
return modules;
}
+16 -7
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,12 +21,17 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NFD_CORE_LOGGER_FACTORY_HPP
#define NFD_CORE_LOGGER_FACTORY_HPP
#include "common.hpp"
#ifdef HAVE_CUSTOM_LOGGER
#include "custom-logger-factory.hpp"
#else
#include "config-file.hpp"
#include "logger.hpp"
@@ -95,6 +101,7 @@ private:
typedef std::pair<std::string, Logger> NameAndLogger;
LoggerMap m_loggers;
mutable std::mutex m_loggersGuard;
LogLevel m_defaultLevel;
};
@@ -107,4 +114,6 @@ LoggerFactory::getDefaultLevel() const
} // namespace nfd
#endif // HAVE_CUSTOM_LOGGER
#endif // NFD_CORE_LOGGER_FACTORY_HPP
+74
View File
@@ -0,0 +1,74 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "logger.hpp"
#ifdef HAVE_CUSTOM_LOGGER
#error "This file should not be compiled when custom logger is used"
#endif
#include <ndn-cxx/util/time.hpp>
#include <cinttypes>
#include <stdio.h>
#include <type_traits>
namespace nfd {
std::mutex g_logMutex;
Logger::Logger(const std::string& name, LogLevel level)
: m_moduleName(name)
, m_enabledLogLevel(level)
{
}
const char*
Logger::now()
{
using namespace ndn::time;
static const microseconds::rep ONE_SECOND = 1000000;
microseconds::rep microsecondsSinceEpoch = duration_cast<microseconds>(
system_clock::now().time_since_epoch()).count();
// 10 (whole seconds) + '.' + 6 (fraction) + '\0'
static char buffer[10 + 1 + 6 + 1];
BOOST_ASSERT_MSG(microsecondsSinceEpoch / ONE_SECOND <= 9999999999L,
"whole seconds cannot fit in 10 characters");
static_assert(std::is_same<microseconds::rep, int_least64_t>::value,
"PRIdLEAST64 is incompatible with microseconds::rep");
// - std::snprintf not found in some environments
// http://redmine.named-data.net/issues/2299 for more information
snprintf(buffer, sizeof(buffer), "%" PRIdLEAST64 ".%06" PRIdLEAST64,
microsecondsSinceEpoch / ONE_SECOND,
microsecondsSinceEpoch % ONE_SECOND);
// It's okay to return a statically allocated buffer, because Logger::now() is invoked
// only once per log macro.
return buffer;
}
} // namespace nfd
+47 -68
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,47 +21,49 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NFD_CORE_LOGGER_HPP
#define NFD_CORE_LOGGER_HPP
#include "common.hpp"
#include <ndn-cxx/util/time.hpp>
/// \todo use when we enable C++11 (see todo in now())
// #include <cinttypes>
#ifdef HAVE_CUSTOM_LOGGER
#include "custom-logger.hpp"
#else
#include <mutex>
namespace nfd {
/** \brief indicates a log level
* \note This type is internal. Logger should be accessed through NFD_LOG_* macros.
*/
enum LogLevel {
LOG_FATAL = -1, // fatal (will be logged unconditionally)
LOG_NONE = 0, // no messages
LOG_ERROR = 1, // serious error messages
LOG_WARN = 2, // warning messages
LOG_INFO = 3, // informational messages
LOG_DEBUG = 4, // debug messages
LOG_TRACE = 5, // trace messages (most verbose)
// LOG_FATAL is not a level and is logged unconditionally
LOG_ALL = 255 // all messages
};
/** \brief provides logging for a module
* \note This type is internal. Logger should be accessed through NFD_LOG_* macros.
* \note This type is copyable because logger can be declared as a field of
* (usually template) classes, and shouldn't prevent those classes to be copyable.
*/
class Logger
{
public:
Logger(const std::string& name, LogLevel level)
: m_moduleName(name)
, m_enabledLogLevel(level)
{
}
Logger(const std::string& name, LogLevel level);
bool
isEnabled(LogLevel level) const
{
// std::cerr << m_moduleName <<
// " enabled = " << m_enabledLogLevel
// << " level = " << level << std::endl;
return (m_enabledLogLevel >= level);
return m_enabledLogLevel >= level;
}
void
@@ -81,29 +84,12 @@ public:
m_moduleName = name;
}
/// \brief return a string representation of time since epoch: seconds.microseconds
static std::string
now()
{
using namespace ndn::time;
static const microseconds::rep ONE_SECOND = 1000000;
microseconds::rep microseconds_since_epoch =
duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
// 10 (whole seconds) + '.' + 6 (fraction) + 1 (\0)
char buffer[10 + 1 + 6 + 1];
::snprintf(buffer, sizeof(buffer), "%lld.%06lld",
static_cast<long long int>(microseconds_since_epoch / ONE_SECOND),
static_cast<long long int>(microseconds_since_epoch % ONE_SECOND));
/// \todo use this version when we enable C++11 to avoid casting
// ::snprintf(buffer, sizeof(buffer), "%" PRIdLEAST64 ".%06" PRIdLEAST64,
// microseconds_since_epoch / ONE_SECOND,
// microseconds_since_epoch % ONE_SECOND);
return std::string(buffer);
}
/** \return string representation of time since epoch: seconds.microseconds
* \warning Return value is in a statically allocated buffer,
* which subsequent calls will overwrite.
*/
static const char*
now();
private:
std::string m_moduleName;
@@ -144,33 +130,26 @@ nfd::Logger& cls<specialization>::g_logger = nfd::LoggerFactory::create(name)
template<> \
nfd::Logger& cls<s1, s2>::g_logger = nfd::LoggerFactory::create(name)
extern std::mutex g_logMutex;
#define NFD_LOG(level, expression) \
do { \
if (g_logger.isEnabled(::nfd::LOG_##level)) \
std::clog << ::nfd::Logger::now() << " "#level": " \
<< "[" << g_logger << "] " << expression << "\n"; \
#define NFD_LOG(level, msg, expression) \
do { \
if (g_logger.isEnabled(::nfd::LOG_##level)) { \
std::lock_guard<std::mutex> lock(::nfd::g_logMutex); \
std::clog << ::nfd::Logger::now() << " "#msg": " \
<< "[" << g_logger << "] " << expression << "\n"; \
} \
} while (false)
#define NFD_LOG_TRACE(expression) NFD_LOG(TRACE, expression)
#define NFD_LOG_DEBUG(expression) NFD_LOG(DEBUG, expression)
#define NFD_LOG_INFO(expression) NFD_LOG(INFO, expression)
#define NFD_LOG_ERROR(expression) NFD_LOG(ERROR, expression)
#define NFD_LOG_TRACE(expression) NFD_LOG(TRACE, TRACE, expression)
#define NFD_LOG_DEBUG(expression) NFD_LOG(DEBUG, DEBUG, expression)
#define NFD_LOG_INFO(expression) NFD_LOG(INFO, INFO, expression)
#define NFD_LOG_WARN(expression) NFD_LOG(WARN, WARNING, expression)
#define NFD_LOG_ERROR(expression) NFD_LOG(ERROR, ERROR, expression)
#define NFD_LOG_FATAL(expression) NFD_LOG(FATAL, FATAL, expression)
// specialize WARN because the message is "WARNING" instead of "WARN"
#define NFD_LOG_WARN(expression) \
do { \
if (g_logger.isEnabled(::nfd::LOG_WARN)) \
std::clog << ::nfd::Logger::now() << " WARNING: " \
<< "[" << g_logger << "] " << expression << "\n"; \
} while (false)
} // namespace nfd
#define NFD_LOG_FATAL(expression) \
do { \
std::clog << ::nfd::Logger::now() << " FATAL: " \
<< "[" << g_logger << "] " << expression << "\n"; \
} while (false)
#endif // HAVE_CUSTOM_LOGGER
} //namespace nfd
#endif
#endif // NFD_CORE_LOGGER_HPP
-87
View File
@@ -1,87 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NFD_CORE_MAP_VALUE_ITERATOR_H
#define NFD_CORE_MAP_VALUE_ITERATOR_H
#include "common.hpp"
#include <boost/iterator/transform_iterator.hpp>
namespace nfd {
/** \class MapValueIterator
* \brief ForwardIterator to iterator over map values
*/
template<typename Map>
class MapValueIterator
: public boost::transform_iterator<
function<const typename Map::mapped_type&(const typename Map::value_type&)>,
typename Map::const_iterator>
{
public:
explicit
MapValueIterator(typename Map::const_iterator it)
: boost::transform_iterator<
function<const typename Map::mapped_type&(const typename Map::value_type&)>,
typename Map::const_iterator>(it, &takeSecond)
{
}
private:
static const typename Map::mapped_type&
takeSecond(const typename Map::value_type& pair)
{
return pair.second;
}
};
/** \class MapValueReverseIterator
* \brief ReverseIterator to iterator over map values
*/
template<typename Map>
class MapValueReverseIterator
: public boost::transform_iterator<
function<const typename Map::mapped_type&(const typename Map::value_type&)>,
typename Map::const_reverse_iterator>
{
public:
explicit
MapValueReverseIterator(typename Map::const_reverse_iterator it)
: boost::transform_iterator<
function<const typename Map::mapped_type&(const typename Map::value_type&)>,
typename Map::const_reverse_iterator>(it, &takeSecond)
{
}
private:
static const typename Map::mapped_type&
takeSecond(const typename Map::value_type& pair)
{
return pair.second;
}
};
} // namespace nfd
#endif // NFD_CORE_MAP_VALUE_ITERATOR_H
+136 -90
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,120 +21,165 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "network-interface.hpp"
#include "core/logger.hpp"
#include <boost/foreach.hpp>
#include <cerrno>
#include <cstring>
#include <type_traits>
#include <unordered_map>
#ifdef HAVE_IFADDRS_H
#include <ifaddrs.h> // for getifaddrs()
#include <arpa/inet.h> // for inet_ntop()
#include <netinet/in.h> // for struct sockaddr_in{,6}
#include <ifaddrs.h> // for getifaddrs()
#if defined(__linux__)
#include <net/if_arp.h> // for ARPHRD_* constants
#include <netpacket/packet.h> // for struct sockaddr_ll
#elif defined(__APPLE__) || defined(__FreeBSD__)
#include <net/if_dl.h> // for struct sockaddr_dl
#else
#error Platform not supported
#include <net/if_types.h> // for IFT_* constants
#endif
#endif // HAVE_IFADDRS_H
NFD_LOG_INIT("NetworkInterfaceInfo");
namespace nfd {
std::list< shared_ptr<NetworkInterfaceInfo> >
static_assert(std::is_standard_layout<NetworkInterfaceInfo>::value,
"NetworkInterfaceInfo must be a standard layout type");
#ifdef HAVE_IS_DEFAULT_CONSTRUCTIBLE
static_assert(std::is_default_constructible<NetworkInterfaceInfo>::value,
"NetworkInterfaceInfo must provide a default constructor");
#endif
#ifdef WITH_TESTS
static shared_ptr<std::vector<NetworkInterfaceInfo>> s_debugNetworkInterfaces = nullptr;
void
setDebugNetworkInterfaces(shared_ptr<std::vector<NetworkInterfaceInfo>> interfaces)
{
s_debugNetworkInterfaces = interfaces;
}
#endif
std::vector<NetworkInterfaceInfo>
listNetworkInterfaces()
{
typedef std::map< std::string, shared_ptr<NetworkInterfaceInfo> > InterfacesMap;
InterfacesMap ifmap;
ifaddrs* ifa_list;
if (::getifaddrs(&ifa_list) < 0)
throw std::runtime_error("getifaddrs() failed");
for (ifaddrs* ifa = ifa_list; ifa != 0; ifa = ifa->ifa_next)
{
shared_ptr<NetworkInterfaceInfo> netif;
std::string ifname(ifa->ifa_name);
InterfacesMap::iterator i = ifmap.find(ifname);
if (i == ifmap.end())
{
netif = make_shared<NetworkInterfaceInfo>();
netif->name = ifname;
netif->flags = ifa->ifa_flags;
ifmap[ifname] = netif;
}
else
{
netif = i->second;
}
if (!ifa->ifa_addr)
continue;
switch (ifa->ifa_addr->sa_family)
{
case AF_INET: {
const sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(ifa->ifa_addr);
char address[INET_ADDRSTRLEN];
if (::inet_ntop(AF_INET, &sin->sin_addr, address, sizeof(address)))
netif->ipv4Addresses.push_back(boost::asio::ip::address_v4::from_string(address));
else
NFD_LOG_WARN("inet_ntop() failed on " << ifname);
}
break;
case AF_INET6: {
const sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(ifa->ifa_addr);
char address[INET6_ADDRSTRLEN];
if (::inet_ntop(AF_INET6, &sin6->sin6_addr, address, sizeof(address)))
netif->ipv6Addresses.push_back(boost::asio::ip::address_v6::from_string(address));
else
NFD_LOG_WARN("inet_ntop() failed on " << ifname);
}
break;
#if defined(__linux__)
case AF_PACKET: {
const sockaddr_ll* sll = reinterpret_cast<sockaddr_ll*>(ifa->ifa_addr);
netif->index = sll->sll_ifindex;
if (sll->sll_hatype == ARPHRD_ETHER && sll->sll_halen == ethernet::ADDR_LEN)
netif->etherAddress = ethernet::Address(sll->sll_addr);
else if (sll->sll_hatype != ARPHRD_LOOPBACK)
NFD_LOG_WARN("Unrecognized hardware address on " << ifname);
}
break;
#elif defined(__APPLE__) || defined(__FreeBSD__)
case AF_LINK: {
const sockaddr_dl* sdl = reinterpret_cast<sockaddr_dl*>(ifa->ifa_addr);
netif->index = sdl->sdl_index;
netif->etherAddress = ethernet::Address(reinterpret_cast<uint8_t*>(LLADDR(sdl)));
}
break;
#ifdef WITH_TESTS
if (s_debugNetworkInterfaces != nullptr) {
return *s_debugNetworkInterfaces;
}
#endif
}
if (netif->isBroadcastCapable() && ifa->ifa_broadaddr != 0)
{
const sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(ifa->ifa_broadaddr);
#ifdef HAVE_IFADDRS_H
using namespace boost::asio::ip;
using std::strerror;
char address[INET_ADDRSTRLEN];
if (::inet_ntop(AF_INET, &sin->sin_addr, address, sizeof(address)))
netif->broadcastAddress = boost::asio::ip::address_v4::from_string(address);
else
NFD_LOG_WARN("inet_ntop() failed on " << ifname);
}
std::unordered_map<std::string, NetworkInterfaceInfo> ifmap;
ifaddrs* ifa_list = nullptr;
if (::getifaddrs(&ifa_list) < 0)
BOOST_THROW_EXCEPTION(std::runtime_error(std::string("getifaddrs() failed: ") +
strerror(errno)));
for (ifaddrs* ifa = ifa_list; ifa != nullptr; ifa = ifa->ifa_next) {
std::string ifname(ifa->ifa_name);
NetworkInterfaceInfo& netif = ifmap[ifname];
netif.name = ifa->ifa_name;
netif.flags = ifa->ifa_flags;
if (ifa->ifa_addr == nullptr)
continue;
switch (ifa->ifa_addr->sa_family) {
case AF_INET: {
const sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(ifa->ifa_addr);
char address[INET_ADDRSTRLEN];
if (::inet_ntop(AF_INET, &sin->sin_addr, address, sizeof(address))) {
netif.ipv4Addresses.push_back(address_v4::from_string(address));
NFD_LOG_TRACE(ifname << ": added IPv4 address " << address);
}
else
NFD_LOG_WARN(ifname << ": inet_ntop(AF_INET) failed: " << strerror(errno));
break;
}
case AF_INET6: {
const sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(ifa->ifa_addr);
char address[INET6_ADDRSTRLEN];
if (::inet_ntop(AF_INET6, &sin6->sin6_addr, address, sizeof(address))) {
netif.ipv6Addresses.push_back(address_v6::from_string(address));
NFD_LOG_TRACE(ifname << ": added IPv6 address " << address);
}
else
NFD_LOG_WARN(ifname << ": inet_ntop(AF_INET6) failed: " << strerror(errno));
break;
}
#if defined(__linux__)
case AF_PACKET: {
const sockaddr_ll* sll = reinterpret_cast<sockaddr_ll*>(ifa->ifa_addr);
netif.index = sll->sll_ifindex;
if (sll->sll_hatype == ARPHRD_ETHER && sll->sll_halen == ethernet::ADDR_LEN) {
netif.etherAddress = ethernet::Address(sll->sll_addr);
NFD_LOG_TRACE(ifname << ": added Ethernet address " << netif.etherAddress);
}
else if (sll->sll_hatype != ARPHRD_LOOPBACK) {
NFD_LOG_DEBUG(ifname << ": ignoring link-layer address for unhandled hardware type "
<< sll->sll_hatype);
}
break;
}
#elif defined(__APPLE__) || defined(__FreeBSD__)
case AF_LINK: {
const sockaddr_dl* sdl = reinterpret_cast<sockaddr_dl*>(ifa->ifa_addr);
netif.index = sdl->sdl_index;
if (sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == ethernet::ADDR_LEN) {
netif.etherAddress = ethernet::Address(reinterpret_cast<uint8_t*>(LLADDR(sdl)));
NFD_LOG_TRACE(ifname << ": added Ethernet address " << netif.etherAddress);
}
else if (sdl->sdl_type != IFT_LOOP) {
NFD_LOG_DEBUG(ifname << ": ignoring link-layer address for unhandled interface type "
<< sdl->sdl_type);
}
break;
}
#endif
}
if (netif.isBroadcastCapable() && ifa->ifa_broadaddr != nullptr) {
const sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(ifa->ifa_broadaddr);
char address[INET_ADDRSTRLEN];
if (::inet_ntop(AF_INET, &sin->sin_addr, address, sizeof(address))) {
netif.broadcastAddress = address_v4::from_string(address);
NFD_LOG_TRACE(ifname << ": added IPv4 broadcast address " << address);
}
else
NFD_LOG_WARN(ifname << ": inet_ntop(AF_INET) for broadaddr failed: " << strerror(errno));
}
}
::freeifaddrs(ifa_list);
std::list< shared_ptr<NetworkInterfaceInfo> > list;
BOOST_FOREACH(InterfacesMap::value_type elem, ifmap) {
list.push_back(elem.second);
std::vector<NetworkInterfaceInfo> v;
v.reserve(ifmap.size());
for (auto&& element : ifmap) {
v.push_back(element.second);
}
return list;
return v;
#else
return {};
#endif // HAVE_IFADDRS_H
}
} // namespace nfd
+26 -9
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,18 +21,23 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NFD_CORE_NETWORK_INTERFACE_HPP
#define NFD_CORE_NETWORK_INTERFACE_HPP
#include "common.hpp"
#include "ethernet.hpp"
#include <ndn-cxx/util/ethernet.hpp>
#include <net/if.h>
namespace nfd {
namespace ethernet = ndn::util::ethernet;
/** \brief contains information about a network interface
*/
class NetworkInterfaceInfo
{
public:
@@ -82,9 +88,20 @@ NetworkInterfaceInfo::isUp() const
return (flags & IFF_UP) != 0;
}
std::list< shared_ptr<NetworkInterfaceInfo> >
/** \brief List configured network interfaces on the system and their info
* \warning invalid IP addresses (e.g., 0.0.0.0) may be returned in some environments
*/
std::vector<NetworkInterfaceInfo>
listNetworkInterfaces();
#ifdef WITH_TESTS
/** \brief Set a list of network interfaces to be returned by subsequent listNetworkInterfaces call
* \note To reset to normal behavior, use `setDebugNetworkInterfaces(nullptr);`
*/
void
setDebugNetworkInterfaces(shared_ptr<std::vector<NetworkInterfaceInfo>> interfaces);
#endif
} // namespace nfd
#endif // NFD_CORE_NETWORK_INTERFACE_HPP
+34 -62
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -22,74 +23,45 @@
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NFD_TOOLS_NETWORK_HPP
#define NFD_TOOLS_NETWORK_HPP
#include "network.hpp"
#include <boost/asio.hpp>
namespace nfd {
class Network
void
Network::print(std::ostream& os) const
{
public:
Network()
{
}
os << m_minAddress << " <-> " << m_maxAddress;
}
Network(const boost::asio::ip::address& minAddress,
const boost::asio::ip::address& maxAddress)
: m_minAddress(minAddress)
, m_maxAddress(maxAddress)
{
}
const Network&
Network::getMaxRangeV4()
{
using boost::asio::ip::address_v4;
static Network range = Network(address_v4(0), address_v4(0xFFFFFFFF));
return range;
}
void
print(std::ostream& os) const
{
os << m_minAddress << " <-> " << m_maxAddress;
}
const Network&
Network::getMaxRangeV6()
{
using boost::asio::ip::address_v6;
static address_v6::bytes_type maxV6 = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
static Network range = Network(address_v6(), address_v6(maxV6));
return range;
}
bool
doesContain(const boost::asio::ip::address& address) const
{
return (m_minAddress <= address && address <= m_maxAddress);
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
static const Network&
getMaxRangeV4()
{
using boost::asio::ip::address_v4;
static Network range = Network(address_v4(0), address_v4(0xFFFFFFFF));
return range;
}
static const Network&
getMaxRangeV6()
{
using boost::asio::ip::address_v6;
static address_v6::bytes_type maxV6 = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
static Network range = Network(address_v6(), address_v6(maxV6));
return range;
}
private:
boost::asio::ip::address m_minAddress;
boost::asio::ip::address m_maxAddress;
friend std::istream&
operator>>(std::istream& is, Network& network);
friend std::ostream&
operator<<(std::ostream& os, const Network& network);
};
inline std::ostream&
std::ostream&
operator<<(std::ostream& os, const Network& network)
{
network.print(os);
return os;
}
inline std::istream&
std::istream&
operator>>(std::istream& is, Network& network)
{
using namespace boost::asio;
@@ -158,4 +130,4 @@ operator>>(std::istream& is, Network& network)
return is;
}
#endif // NFD_TOOLS_NETWORK_HPP
} // namespace nfd
@@ -21,74 +21,75 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
**/
#ifndef NFD_TESTS_CORE_SIMPLE_NOTIFICATION_HPP
#define NFD_TESTS_CORE_SIMPLE_NOTIFICATION_HPP
#ifndef NFD_CORE_NETWORK_HPP
#define NFD_CORE_NETWORK_HPP
#include "common.hpp"
#include "tests/test-common.hpp"
#include <boost/asio.hpp>
#include <boost/utility/value_init.hpp>
#include <boost/lexical_cast.hpp>
namespace nfd {
namespace tests {
class SimpleNotification
class Network
{
public:
SimpleNotification()
Network()
{
}
SimpleNotification(const std::string& message)
: m_message(message)
Network(const boost::asio::ip::address& minAddress,
const boost::asio::ip::address& maxAddress)
: m_minAddress(minAddress)
, m_maxAddress(maxAddress)
{
}
~SimpleNotification()
{
}
Block
wireEncode() const
{
ndn::EncodingBuffer buffer;
prependByteArrayBlock(buffer,
0x8888,
reinterpret_cast<const uint8_t*>(m_message.c_str()),
m_message.size());
return buffer.block();
}
void
wireDecode(const Block& block)
{
m_message.assign(reinterpret_cast<const char*>(block.value()),
block.value_size());
print(std::ostream& os) const;
// error for testing
if (!m_message.empty() && m_message[0] == '\x07')
throw tlv::Error("0x07 error");
bool
doesContain(const boost::asio::ip::address& address) const
{
return (m_minAddress <= address && address <= m_maxAddress);
}
public:
const std::string&
getMessage() const
static const Network&
getMaxRangeV4();
static const Network&
getMaxRangeV6();
bool
operator==(const Network& rhs) const
{
return m_message;
return m_minAddress == rhs.m_minAddress && m_maxAddress == rhs.m_maxAddress;
}
void
setMessage(const std::string& message)
bool
operator!=(const Network& rhs) const
{
m_message = message;
return !(*this == rhs);
}
private:
std::string m_message;
boost::asio::ip::address m_minAddress;
boost::asio::ip::address m_maxAddress;
friend std::istream&
operator>>(std::istream& is, Network& network);
friend std::ostream&
operator<<(std::ostream& os, const Network& network);
};
} // namespace tests
std::ostream&
operator<<(std::ostream& os, const Network& network);
std::istream&
operator>>(std::istream& is, Network& network);
} // namespace nfd
#endif // NFD_TESTS_CORE_SIMPLE_NOTIFICATION_HPP
#endif // NFD_CORE_NETWORK_HPP
-81
View File
@@ -1,81 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_CORE_NOTIFICATION_STREAM_HPP
#define NFD_CORE_NOTIFICATION_STREAM_HPP
#include "common.hpp"
#include <ndn-cxx/encoding/encoding-buffer.hpp>
#include <ndn-cxx/security/key-chain.hpp>
namespace nfd {
/** \brief provides a publisher of Notification Stream
* \sa http://redmine.named-data.net/projects/nfd/wiki/Notification
*/
template <class FaceBase>
class NotificationStream : noncopyable
{
public:
NotificationStream(FaceBase& face, const Name& prefix, ndn::KeyChain& keyChain)
: m_face(face)
, m_prefix(prefix)
, m_keyChain(keyChain)
, m_sequenceNo(0)
{
}
virtual
~NotificationStream()
{
}
template<typename T> void
postNotification(const T& notification)
{
Name dataName = m_prefix;
dataName.appendSequenceNumber(m_sequenceNo);
shared_ptr<Data> data = make_shared<Data>(dataName);
data->setContent(notification.wireEncode());
data->setFreshnessPeriod(time::seconds(1));
m_keyChain.sign(*data);
m_face.put(*data);
++m_sequenceNo;
}
private:
FaceBase& m_face;
const Name m_prefix;
ndn::KeyChain& m_keyChain;
uint64_t m_sequenceNo;
};
} // namespace nfd
#endif // NFD_CORE_NOTIFICATION_STREAM_HPP
+24 -7
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,7 +21,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "privilege-helper.hpp"
#include "core/logger.hpp"
@@ -32,15 +33,18 @@ namespace nfd {
NFD_LOG_INIT("PrivilegeHelper");
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
uid_t PrivilegeHelper::s_normalUid = ::geteuid();
gid_t PrivilegeHelper::s_normalGid = ::getegid();
uid_t PrivilegeHelper::s_privilegedUid = ::geteuid();
gid_t PrivilegeHelper::s_privilegedGid = ::getegid();
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
void
PrivilegeHelper::initialize(const std::string& userName, const std::string& groupName)
{
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
static const size_t MAX_GROUP_BUFFER_SIZE = 16384; // 16kB
static const size_t MAX_PASSWD_BUFFER_SIZE = 16384;
@@ -126,11 +130,17 @@ PrivilegeHelper::initialize(const std::string& userName, const std::string& grou
s_normalUid = passwd.pw_uid;
}
#else
if (!userName.empty() || !groupName.empty()) {
throw Error("Dropping and raising privileges is not supported on this platform");
}
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
}
void
PrivilegeHelper::drop()
{
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
NFD_LOG_TRACE("dropping to effective gid=" << s_normalGid);
if (::setegid(s_normalGid) != 0)
{
@@ -150,11 +160,15 @@ PrivilegeHelper::drop()
}
NFD_LOG_INFO("dropped to effective uid=" << ::geteuid() << " gid=" << ::getegid());
#else
NFD_LOG_WARN("Dropping privileges is not supported on this platform");
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
}
void
PrivilegeHelper::raise()
{
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
NFD_LOG_TRACE("elevating to effective uid=" << s_privilegedUid);
if (::seteuid(s_privilegedUid) != 0)
{
@@ -173,6 +187,9 @@ PrivilegeHelper::raise()
throw PrivilegeHelper::Error(error.str());
}
NFD_LOG_INFO("elevated to effective uid=" << ::geteuid() << " gid=" << ::getegid());
#else
NFD_LOG_WARN("Elevating privileges is not supported on this platform");
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
}
void
+17 -12
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,7 +21,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NFD_CORE_PRIVILEGE_HELPER_HPP
#define NFD_CORE_PRIVILEGE_HELPER_HPP
@@ -35,8 +36,11 @@ class PrivilegeHelper
{
public:
/// \brief PrivilegeHelper::Error represents a serious seteuid/gid failure and
/// should only be caught by main in as part of a graceful program termination.
/** \brief represents a serious seteuid/gid failure
*
* This should only be caught by main as part of a graceful program termination.
* \note This is not an std::exception and BOOST_THROW_EXCEPTION should not be used.
*/
class Error
{
public:
@@ -65,18 +69,19 @@ public:
static void
runElevated(function<void()> f);
private:
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
static void
raise();
private:
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
static uid_t s_normalUid;
static gid_t s_normalGid;
static uid_t s_privilegedUid;
static gid_t s_privilegedGid;
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
};
} // namespace nfd
+19 -9
View File
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -24,15 +24,25 @@
*/
#include "random.hpp"
#include <boost/thread/tss.hpp>
namespace nfd {
static boost::random::mt19937 g_rng;
static boost::thread_specific_ptr<boost::random::mt19937> g_rng;
boost::random::mt19937&
getGlobalRng()
{
return g_rng;
if (g_rng.get() == nullptr) {
g_rng.reset(new boost::random::mt19937());
}
return *g_rng;
}
void
resetGlobalRng()
{
g_rng.reset();
}
} // namespace nfd
-214
View File
@@ -1,214 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NFD_CORE_RESOLVER_H
#define NFD_CORE_RESOLVER_H
#include "common.hpp"
#include "core/global-io.hpp"
#include "core/scheduler.hpp"
namespace nfd {
namespace resolver {
typedef function<bool (const boost::asio::ip::address& address)> AddressSelector;
struct AnyAddress {
bool
operator()(const boost::asio::ip::address& address)
{
return true;
}
};
struct Ipv4Address {
bool
operator()(const boost::asio::ip::address& address)
{
return address.is_v4();
}
};
struct Ipv6Address {
bool
operator()(const boost::asio::ip::address& address)
{
return address.is_v6();
}
};
} // namespace resolver
template<class Protocol>
class Resolver
{
public:
struct Error : public std::runtime_error
{
Error(const std::string& what) : std::runtime_error(what) {}
};
typedef function<void (const typename Protocol::endpoint& endpoint)> SuccessCallback;
typedef function<void (const std::string& reason)> ErrorCallback;
typedef boost::asio::ip::basic_resolver< Protocol > resolver;
/** \brief Asynchronously resolve host and port
*
* If an address selector predicate is specified, then each resolved IP address
* is checked against the predicate.
*
* Available address selector predicates:
*
* - resolver::AnyAddress()
* - resolver::Ipv4Address()
* - resolver::Ipv6Address()
*/
static void
asyncResolve(const std::string& host, const std::string& port,
const SuccessCallback& onSuccess,
const ErrorCallback& onError,
const nfd::resolver::AddressSelector& addressSelector = nfd::resolver::AnyAddress(),
const time::seconds& timeout = time::seconds(4))
{
shared_ptr<Resolver> resolver =
shared_ptr<Resolver>(new Resolver(onSuccess, onError,
addressSelector));
resolver->asyncResolve(host, port, timeout, resolver);
// resolver will be destroyed when async operation finishes or global IO service stops
}
/** \brief Synchronously resolve host and port
*
* If an address selector predicate is specified, then each resolved IP address
* is checked against the predicate.
*
* Available address selector predicates:
*
* - resolver::AnyAddress()
* - resolver::Ipv4Address()
* - resolver::Ipv6Address()
*/
static typename Protocol::endpoint
syncResolve(const std::string& host, const std::string& port,
const nfd::resolver::AddressSelector& addressSelector = nfd::resolver::AnyAddress())
{
Resolver resolver(SuccessCallback(), ErrorCallback(), addressSelector);
typename resolver::query query(host, port
#if not defined(__FreeBSD__)
, resolver::query::all_matching
#endif
);
typename resolver::iterator remoteEndpoint = resolver.m_resolver.resolve(query);
typename resolver::iterator end;
for (; remoteEndpoint != end; ++remoteEndpoint)
{
if (addressSelector(typename Protocol::endpoint(*remoteEndpoint).address()))
return *remoteEndpoint;
}
throw Error("No endpoint matching the specified address selector found");
}
private:
Resolver(const SuccessCallback& onSuccess,
const ErrorCallback& onError,
const nfd::resolver::AddressSelector& addressSelector)
: m_resolver(getGlobalIoService())
, m_addressSelector(addressSelector)
, m_onSuccess(onSuccess)
, m_onError(onError)
{
}
void
asyncResolve(const std::string& host, const std::string& port,
const time::seconds& timeout,
const shared_ptr<Resolver>& self)
{
typename resolver::query query(host, port
#if not defined(__FreeBSD__)
, resolver::query::all_matching
#endif
);
m_resolver.async_resolve(query,
bind(&Resolver::onResolveSuccess, this, _1, _2, self));
m_resolveTimeout = scheduler::schedule(timeout,
bind(&Resolver::onResolveError, this,
"Timeout", self));
}
void
onResolveSuccess(const boost::system::error_code& error,
typename resolver::iterator remoteEndpoint,
const shared_ptr<Resolver>& self)
{
scheduler::cancel(m_resolveTimeout);
if (error)
{
if (error == boost::system::errc::operation_canceled)
return;
return m_onError("Remote endpoint hostname or port cannot be resolved: " +
error.category().message(error.value()));
}
typename resolver::iterator end;
for (; remoteEndpoint != end; ++remoteEndpoint)
{
if (m_addressSelector(typename Protocol::endpoint(*remoteEndpoint).address()))
return m_onSuccess(*remoteEndpoint);
}
m_onError("No endpoint matching the specified address selector found");
}
void
onResolveError(const std::string& errorInfo,
const shared_ptr<Resolver>& self)
{
m_resolver.cancel();
m_onError(errorInfo);
}
private:
resolver m_resolver;
EventId m_resolveTimeout;
nfd::resolver::AddressSelector m_addressSelector;
SuccessCallback m_onSuccess;
ErrorCallback m_onError;
};
typedef Resolver<boost::asio::ip::tcp> TcpResolver;
typedef Resolver<boost::asio::ip::udp> UdpResolver;
} // namespace nfd
#endif // NFD_CORE_RESOLVER_H
+57 -11
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,22 +21,25 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "scheduler.hpp"
#include "global-io.hpp"
#include <boost/thread/tss.hpp>
namespace nfd {
namespace scheduler {
static shared_ptr<Scheduler> g_scheduler;
static boost::thread_specific_ptr<Scheduler> g_scheduler;
inline Scheduler&
Scheduler&
getGlobalScheduler()
{
if (!static_cast<bool>(g_scheduler)) {
g_scheduler = make_shared<Scheduler>(ref(getGlobalIoService()));
if (g_scheduler.get() == nullptr) {
g_scheduler.reset(new Scheduler(getGlobalIoService()));
}
return *g_scheduler;
}
@@ -57,5 +61,47 @@ resetGlobalScheduler()
g_scheduler.reset();
}
ScopedEventId::ScopedEventId()
{
}
ScopedEventId::ScopedEventId(const EventId& event)
: m_event(event)
{
}
ScopedEventId::ScopedEventId(ScopedEventId&& other)
: m_event(other.m_event)
{
other.release();
}
ScopedEventId&
ScopedEventId::operator=(const EventId& event)
{
if (m_event != event) {
scheduler::cancel(m_event);
m_event = event;
}
return *this;
}
ScopedEventId::~ScopedEventId()
{
scheduler::cancel(m_event);
}
void
ScopedEventId::cancel()
{
scheduler::cancel(m_event);
}
void
ScopedEventId::release()
{
m_event.reset();
}
} // namespace scheduler
} // namespace nfd
+51 -9
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,7 +21,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NFD_CORE_SCHEDULER_HPP
#define NFD_CORE_SCHEDULER_HPP
@@ -48,9 +49,50 @@ schedule(const time::nanoseconds& after, const Scheduler::Event& event);
void
cancel(const EventId& eventId);
} // namespace scheduler
/** \brief cancels an event automatically upon destruction
*/
class ScopedEventId : noncopyable
{
public:
ScopedEventId();
using scheduler::EventId;
/** \brief implicit constructor from EventId
* \param event the event to be cancelled upon destruction
*/
ScopedEventId(const EventId& event);
/** \brief move constructor
*/
ScopedEventId(ScopedEventId&& other);
/** \brief assigns an event
*
* If a different event has been assigned to this instance previously,
* that event will be cancelled immediately.
*/
ScopedEventId&
operator=(const EventId& event);
/** \brief cancels the event
*/
~ScopedEventId();
/** \brief cancels the event manually
*/
void
cancel();
/** \brief releases the event so that it won't be disconnected
* when this ScopedEventId is destructed
*/
void
release();
private:
EventId m_event;
};
} // namespace scheduler
} // namespace nfd
+20 -8
View File
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -40,10 +40,14 @@ template <class FaceBase>
class SegmentPublisher : noncopyable
{
public:
SegmentPublisher(FaceBase& face, const Name& prefix, ndn::KeyChain& keyChain)
SegmentPublisher(FaceBase& face,
const Name& prefix,
ndn::KeyChain& keyChain,
const time::milliseconds& freshnessPeriod = getDefaultFreshness())
: m_face(face)
, m_prefix(prefix)
, m_keyChain(keyChain)
, m_freshnessPeriod(freshnessPeriod)
{
}
@@ -59,6 +63,12 @@ public:
return MAX_SEGMENT_SIZE;
}
static constexpr time::milliseconds
getDefaultFreshness()
{
return time::milliseconds(1000);
}
void
publish()
{
@@ -84,6 +94,7 @@ public:
shared_ptr<Data> data = make_shared<Data>(segmentName);
data->setContent(segmentBegin, segmentEnd - segmentBegin);
data->setFreshnessPeriod(m_freshnessPeriod);
segmentBegin = segmentEnd;
if (segmentBegin >= end) {
@@ -113,6 +124,7 @@ private:
FaceBase& m_face;
const Name m_prefix;
ndn::KeyChain& m_keyChain;
const time::milliseconds m_freshnessPeriod;
};
} // namespace nfd
+21 -7
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,7 +21,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "channel.hpp"
@@ -36,4 +37,17 @@ Channel::setUri(const FaceUri& uri)
m_uri = uri;
}
void
connectFaceClosedSignal(Face& face, const std::function<void()>& f)
{
using face::FaceState;
face.afterStateChange.connect(
[f] (FaceState oldState, FaceState newState) {
if (newState == FaceState::CLOSED) {
f();
}
});
}
} // namespace nfd
+32 -18
View File
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,7 +21,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NFD_DAEMON_FACE_CHANNEL_HPP
#define NFD_DAEMON_FACE_CHANNEL_HPP
@@ -29,20 +30,23 @@
namespace nfd {
/**
* \brief Prototype for the callback that is invoked when the face
* is created (as a response to incoming connection or after
* connection is established)
*/
typedef function<void(const shared_ptr<Face>& newFace)> FaceCreatedCallback;
/**
* \brief Prototype for the callback that is invoked when the face
* fails to be created
*/
typedef function<void(const std::string& reason)> FaceCreationFailedCallback;
class Channel : noncopyable
{
public:
/** \brief Prototype for the callback called when face is created
* (as a response to incoming connection or after connection
* is established)
*/
typedef function<void(const shared_ptr<Face>& newFace)> FaceCreatedCallback;
/** \brief Prototype for the callback that is called when face is failed to
* get created
*/
typedef function<void(const std::string& reason)> ConnectFailedCallback;
virtual
~Channel();
@@ -63,6 +67,16 @@ Channel::getUri() const
return m_uri;
}
/** \brief invokes a callback when the face is closed
* \param face the face
* \param f the callback to be invoked when the face enters CLOSED state
*
* This function connects a callback to the afterStateChange signal on the \p face,
* and invokes \p f when the state becomes CLOSED.
*/
void
connectFaceClosedSignal(Face& face, const std::function<void()>& f);
} // namespace nfd
#endif // NFD_DAEMON_FACE_CHANNEL_HPP
-342
View File
@@ -1,342 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_DATAGRAM_FACE_HPP
#define NFD_DAEMON_FACE_DATAGRAM_FACE_HPP
#include "face.hpp"
#include "core/logger.hpp"
namespace nfd {
class Unicast {};
class Multicast {};
template<class Protocol, class Type = Unicast>
class DatagramFace : public Face
{
public:
typedef Protocol protocol;
/** \brief Construct datagram face
*
* \param socket Protocol-specific socket for the created face
* \param isOnDemand If true, the face can be closed after it remains
* unused for a certain amount of time
*/
DatagramFace(const FaceUri& remoteUri, const FaceUri& localUri,
const shared_ptr<typename protocol::socket>& socket,
bool isOnDemand);
virtual
~DatagramFace();
// from Face
virtual void
sendInterest(const Interest& interest);
virtual void
sendData(const Data& data);
virtual void
close();
void
receiveDatagram(const uint8_t* buffer,
size_t nBytesReceived,
const boost::system::error_code& error);
/**
* \brief Set m_hasBeenUsedRecently to false
*/
void
resetRecentUsage();
bool
hasBeenUsedRecently() const;
void
setOnDemand(bool isOnDemand);
protected:
void
handleSend(const boost::system::error_code& error,
size_t nBytesSent,
const Block& payload);
void
handleReceive(const boost::system::error_code& error,
size_t nBytesReceived);
void
keepFaceAliveUntilAllHandlersExecuted(const shared_ptr<Face>& face);
void
closeSocket();
protected:
shared_ptr<typename protocol::socket> m_socket;
uint8_t m_inputBuffer[MAX_NDN_PACKET_SIZE];
bool m_hasBeenUsedRecently;
NFD_LOG_INCLASS_DECLARE();
};
template<class T, class U>
inline
DatagramFace<T, U>::DatagramFace(const FaceUri& remoteUri, const FaceUri& localUri,
const shared_ptr<typename DatagramFace::protocol::socket>& socket,
bool isOnDemand)
: Face(remoteUri, localUri)
, m_socket(socket)
{
setOnDemand(isOnDemand);
m_socket->async_receive(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE), 0,
bind(&DatagramFace<T, U>::handleReceive, this, _1, _2));
}
template<class T, class U>
inline
DatagramFace<T, U>::~DatagramFace()
{
}
template<class T, class U>
inline void
DatagramFace<T, U>::sendInterest(const Interest& interest)
{
this->onSendInterest(interest);
const Block& payload = interest.wireEncode();
m_socket->async_send(boost::asio::buffer(payload.wire(), payload.size()),
bind(&DatagramFace<T, U>::handleSend, this, _1, _2, payload));
// anything else should be done here?
}
template<class T, class U>
inline void
DatagramFace<T, U>::sendData(const Data& data)
{
this->onSendData(data);
const Block& payload = data.wireEncode();
m_socket->async_send(boost::asio::buffer(payload.wire(), payload.size()),
bind(&DatagramFace<T, U>::handleSend, this, _1, _2, payload));
// anything else should be done here?
}
template<class T, class U>
inline void
DatagramFace<T, U>::handleSend(const boost::system::error_code& error,
size_t nBytesSent,
const Block& payload)
// 'payload' is unused; it's needed to retain the underlying Buffer
{
if (error != 0) {
if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
return;
if (!m_socket->is_open()) {
fail("Tunnel closed");
return;
}
NFD_LOG_WARN("[id:" << this->getId()
<< ",uri:" << this->getRemoteUri()
<< "] Send operation failed, closing socket: "
<< error.category().message(error.value()));
closeSocket();
if (error == boost::asio::error::eof) {
fail("Tunnel closed");
}
else {
fail("Send operation failed, closing socket: " +
error.category().message(error.value()));
}
return;
}
NFD_LOG_TRACE("[id:" << this->getId()
<< ",uri:" << this->getRemoteUri()
<< "] Successfully sent: " << nBytesSent << " bytes");
this->getMutableCounters().getNOutBytes() += nBytesSent;
}
template<class T, class U>
inline void
DatagramFace<T, U>::close()
{
if (!m_socket->is_open())
return;
NFD_LOG_INFO("[id:" << this->getId()
<< ",uri:" << this->getRemoteUri()
<< "] Close tunnel");
closeSocket();
fail("Close tunnel");
}
template<class T, class U>
inline void
DatagramFace<T, U>::handleReceive(const boost::system::error_code& error,
size_t nBytesReceived)
{
NFD_LOG_DEBUG("handleReceive: " << nBytesReceived);
receiveDatagram(m_inputBuffer, nBytesReceived, error);
if (m_socket->is_open())
m_socket->async_receive(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE), 0,
bind(&DatagramFace<T, U>::handleReceive, this, _1, _2));
}
template<class T, class U>
inline void
DatagramFace<T, U>::receiveDatagram(const uint8_t* buffer,
size_t nBytesReceived,
const boost::system::error_code& error)
{
if (error != 0 || nBytesReceived == 0) {
if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
return;
// this should be unnecessary, but just in case
if (!m_socket->is_open()) {
fail("Tunnel closed");
return;
}
NFD_LOG_WARN("[id:" << this->getId()
<< ",uri:" << this->getRemoteUri()
<< "] Receive operation failed: "
<< error.category().message(error.value()));
closeSocket();
if (error == boost::asio::error::eof) {
fail("Tunnel closed");
}
else {
fail("Receive operation failed, closing socket: " +
error.category().message(error.value()));
}
return;
}
NFD_LOG_TRACE("[id:" << this->getId()
<< ",uri:" << this->getRemoteUri()
<< "] Received: " << nBytesReceived << " bytes");
this->getMutableCounters().getNInBytes() += nBytesReceived;
Block element;
bool isOk = Block::fromBuffer(buffer, nBytesReceived, element);
if (!isOk)
{
NFD_LOG_WARN("[id:" << this->getId()
<< ",uri:" << this->getRemoteUri()
<< "] Failed to parse incoming packet");
// This message won't extend the face lifetime
return;
}
if (element.size() != nBytesReceived)
{
NFD_LOG_WARN("[id:" << this->getId()
<< ",uri:" << this->getRemoteUri()
<< "] Received datagram size and decoded "
<< "element size don't match");
// This message won't extend the face lifetime
return;
}
if (!this->decodeAndDispatchInput(element))
{
NFD_LOG_WARN("[id:" << this->getId()
<< ",uri:" << this->getRemoteUri()
<< "] Received unrecognized block of type ["
<< element.type() << "]");
// This message won't extend the face lifetime
return;
}
m_hasBeenUsedRecently = true;
}
template<class T, class U>
inline void
DatagramFace<T, U>::keepFaceAliveUntilAllHandlersExecuted(const shared_ptr<Face>& face)
{
}
template<class T, class U>
inline void
DatagramFace<T, U>::closeSocket()
{
NFD_LOG_DEBUG("[id:" << this->getId()
<< ",uri:" << this->getRemoteUri()
<< "] closeSocket");
boost::asio::io_service& io = m_socket->get_io_service();
// use the non-throwing variants and ignore errors, if any
boost::system::error_code error;
m_socket->shutdown(protocol::socket::shutdown_both, error);
m_socket->close(error);
// after this, handlers will be called with an error code
// ensure that the Face object is alive at least until all pending
// handlers are dispatched
io.post(bind(&DatagramFace<T, U>::keepFaceAliveUntilAllHandlersExecuted,
this, this->shared_from_this()));
}
template<class T, class U>
inline void
DatagramFace<T, U>::setOnDemand(bool isOnDemand)
{
Face::setOnDemand(isOnDemand);
}
template<class T, class U>
inline void
DatagramFace<T, U>::resetRecentUsage()
{
m_hasBeenUsedRecently = false;
}
template<class T, class U>
inline bool
DatagramFace<T, U>::hasBeenUsedRecently() const
{
return m_hasBeenUsedRecently;
}
} // namespace nfd
#endif // NFD_DAEMON_FACE_DATAGRAM_FACE_HPP
+252
View File
@@ -0,0 +1,252 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_DATAGRAM_TRANSPORT_HPP
#define NFD_DAEMON_FACE_DATAGRAM_TRANSPORT_HPP
#include "transport.hpp"
#include "core/global-io.hpp"
#include <array>
namespace nfd {
namespace face {
struct Unicast {};
struct Multicast {};
/** \brief Implements Transport for datagram-based protocols.
*
* \tparam Protocol a datagram-based protocol in Boost.Asio
*/
template<class Protocol, class Addressing = Unicast>
class DatagramTransport : public Transport
{
public:
typedef Protocol protocol;
/** \brief Construct datagram transport.
*
* \param socket Protocol-specific socket for the created transport
*/
explicit
DatagramTransport(typename protocol::socket&& socket);
/** \brief Receive datagram, translate buffer into packet, deliver to parent class.
*/
void
receiveDatagram(const uint8_t* buffer, size_t nBytesReceived,
const boost::system::error_code& error);
protected:
virtual void
doClose() DECL_OVERRIDE;
virtual void
doSend(Transport::Packet&& packet) DECL_OVERRIDE;
void
handleSend(const boost::system::error_code& error,
size_t nBytesSent, const Block& payload);
void
handleReceive(const boost::system::error_code& error,
size_t nBytesReceived);
void
processErrorCode(const boost::system::error_code& error);
bool
hasBeenUsedRecently() const;
void
resetRecentUsage();
static EndpointId
makeEndpointId(const typename protocol::endpoint& ep);
protected:
typename protocol::socket m_socket;
typename protocol::endpoint m_sender;
NFD_LOG_INCLASS_DECLARE();
private:
std::array<uint8_t, ndn::MAX_NDN_PACKET_SIZE> m_receiveBuffer;
bool m_hasBeenUsedRecently;
};
template<class T, class U>
DatagramTransport<T, U>::DatagramTransport(typename DatagramTransport::protocol::socket&& socket)
: m_socket(std::move(socket))
, m_hasBeenUsedRecently(false)
{
m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
bind(&DatagramTransport<T, U>::handleReceive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
template<class T, class U>
void
DatagramTransport<T, U>::doClose()
{
NFD_LOG_FACE_TRACE(__func__);
if (m_socket.is_open()) {
// Cancel all outstanding operations and close the socket.
// Use the non-throwing variants and ignore errors, if any.
boost::system::error_code error;
m_socket.cancel(error);
m_socket.close(error);
}
// Ensure that the Transport stays alive at least until
// all pending handlers are dispatched
getGlobalIoService().post([this] {
this->setState(TransportState::CLOSED);
});
}
template<class T, class U>
void
DatagramTransport<T, U>::doSend(Transport::Packet&& packet)
{
NFD_LOG_FACE_TRACE(__func__);
m_socket.async_send(boost::asio::buffer(packet.packet),
bind(&DatagramTransport<T, U>::handleSend, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
packet.packet));
}
template<class T, class U>
void
DatagramTransport<T, U>::receiveDatagram(const uint8_t* buffer, size_t nBytesReceived,
const boost::system::error_code& error)
{
if (error)
return processErrorCode(error);
NFD_LOG_FACE_TRACE("Received: " << nBytesReceived << " bytes");
bool isOk = false;
Block element;
std::tie(isOk, element) = Block::fromBuffer(buffer, nBytesReceived);
if (!isOk) {
NFD_LOG_FACE_WARN("Failed to parse incoming packet");
// This packet won't extend the face lifetime
return;
}
if (element.size() != nBytesReceived) {
NFD_LOG_FACE_WARN("Received datagram size and decoded element size don't match");
// This packet won't extend the face lifetime
return;
}
m_hasBeenUsedRecently = true;
Transport::Packet tp(std::move(element));
tp.remoteEndpoint = makeEndpointId(m_sender);
this->receive(std::move(tp));
}
template<class T, class U>
void
DatagramTransport<T, U>::handleReceive(const boost::system::error_code& error,
size_t nBytesReceived)
{
receiveDatagram(m_receiveBuffer.data(), nBytesReceived, error);
if (m_socket.is_open())
m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
bind(&DatagramTransport<T, U>::handleReceive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
template<class T, class U>
void
DatagramTransport<T, U>::handleSend(const boost::system::error_code& error,
size_t nBytesSent, const Block& payload)
// 'payload' is unused; it's needed to retain the underlying Buffer
{
if (error)
return processErrorCode(error);
NFD_LOG_FACE_TRACE("Successfully sent: " << nBytesSent << " bytes");
}
template<class T, class U>
void
DatagramTransport<T, U>::processErrorCode(const boost::system::error_code& error)
{
NFD_LOG_FACE_TRACE(__func__);
if (getState() == TransportState::CLOSING ||
getState() == TransportState::FAILED ||
getState() == TransportState::CLOSED ||
error == boost::asio::error::operation_aborted)
// transport is shutting down, ignore any errors
return;
if (getPersistency() == ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERMANENT) {
NFD_LOG_FACE_DEBUG("Permanent face ignores error: " << error.message());
return;
}
if (error != boost::asio::error::eof)
NFD_LOG_FACE_WARN("Send or receive operation failed: " << error.message());
this->setState(TransportState::FAILED);
doClose();
}
template<class T, class U>
inline bool
DatagramTransport<T, U>::hasBeenUsedRecently() const
{
return m_hasBeenUsedRecently;
}
template<class T, class U>
inline void
DatagramTransport<T, U>::resetRecentUsage()
{
m_hasBeenUsedRecently = false;
}
template<class T, class U>
inline Transport::EndpointId
DatagramTransport<T, U>::makeEndpointId(const typename protocol::endpoint& ep)
{
return 0;
}
} // namespace face
} // namespace nfd
#endif // NFD_DAEMON_FACE_DATAGRAM_TRANSPORT_HPP
-336
View File
@@ -1,336 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "ethernet-face.hpp"
#include "core/logger.hpp"
#include "core/network-interface.hpp"
#include <pcap/pcap.h>
#include <cstring> // for std::strncpy()
#include <arpa/inet.h> // for htons() and ntohs()
#include <net/ethernet.h> // for struct ether_header
#include <net/if.h> // for struct ifreq
#include <stdio.h> // for snprintf()
#include <sys/ioctl.h> // for ioctl()
#include <unistd.h> // for dup()
#if !defined(PCAP_NETMASK_UNKNOWN)
/*
* Value to pass to pcap_compile() as the netmask if you don't know what
* the netmask is.
*/
#define PCAP_NETMASK_UNKNOWN 0xffffffff
#endif
namespace nfd {
NFD_LOG_INIT("EthernetFace");
EthernetFace::EthernetFace(const shared_ptr<boost::asio::posix::stream_descriptor>& socket,
const shared_ptr<NetworkInterfaceInfo>& interface,
const ethernet::Address& address)
: Face(FaceUri(address), FaceUri::fromDev(interface->name))
, m_socket(socket)
, m_interfaceName(interface->name)
, m_srcAddress(interface->etherAddress)
, m_destAddress(address)
{
NFD_LOG_INFO("Creating ethernet face on " << m_interfaceName << ": "
<< m_srcAddress << " <--> " << m_destAddress);
pcapInit();
int fd = pcap_get_selectable_fd(m_pcap);
if (fd < 0)
throw Error("pcap_get_selectable_fd() failed");
// need to duplicate the fd, otherwise both pcap_close()
// and stream_descriptor::close() will try to close the
// same fd and one of them will fail
m_socket->assign(::dup(fd));
m_interfaceMtu = getInterfaceMtu();
NFD_LOG_DEBUG("[id:" << getId() << ",endpoint:" << m_interfaceName
<< "] Interface MTU is: " << m_interfaceMtu);
char filter[100];
::snprintf(filter, sizeof(filter),
"(ether proto 0x%x) && (ether dst %s) && (not ether src %s)",
ETHERTYPE_NDN,
m_destAddress.toString().c_str(),
m_srcAddress.toString().c_str());
setPacketFilter(filter);
m_socket->async_read_some(boost::asio::null_buffers(),
bind(&EthernetFace::handleRead, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
EthernetFace::~EthernetFace()
{
onFail.clear(); // no reason to call onFail anymore
close();
}
void
EthernetFace::sendInterest(const Interest& interest)
{
onSendInterest(interest);
sendPacket(interest.wireEncode());
}
void
EthernetFace::sendData(const Data& data)
{
onSendData(data);
sendPacket(data.wireEncode());
}
void
EthernetFace::close()
{
if (m_pcap)
{
boost::system::error_code error;
m_socket->close(error); // ignore errors
pcap_close(m_pcap);
m_pcap = 0;
fail("Face closed");
}
}
void
EthernetFace::pcapInit()
{
char errbuf[PCAP_ERRBUF_SIZE];
errbuf[0] = '\0';
m_pcap = pcap_create(m_interfaceName.c_str(), errbuf);
if (!m_pcap)
throw Error("pcap_create(): " + std::string(errbuf));
#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
// Enable "immediate mode", effectively disabling any read buffering in the kernel.
// This corresponds to the BIOCIMMEDIATE ioctl on BSD-like systems (including OS X)
// where libpcap uses a BPF device. On Linux this forces libpcap not to use TPACKET_V3,
// even if the kernel supports it, thus preventing bug #1511.
pcap_set_immediate_mode(m_pcap, 1);
#endif
/// \todo Do not rely on promisc mode, see task #1278
if (!m_destAddress.isBroadcast())
pcap_set_promisc(m_pcap, 1);
if (pcap_activate(m_pcap) < 0)
throw Error("pcap_activate() failed");
if (pcap_set_datalink(m_pcap, DLT_EN10MB) < 0)
throw Error("pcap_set_datalink(): " + std::string(pcap_geterr(m_pcap)));
if (pcap_setdirection(m_pcap, PCAP_D_IN) < 0)
// no need to throw on failure, BPF will filter unwanted packets anyway
NFD_LOG_WARN("pcap_setdirection(): " << pcap_geterr(m_pcap));
}
void
EthernetFace::setPacketFilter(const char* filterString)
{
bpf_program filter;
if (pcap_compile(m_pcap, &filter, filterString, 1, PCAP_NETMASK_UNKNOWN) < 0)
throw Error("pcap_compile(): " + std::string(pcap_geterr(m_pcap)));
int ret = pcap_setfilter(m_pcap, &filter);
pcap_freecode(&filter);
if (ret < 0)
throw Error("pcap_setfilter(): " + std::string(pcap_geterr(m_pcap)));
}
void
EthernetFace::sendPacket(const ndn::Block& block)
{
if (!m_pcap)
{
NFD_LOG_WARN("[id:" << getId() << ",endpoint:" << m_interfaceName
<< "] Trying to send on closed face");
fail("Face closed");
return;
}
/// \todo Fragmentation
if (block.size() > m_interfaceMtu)
{
NFD_LOG_ERROR("[id:" << getId() << ",endpoint:" << m_interfaceName
<< "] Fragmentation not implemented: dropping packet larger than MTU");
return;
}
/// \todo Right now there is no reserve when packet is received, but
/// we should reserve some space at the beginning and at the end
ndn::EncodingBuffer buffer(block);
// pad with zeroes if the payload is too short
if (block.size() < ethernet::MIN_DATA_LEN)
{
static const uint8_t padding[ethernet::MIN_DATA_LEN] = {0};
buffer.appendByteArray(padding, ethernet::MIN_DATA_LEN - block.size());
}
// construct and prepend the ethernet header
static uint16_t ethertype = htons(ETHERTYPE_NDN);
buffer.prependByteArray(reinterpret_cast<const uint8_t*>(&ethertype), ethernet::TYPE_LEN);
buffer.prependByteArray(m_srcAddress.data(), m_srcAddress.size());
buffer.prependByteArray(m_destAddress.data(), m_destAddress.size());
// send the packet
int sent = pcap_inject(m_pcap, buffer.buf(), buffer.size());
if (sent < 0)
{
throw Error("pcap_inject(): " + std::string(pcap_geterr(m_pcap)));
}
else if (static_cast<size_t>(sent) < buffer.size())
{
throw Error("Failed to send packet");
}
NFD_LOG_TRACE("[id:" << getId() << ",endpoint:" << m_interfaceName
<< "] Successfully sent: " << block.size() << " bytes");
this->getMutableCounters().getNOutBytes() += block.size();
}
void
EthernetFace::handleRead(const boost::system::error_code& error, size_t)
{
if (error)
return processErrorCode(error);
pcap_pkthdr* pktHeader;
const uint8_t* packet;
int ret = pcap_next_ex(m_pcap, &pktHeader, &packet);
if (ret < 0)
{
throw Error("pcap_next_ex(): " + std::string(pcap_geterr(m_pcap)));
}
else if (ret == 0)
{
NFD_LOG_WARN("[id:" << getId() << ",endpoint:" << m_interfaceName
<< "] pcap_next_ex() timed out");
}
else
{
size_t length = pktHeader->caplen;
if (length < ethernet::HDR_LEN + ethernet::MIN_DATA_LEN)
throw Error("Received packet is too short");
const ether_header* eh = reinterpret_cast<const ether_header*>(packet);
if (ntohs(eh->ether_type) != ETHERTYPE_NDN)
throw Error("Unrecognized ethertype");
packet += ethernet::HDR_LEN;
length -= ethernet::HDR_LEN;
/// \todo Reserve space in front and at the back
/// of the underlying buffer
Block element;
bool isOk = Block::fromBuffer(packet, length, element);
if (isOk)
{
NFD_LOG_TRACE("[id:" << getId() << ",endpoint:" << m_interfaceName
<< "] Received: " << element.size() << " bytes");
this->getMutableCounters().getNInBytes() += element.size();
if (!decodeAndDispatchInput(element))
{
NFD_LOG_WARN("[id:" << getId() << ",endpoint:" << m_interfaceName
<< "] Received unrecognized block of type " << element.type());
// ignore unknown packet
}
}
else
{
NFD_LOG_WARN("[id:" << getId() << ",endpoint:" << m_interfaceName
<< "] Received block is invalid or too large to process");
}
}
m_socket->async_read_some(boost::asio::null_buffers(),
bind(&EthernetFace::handleRead, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void
EthernetFace::processErrorCode(const boost::system::error_code& error)
{
if (error == boost::system::errc::operation_canceled)
// when socket is closed by someone
return;
if (!m_pcap)
{
fail("Face closed");
return;
}
std::string msg;
if (error == boost::asio::error::eof)
{
msg = "Face closed";
NFD_LOG_INFO("[id:" << getId() << ",endpoint:" << m_interfaceName << "] " << msg);
}
else
{
msg = "Receive operation failed, closing face: " + error.message();
NFD_LOG_WARN("[id:" << getId() << ",endpoint:" << m_interfaceName << "] " << msg);
}
close();
fail(msg);
}
size_t
EthernetFace::getInterfaceMtu() const
{
size_t mtu = ethernet::MAX_DATA_LEN;
#ifdef SIOCGIFMTU
ifreq ifr = boost::initialized_value;
std::strncpy(ifr.ifr_name, m_interfaceName.c_str(), sizeof(ifr.ifr_name) - 1);
if (::ioctl(m_socket->native_handle(), SIOCGIFMTU, &ifr) < 0)
{
NFD_LOG_WARN("[id:" << getId() << ",endpoint:" << m_interfaceName
<< "] Failed to get interface MTU, assuming " << mtu);
}
else
{
mtu = std::min(mtu, static_cast<size_t>(ifr.ifr_mtu));
}
#endif
return mtu;
}
} // namespace nfd
-115
View File
@@ -1,115 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_ETHERNET_FACE_HPP
#define NFD_DAEMON_FACE_ETHERNET_FACE_HPP
#include "config.hpp"
#include "ethernet.hpp"
#include "face.hpp"
#ifndef HAVE_LIBPCAP
#error "Cannot include this file when libpcap is not available"
#endif
// forward declarations
struct pcap;
typedef pcap pcap_t;
namespace nfd {
class NetworkInterfaceInfo;
/**
* \brief Implementation of Face abstraction that uses raw
* Ethernet frames as underlying transport mechanism
*/
class EthernetFace : public Face
{
public:
/**
* \brief EthernetFace-related error
*/
struct Error : public Face::Error
{
Error(const std::string& what) : Face::Error(what) {}
};
EthernetFace(const shared_ptr<boost::asio::posix::stream_descriptor>& socket,
const shared_ptr<NetworkInterfaceInfo>& interface,
const ethernet::Address& address);
virtual
~EthernetFace();
/// send an Interest
virtual void
sendInterest(const Interest& interest);
/// send a Data
virtual void
sendData(const Data& data);
/**
* \brief Close the face
*
* This terminates all communication on the face and cause
* onFail() method event to be invoked
*/
virtual void
close();
private:
void
pcapInit();
void
setPacketFilter(const char* filterString);
void
sendPacket(const ndn::Block& block);
void
handleRead(const boost::system::error_code& error,
size_t nBytesRead);
void
processErrorCode(const boost::system::error_code& error);
size_t
getInterfaceMtu() const;
private:
shared_ptr<boost::asio::posix::stream_descriptor> m_socket;
std::string m_interfaceName;
ethernet::Address m_srcAddress;
ethernet::Address m_destAddress;
size_t m_interfaceMtu;
pcap_t* m_pcap;
};
} // namespace nfd
#endif // NFD_DAEMON_FACE_ETHERNET_FACE_HPP
+38 -49
View File
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -24,72 +24,61 @@
*/
#include "ethernet-factory.hpp"
#include "core/logger.hpp"
#include "core/global-io.hpp"
#include "core/network-interface.hpp"
#include <boost/algorithm/string/predicate.hpp>
#include <pcap/pcap.h>
#include "ethernet-transport.hpp"
#include "generic-link-service.hpp"
namespace nfd {
NFD_LOG_INIT("EthernetFactory");
shared_ptr<EthernetFace>
EthernetFactory::createMulticastFace(const shared_ptr<NetworkInterfaceInfo> &interface,
const ethernet::Address &address)
shared_ptr<Face>
EthernetFactory::createMulticastFace(const NetworkInterfaceInfo& interface,
const ethernet::Address& address)
{
if (!address.isMulticast())
throw Error(address.toString() + " is not a multicast address");
BOOST_THROW_EXCEPTION(Error(address.toString() + " is not a multicast address"));
const std::string& name = interface->name;
shared_ptr<EthernetFace> face = findMulticastFace(name, address);
auto face = findMulticastFace(interface.name, address);
if (face)
return face;
shared_ptr<boost::asio::posix::stream_descriptor> socket =
make_shared<boost::asio::posix::stream_descriptor>(ref(getGlobalIoService()));
face::GenericLinkService::Options opts;
opts.allowFragmentation = true;
opts.allowReassembly = true;
face = make_shared<EthernetFace>(socket, interface, address);
face->onFail += bind(&EthernetFactory::afterFaceFailed,
this, name, address);
m_multicastFaces[std::make_pair(name, address)] = face;
auto linkService = make_unique<face::GenericLinkService>(opts);
auto transport = make_unique<face::EthernetTransport>(interface, address);
face = make_shared<Face>(std::move(linkService), std::move(transport));
auto key = std::make_pair(interface.name, address);
m_multicastFaces[key] = face;
connectFaceClosedSignal(*face, [this, key] { m_multicastFaces.erase(key); });
return face;
}
void
EthernetFactory::afterFaceFailed(const std::string& interfaceName,
const ethernet::Address& address)
EthernetFactory::createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceCreationFailedCallback& onConnectFailed)
{
NFD_LOG_DEBUG("afterFaceFailed: " << interfaceName << "/" << address);
m_multicastFaces.erase(std::make_pair(interfaceName, address));
BOOST_THROW_EXCEPTION(Error("EthernetFactory does not support 'createFace' operation"));
}
shared_ptr<EthernetFace>
std::vector<shared_ptr<const Channel>>
EthernetFactory::getChannels() const
{
return {};
}
shared_ptr<Face>
EthernetFactory::findMulticastFace(const std::string& interfaceName,
const ethernet::Address& address) const
{
MulticastFaceMap::const_iterator i =
m_multicastFaces.find(std::make_pair(interfaceName, address));
auto i = m_multicastFaces.find({interfaceName, address});
if (i != m_multicastFaces.end())
return i->second;
else
return shared_ptr<EthernetFace>();
}
void
EthernetFactory::createFace(const FaceUri& uri,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed)
{
throw Error("EthernetFactory does not support 'createFace' operation");
}
std::list<shared_ptr<const Channel> >
EthernetFactory::getChannels() const
{
return std::list<shared_ptr<const Channel> >();
return nullptr;
}
} // namespace nfd
+26 -35
View File
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -21,18 +21,16 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NFD_DAEMON_FACE_ETHERNET_FACTORY_HPP
#define NFD_DAEMON_FACE_ETHERNET_FACTORY_HPP
#include "ethernet-face.hpp"
#include "protocol-factory.hpp"
#include "core/network-interface.hpp"
namespace nfd {
class NetworkInterfaceInfo;
class EthernetFactory : public ProtocolFactory
{
public:
@@ -49,14 +47,8 @@ public:
}
};
typedef std::map< std::pair<std::string, ethernet::Address>,
shared_ptr<EthernetFace> > MulticastFaceMap;
// from ProtocolFactory
virtual void
createFace(const FaceUri& uri,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed);
typedef std::map<std::pair<std::string, ethernet::Address>,
shared_ptr<Face>> MulticastFaceMap;
/**
* \brief Create an EthernetFace to communicate with the given multicast group
@@ -71,10 +63,10 @@ public:
* \returns always a valid shared pointer to an EthernetFace object,
* an exception will be thrown if the creation fails
*
* \throws EthernetFactory::Error or EthernetFace::Error
* \throws EthernetFactory::Error or EthernetTransport::Error
*/
shared_ptr<EthernetFace>
createMulticastFace(const shared_ptr<NetworkInterfaceInfo>& interface,
shared_ptr<Face>
createMulticastFace(const NetworkInterfaceInfo& interface,
const ethernet::Address& address);
/**
@@ -83,23 +75,24 @@ public:
const MulticastFaceMap&
getMulticastFaces() const;
virtual std::list<shared_ptr<const Channel> >
getChannels() const;
public: // from ProtocolFactory
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceCreationFailedCallback& onConnectFailed) DECL_OVERRIDE;
virtual std::vector<shared_ptr<const Channel>>
getChannels() const DECL_OVERRIDE;
private:
void
afterFaceFailed(const std::string& interfaceName,
const ethernet::Address& address);
/**
* \brief Look up EthernetFace using specified interface and address
*
* \returns shared pointer to the existing EthernetFace object or
* empty shared pointer when such face does not exist
*
* \throws never
* \returns shared pointer to the existing EthernetFace object
* or nullptr when such face does not exist
*/
shared_ptr<EthernetFace>
shared_ptr<Face>
findMulticastFace(const std::string& interfaceName,
const ethernet::Address& address) const;
@@ -107,14 +100,12 @@ private:
MulticastFaceMap m_multicastFaces;
};
inline const EthernetFactory::MulticastFaceMap&
EthernetFactory::getMulticastFaces() const
{
return m_multicastFaces;
}
} // namespace nfd
#endif // NFD_DAEMON_FACE_ETHERNET_FACTORY_HPP
+418
View File
@@ -0,0 +1,418 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ethernet-transport.hpp"
#include "core/global-io.hpp"
#include <pcap/pcap.h>
#include <cerrno> // for errno
#include <cstring> // for memcpy(), strerror(), strncpy()
#include <arpa/inet.h> // for htons() and ntohs()
#include <net/ethernet.h> // for struct ether_header
#include <net/if.h> // for struct ifreq
#include <stdio.h> // for snprintf()
#include <sys/ioctl.h> // for ioctl()
#include <unistd.h> // for dup()
#if defined(__linux__)
#include <netpacket/packet.h> // for struct packet_mreq
#include <sys/socket.h> // for setsockopt()
#endif
#ifdef SIOCADDMULTI
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <net/if_dl.h> // for struct sockaddr_dl
#endif
#endif
#if !defined(PCAP_NETMASK_UNKNOWN)
/*
* Value to pass to pcap_compile() as the netmask if you don't know what
* the netmask is.
*/
#define PCAP_NETMASK_UNKNOWN 0xffffffff
#endif
namespace nfd {
namespace face {
NFD_LOG_INIT("EthernetTransport");
EthernetTransport::EthernetTransport(const NetworkInterfaceInfo& interface,
const ethernet::Address& mcastAddress)
: m_pcap(nullptr, pcap_close)
, m_socket(getGlobalIoService())
, m_srcAddress(interface.etherAddress)
, m_destAddress(mcastAddress)
, m_interfaceName(interface.name)
#if defined(__linux__)
, m_interfaceIndex(interface.index)
#endif
#ifdef _DEBUG
, m_nDropped(0)
#endif
{
this->setLocalUri(FaceUri::fromDev(interface.name));
this->setRemoteUri(FaceUri(mcastAddress));
this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
this->setPersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
this->setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS);
NFD_LOG_FACE_INFO("Creating transport");
pcapInit();
int fd = pcap_get_selectable_fd(m_pcap.get());
if (fd < 0)
BOOST_THROW_EXCEPTION(Error("pcap_get_selectable_fd failed"));
// need to duplicate the fd, otherwise both pcap_close()
// and stream_descriptor::close() will try to close the
// same fd and one of them will fail
m_socket.assign(::dup(fd));
// do this after assigning m_socket because getInterfaceMtu uses it
this->setMtu(getInterfaceMtu());
char filter[110];
// note #1: we cannot use std::snprintf because it's not available
// on some platforms (see #2299)
// note #2: "not vlan" must appear last in the filter expression, or the
// rest of the filter won't work as intended (see pcap-filter(7))
snprintf(filter, sizeof(filter),
"(ether proto 0x%x) && (ether dst %s) && (not ether src %s) && (not vlan)",
ethernet::ETHERTYPE_NDN,
m_destAddress.toString().c_str(),
m_srcAddress.toString().c_str());
setPacketFilter(filter);
if (!m_destAddress.isBroadcast() && !joinMulticastGroup()) {
NFD_LOG_FACE_WARN("Falling back to promiscuous mode");
pcap_set_promisc(m_pcap.get(), 1);
}
m_socket.async_read_some(boost::asio::null_buffers(),
bind(&EthernetTransport::handleRead, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void EthernetTransport::beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
{
if (newPersistency != ndn::nfd::FACE_PERSISTENCY_PERMANENT) {
BOOST_THROW_EXCEPTION(
std::invalid_argument("EthernetTransport supports only FACE_PERSISTENCY_PERMANENT"));
}
}
void EthernetTransport::doSend(Transport::Packet&& packet)
{
NFD_LOG_FACE_TRACE(__func__);
sendPacket(packet.packet);
}
void EthernetTransport::doClose()
{
NFD_LOG_FACE_TRACE(__func__);
if (m_socket.is_open()) {
// Cancel all outstanding operations and close the socket.
// Use the non-throwing variants and ignore errors, if any.
boost::system::error_code error;
m_socket.cancel(error);
m_socket.close(error);
}
m_pcap.reset();
// Ensure that the Transport stays alive at least
// until all pending handlers are dispatched
getGlobalIoService().post([this] {
this->setState(TransportState::CLOSED);
});
}
void
EthernetTransport::pcapInit()
{
char errbuf[PCAP_ERRBUF_SIZE] = {};
m_pcap.reset(pcap_create(m_interfaceName.c_str(), errbuf));
if (!m_pcap)
BOOST_THROW_EXCEPTION(Error("pcap_create: " + std::string(errbuf)));
#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
// Enable "immediate mode", effectively disabling any read buffering in the kernel.
// This corresponds to the BIOCIMMEDIATE ioctl on BSD-like systems (including OS X)
// where libpcap uses a BPF device. On Linux this forces libpcap not to use TPACKET_V3,
// even if the kernel supports it, thus preventing bug #1511.
pcap_set_immediate_mode(m_pcap.get(), 1);
#endif
if (pcap_activate(m_pcap.get()) < 0)
BOOST_THROW_EXCEPTION(Error("pcap_activate failed"));
if (pcap_set_datalink(m_pcap.get(), DLT_EN10MB) < 0)
BOOST_THROW_EXCEPTION(Error("pcap_set_datalink: " + std::string(pcap_geterr(m_pcap.get()))));
if (pcap_setdirection(m_pcap.get(), PCAP_D_IN) < 0)
// no need to throw on failure, BPF will filter unwanted packets anyway
NFD_LOG_FACE_WARN("pcap_setdirection failed: " << pcap_geterr(m_pcap.get()));
}
void
EthernetTransport::setPacketFilter(const char* filterString)
{
bpf_program filter;
if (pcap_compile(m_pcap.get(), &filter, filterString, 1, PCAP_NETMASK_UNKNOWN) < 0)
BOOST_THROW_EXCEPTION(Error("pcap_compile: " + std::string(pcap_geterr(m_pcap.get()))));
int ret = pcap_setfilter(m_pcap.get(), &filter);
pcap_freecode(&filter);
if (ret < 0)
BOOST_THROW_EXCEPTION(Error("pcap_setfilter: " + std::string(pcap_geterr(m_pcap.get()))));
}
bool
EthernetTransport::joinMulticastGroup()
{
#if defined(__linux__)
packet_mreq mr{};
mr.mr_ifindex = m_interfaceIndex;
mr.mr_type = PACKET_MR_MULTICAST;
mr.mr_alen = m_destAddress.size();
std::memcpy(mr.mr_address, m_destAddress.data(), m_destAddress.size());
if (::setsockopt(m_socket.native_handle(), SOL_PACKET,
PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == 0)
return true; // success
NFD_LOG_FACE_WARN("setsockopt(PACKET_ADD_MEMBERSHIP) failed: " << std::strerror(errno));
#endif
#if defined(SIOCADDMULTI)
ifreq ifr{};
std::strncpy(ifr.ifr_name, m_interfaceName.c_str(), sizeof(ifr.ifr_name) - 1);
#if defined(__APPLE__) || defined(__FreeBSD__)
// see bug #2327
using boost::asio::ip::udp;
udp::socket sock(getGlobalIoService(), udp::v4());
int fd = sock.native_handle();
/*
* Differences between Linux and the BSDs (including OS X):
* o BSD does not have ifr_hwaddr; use ifr_addr instead.
* o While OS X seems to accept both AF_LINK and AF_UNSPEC as the address
* family, FreeBSD explicitly requires AF_LINK, so we have to use AF_LINK
* and sockaddr_dl instead of the generic sockaddr structure.
* o BSD's sockaddr (and sockaddr_dl in particular) contains an additional
* field, sa_len (sdl_len), which must be set to the total length of the
* structure, including the length field itself.
* o We do not specify the interface name, thus sdl_nlen is left at 0 and
* LLADDR is effectively the same as sdl_data.
*/
sockaddr_dl* sdl = reinterpret_cast<sockaddr_dl*>(&ifr.ifr_addr);
sdl->sdl_len = sizeof(ifr.ifr_addr);
sdl->sdl_family = AF_LINK;
sdl->sdl_alen = m_destAddress.size();
std::memcpy(LLADDR(sdl), m_destAddress.data(), m_destAddress.size());
static_assert(sizeof(ifr.ifr_addr) >= offsetof(sockaddr_dl, sdl_data) + ethernet::ADDR_LEN,
"ifr_addr in struct ifreq is too small on this platform");
#else
int fd = m_socket.native_handle();
ifr.ifr_hwaddr.sa_family = AF_UNSPEC;
std::memcpy(ifr.ifr_hwaddr.sa_data, m_destAddress.data(), m_destAddress.size());
static_assert(sizeof(ifr.ifr_hwaddr.sa_data) >= ethernet::ADDR_LEN,
"ifr_hwaddr in struct ifreq is too small on this platform");
#endif
if (::ioctl(fd, SIOCADDMULTI, &ifr) == 0)
return true; // success
NFD_LOG_FACE_WARN("ioctl(SIOCADDMULTI) failed: " << std::strerror(errno));
#endif
return false;
}
void
EthernetTransport::sendPacket(const ndn::Block& block)
{
/// \todo Right now there is no reserve when packet is received, but
/// we should reserve some space at the beginning and at the end
ndn::EncodingBuffer buffer(block);
// pad with zeroes if the payload is too short
if (block.size() < ethernet::MIN_DATA_LEN) {
static const uint8_t padding[ethernet::MIN_DATA_LEN] = {};
buffer.appendByteArray(padding, ethernet::MIN_DATA_LEN - block.size());
}
// construct and prepend the ethernet header
static uint16_t ethertype = htons(ethernet::ETHERTYPE_NDN);
buffer.prependByteArray(reinterpret_cast<const uint8_t*>(&ethertype), ethernet::TYPE_LEN);
buffer.prependByteArray(m_srcAddress.data(), m_srcAddress.size());
buffer.prependByteArray(m_destAddress.data(), m_destAddress.size());
// send the packet
int sent = pcap_inject(m_pcap.get(), buffer.buf(), buffer.size());
if (sent < 0)
NFD_LOG_FACE_ERROR("pcap_inject failed: " << pcap_geterr(m_pcap.get()));
else if (static_cast<size_t>(sent) < buffer.size())
NFD_LOG_FACE_ERROR("Failed to send the full frame: bufsize=" << buffer.size() << " sent=" << sent);
else
// print block size because we don't want to count the padding in buffer
NFD_LOG_FACE_TRACE("Successfully sent: " << block.size() << " bytes");
}
void
EthernetTransport::handleRead(const boost::system::error_code& error, size_t)
{
if (error)
return processErrorCode(error);
pcap_pkthdr* header;
const uint8_t* packet;
// read the pcap header and packet data
int ret = pcap_next_ex(m_pcap.get(), &header, &packet);
if (ret < 0)
NFD_LOG_FACE_ERROR("pcap_next_ex failed: " << pcap_geterr(m_pcap.get()));
else if (ret == 0)
NFD_LOG_FACE_WARN("Read timeout");
else
processIncomingPacket(header, packet);
#ifdef _DEBUG
pcap_stat ps{};
ret = pcap_stats(m_pcap.get(), &ps);
if (ret < 0) {
NFD_LOG_FACE_DEBUG("pcap_stats failed: " << pcap_geterr(m_pcap.get()));
}
else if (ret == 0) {
if (ps.ps_drop - m_nDropped > 0)
NFD_LOG_FACE_DEBUG("Detected " << ps.ps_drop - m_nDropped << " dropped packet(s)");
m_nDropped = ps.ps_drop;
}
#endif
m_socket.async_read_some(boost::asio::null_buffers(),
bind(&EthernetTransport::handleRead, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void
EthernetTransport::processIncomingPacket(const pcap_pkthdr* header, const uint8_t* packet)
{
size_t length = header->caplen;
if (length < ethernet::HDR_LEN + ethernet::MIN_DATA_LEN) {
NFD_LOG_FACE_WARN("Received frame is too short (" << length << " bytes)");
return;
}
const ether_header* eh = reinterpret_cast<const ether_header*>(packet);
const ethernet::Address sourceAddress(eh->ether_shost);
// in some cases VLAN-tagged frames may survive the BPF filter,
// make sure we do not process those frames (see #3348)
if (ntohs(eh->ether_type) != ethernet::ETHERTYPE_NDN)
return;
// check that our BPF filter is working correctly
BOOST_ASSERT_MSG(ethernet::Address(eh->ether_dhost) == m_destAddress,
"Received frame addressed to a different multicast group");
BOOST_ASSERT_MSG(sourceAddress != m_srcAddress,
"Received frame sent by this host");
packet += ethernet::HDR_LEN;
length -= ethernet::HDR_LEN;
bool isOk = false;
Block element;
std::tie(isOk, element) = Block::fromBuffer(packet, length);
if (!isOk) {
NFD_LOG_FACE_WARN("Received invalid packet from " << sourceAddress.toString());
return;
}
NFD_LOG_FACE_TRACE("Received: " << element.size() << " bytes from " << sourceAddress.toString());
Transport::Packet tp(std::move(element));
static_assert(sizeof(tp.remoteEndpoint) >= ethernet::ADDR_LEN,
"Transport::Packet::remoteEndpoint is too small");
std::memcpy(&tp.remoteEndpoint, sourceAddress.data(), sourceAddress.size());
this->receive(std::move(tp));
}
void
EthernetTransport::processErrorCode(const boost::system::error_code& error)
{
NFD_LOG_FACE_TRACE(__func__);
if (getState() == TransportState::CLOSING ||
getState() == TransportState::FAILED ||
getState() == TransportState::CLOSED ||
error == boost::asio::error::operation_aborted)
// transport is shutting down, ignore any errors
return;
NFD_LOG_FACE_WARN("Receive operation failed: " << error.message());
}
size_t
EthernetTransport::getInterfaceMtu()
{
#ifdef SIOCGIFMTU
#if defined(__APPLE__) || defined(__FreeBSD__)
// see bug #2328
using boost::asio::ip::udp;
udp::socket sock(getGlobalIoService(), udp::v4());
int fd = sock.native_handle();
#else
int fd = m_socket.native_handle();
#endif
ifreq ifr{};
std::strncpy(ifr.ifr_name, m_interfaceName.c_str(), sizeof(ifr.ifr_name) - 1);
if (::ioctl(fd, SIOCGIFMTU, &ifr) == 0) {
NFD_LOG_FACE_DEBUG("Interface MTU is " << ifr.ifr_mtu);
return static_cast<size_t>(ifr.ifr_mtu);
}
NFD_LOG_FACE_WARN("Failed to get interface MTU: " << std::strerror(errno));
#endif
NFD_LOG_FACE_DEBUG("Assuming default MTU of " << ethernet::MAX_DATA_LEN);
return ethernet::MAX_DATA_LEN;
}
} // namespace face
} // namespace nfd
+155
View File
@@ -0,0 +1,155 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_ETHERNET_TRANSPORT_HPP
#define NFD_DAEMON_FACE_ETHERNET_TRANSPORT_HPP
#include "common.hpp"
#include "transport.hpp"
#include "core/network-interface.hpp"
#ifndef HAVE_LIBPCAP
#error "Cannot include this file when libpcap is not available"
#endif
// forward declarations
struct pcap;
typedef pcap pcap_t;
struct pcap_pkthdr;
namespace nfd {
namespace face {
/**
* \brief A multicast Transport that uses raw Ethernet II frames
*/
class EthernetTransport DECL_CLASS_FINAL : public Transport
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
/**
* @brief Creates an Ethernet-based transport for multicast communication
*/
EthernetTransport(const NetworkInterfaceInfo& interface,
const ethernet::Address& mcastAddress);
protected:
virtual void
beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_FINAL;
virtual void
doClose() DECL_FINAL;
private:
virtual void
doSend(Transport::Packet&& packet) DECL_FINAL;
/**
* @brief Allocates and initializes a libpcap context for live capture
*/
void
pcapInit();
/**
* @brief Installs a BPF filter on the receiving socket
*
* @param filterString string containing the source BPF program
*/
void
setPacketFilter(const char* filterString);
/**
* @brief Enables receiving frames addressed to our MAC multicast group
*
* @return true if successful, false otherwise
*/
bool
joinMulticastGroup();
/**
* @brief Sends the specified TLV block on the network wrapped in an Ethernet frame
*/
void
sendPacket(const ndn::Block& block);
/**
* @brief Receive callback
*/
void
handleRead(const boost::system::error_code& error, size_t nBytesRead);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/**
* @brief Processes an incoming frame as captured by libpcap
*
* @param header pointer to capture metadata
* @param packet pointer to the received frame, including the link-layer header
*/
void
processIncomingPacket(const pcap_pkthdr* header, const uint8_t* packet);
private:
/**
* @brief Handles errors encountered by Boost.Asio on the receive path
*/
void
processErrorCode(const boost::system::error_code& error);
/**
* @brief Returns the MTU of the underlying network interface
*/
size_t
getInterfaceMtu();
private:
unique_ptr<pcap_t, void(*)(pcap_t*)> m_pcap;
boost::asio::posix::stream_descriptor m_socket;
ethernet::Address m_srcAddress;
ethernet::Address m_destAddress;
std::string m_interfaceName;
#if defined(__linux__)
int m_interfaceIndex;
#endif
#ifdef _DEBUG
/// number of packets dropped by the kernel, as reported by libpcap
unsigned int m_nDropped;
#endif
};
} // namespace face
} // namespace nfd
#endif // NFD_DAEMON_FACE_ETHERNET_TRANSPORT_HPP
+49
View File
@@ -0,0 +1,49 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "face-counters.hpp"
namespace nfd {
namespace face {
FaceCounters::FaceCounters(const LinkService::Counters& linkServiceCounters,
const Transport::Counters& transportCounters)
: nInInterests(linkServiceCounters.nInInterests)
, nOutInterests(linkServiceCounters.nOutInterests)
, nInData(linkServiceCounters.nInData)
, nOutData(linkServiceCounters.nOutData)
, nInNacks(linkServiceCounters.nInNacks)
, nOutNacks(linkServiceCounters.nOutNacks)
, nInPackets(transportCounters.nInPackets)
, nOutPackets(transportCounters.nOutPackets)
, nInBytes(transportCounters.nInBytes)
, nOutBytes(transportCounters.nOutBytes)
, m_linkServiceCounters(linkServiceCounters)
, m_transportCounters(transportCounters)
{
}
} // namespace face
} // namespace nfd
+53 -213
View File
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -26,226 +26,66 @@
#ifndef NFD_DAEMON_FACE_FACE_COUNTERS_HPP
#define NFD_DAEMON_FACE_FACE_COUNTERS_HPP
#include "common.hpp"
#include "link-service.hpp"
#include "transport.hpp"
namespace nfd {
namespace face {
/** \brief represents a counter of number of packets
/** \brief gives access to counters provided by Face
*
* This type is a facade that exposes common counters of a Face.
*
* get<T>() can be used to access extended counters provided by
* LinkService or Transport of the Face.
*/
// PacketCounter is noncopyable, because increment should be called on the counter,
// not a copy of it; it's implicitly convertible to uint64_t to be observed
class PacketCounter : noncopyable
class FaceCounters
{
public:
typedef uint64_t rep;
FaceCounters(const LinkService::Counters& linkServiceCounters,
const Transport::Counters& transportCounters);
PacketCounter()
: m_value(0)
{
}
operator rep() const
{
return m_value;
}
PacketCounter&
operator++()
{
++m_value;
return *this;
}
// postfix ++ operator is not provided because it's not needed
void
set(rep value)
{
m_value = value;
}
private:
rep m_value;
};
/** \brief represents a counter of number of bytes
*/
// ByteCounter is noncopyable, because increment should be called on the counter,
// not a copy of it; it's implicitly convertible to uint64_t to be observed
class ByteCounter : noncopyable
{
public:
typedef uint64_t rep;
ByteCounter()
: m_value(0)
{
}
operator rep() const
{
return m_value;
}
ByteCounter&
operator+=(rep n)
{
m_value += n;
return *this;
}
void
set(rep value)
{
m_value = value;
}
private:
rep m_value;
};
/** \brief contains network layer packet counters
*/
class NetworkLayerCounters : noncopyable
{
public:
/// incoming Interest
const PacketCounter&
getNInInterests() const
{
return m_nInInterests;
}
PacketCounter&
getNInInterests()
{
return m_nInInterests;
}
/// incoming Data
const PacketCounter&
getNInDatas() const
{
return m_nInDatas;
}
PacketCounter&
getNInDatas()
{
return m_nInDatas;
}
/// outgoing Interest
const PacketCounter&
getNOutInterests() const
{
return m_nOutInterests;
}
PacketCounter&
getNOutInterests()
{
return m_nOutInterests;
}
/// outgoing Data
const PacketCounter&
getNOutDatas() const
{
return m_nOutDatas;
}
PacketCounter&
getNOutDatas()
{
return m_nOutDatas;
}
protected:
/** \brief copy current obseverations to a struct
* \param recipient an object with set methods for counters
/** \return counters provided by LinkService
* \tparam T LinkService counters type
* \throw std::bad_cast counters type mismatch
*/
template<typename R>
void
copyTo(R& recipient) const
template<typename T>
typename std::enable_if<std::is_base_of<LinkService::Counters, T>::value, const T&>::type
get() const
{
recipient.setNInInterests(this->getNInInterests());
recipient.setNInDatas(this->getNInDatas());
recipient.setNOutInterests(this->getNOutInterests());
recipient.setNOutDatas(this->getNOutDatas());
return dynamic_cast<const T&>(m_linkServiceCounters);
}
/** \return counters provided by Transport
* \tparam T Transport counters type
* \throw std::bad_cast counters type mismatch
*/
template<typename T>
typename std::enable_if<std::is_base_of<Transport::Counters, T>::value, const T&>::type
get() const
{
return dynamic_cast<const T&>(m_transportCounters);
}
public:
const PacketCounter& nInInterests;
const PacketCounter& nOutInterests;
const PacketCounter& nInData;
const PacketCounter& nOutData;
const PacketCounter& nInNacks;
const PacketCounter& nOutNacks;
const PacketCounter& nInPackets;
const PacketCounter& nOutPackets;
const ByteCounter& nInBytes;
const ByteCounter& nOutBytes;
private:
PacketCounter m_nInInterests;
PacketCounter m_nInDatas;
PacketCounter m_nOutInterests;
PacketCounter m_nOutDatas;
};
/** \brief contains link layer byte counters
*/
class LinkLayerCounters : noncopyable
{
public:
/// received bytes
const ByteCounter&
getNInBytes() const
{
return m_nInBytes;
}
ByteCounter&
getNInBytes()
{
return m_nInBytes;
}
/// sent bytes
const ByteCounter&
getNOutBytes() const
{
return m_nOutBytes;
}
ByteCounter&
getNOutBytes()
{
return m_nOutBytes;
}
protected:
/** \brief copy current obseverations to a struct
* \param recipient an object with set methods for counters
*/
template<typename R>
void
copyTo(R& recipient) const
{
recipient.setNInBytes(this->getNInBytes());
recipient.setNOutBytes(this->getNOutBytes());
}
private:
ByteCounter m_nInBytes;
ByteCounter m_nOutBytes;
};
/** \brief contains counters on face
*/
class FaceCounters : public NetworkLayerCounters, public LinkLayerCounters
{
public:
/** \brief copy current obseverations to a struct
* \param recipient an object with set methods for counters
*/
template<typename R>
void
copyTo(R& recipient) const
{
this->NetworkLayerCounters::copyTo(recipient);
this->LinkLayerCounters::copyTo(recipient);
}
const LinkService::Counters& m_linkServiceCounters;
const Transport::Counters& m_transportCounters;
};
} // namespace face
} // namespace nfd
#endif // NFD_DAEMON_FACE_FACE_COUNTERS_HPP
+93
View File
@@ -0,0 +1,93 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_FACE_LOG_HPP
#define NFD_DAEMON_FACE_FACE_LOG_HPP
#include "core/logger.hpp"
namespace nfd {
namespace face {
/** \brief for internal use by FaceLogging macros
*
* FaceLogHelper wraps a Face, LinkService, or Transport object.
*
* std::ostream& operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
* should be specialized to print "[id=888,local=scheme://local/uri,remote=scheme://remote/uri] "
* which appears as part of the log message.
*/
template<typename T>
class FaceLogHelper
{
public:
explicit
FaceLogHelper(const T& obj1)
: obj(obj1)
{
}
public:
const T& obj;
};
/** \defgroup FaceLogging Face logging macros
*
* These macros augment the log message with some face-specific information,
* such as the face ID, that are useful to distinguish which face produced the
* message. It is strongly recommended to use these macros instead of the
* generic ones for all logging inside Face, LinkService, Transport subclasses.
* @{
*/
#define NFD_LOG_FACE(level, msg) NFD_LOG_##level( \
::nfd::face::FaceLogHelper< \
typename std::remove_cv< \
typename std::remove_reference<decltype(*this)>::type \
>::type \
>(*this) \
<< msg)
/** \brief Log a message at TRACE level */
#define NFD_LOG_FACE_TRACE(msg) NFD_LOG_FACE(TRACE, msg)
/** \brief Log a message at DEBUG level */
#define NFD_LOG_FACE_DEBUG(msg) NFD_LOG_FACE(DEBUG, msg)
/** \brief Log a message at INFO level */
#define NFD_LOG_FACE_INFO(msg) NFD_LOG_FACE(INFO, msg)
/** \brief Log a message at WARN level */
#define NFD_LOG_FACE_WARN(msg) NFD_LOG_FACE(WARN, msg)
/** \brief Log a message at ERROR level */
#define NFD_LOG_FACE_ERROR(msg) NFD_LOG_FACE(ERROR, msg)
/** @} */
} // namespace face
} // namespace nfd
#endif // NFD_DAEMON_FACE_FACE_LOG_HPP
+27 -115
View File
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -24,120 +24,32 @@
*/
#include "face.hpp"
#include "face-flags.hpp"
#include "core/logger.hpp"
namespace nfd {
namespace face {
Face::Face(const FaceUri& remoteUri, const FaceUri& localUri, bool isLocal)
: m_id(INVALID_FACEID)
, m_isLocal(isLocal)
, m_remoteUri(remoteUri)
, m_localUri(localUri)
, m_isOnDemand(false)
, m_isFailed(false)
Face::Face(unique_ptr<LinkService> service, unique_ptr<Transport> transport)
: afterReceiveInterest(service->afterReceiveInterest)
, afterReceiveData(service->afterReceiveData)
, afterReceiveNack(service->afterReceiveNack)
, afterStateChange(transport->afterStateChange)
, m_id(INVALID_FACEID)
, m_service(std::move(service))
, m_transport(std::move(transport))
, m_counters(m_service->getCounters(), m_transport->getCounters())
{
onReceiveInterest += bind(&PacketCounter::operator++, &m_counters.getNInInterests());
onReceiveData += bind(&PacketCounter::operator++, &m_counters.getNInDatas());
onSendInterest += bind(&PacketCounter::operator++, &m_counters.getNOutInterests());
onSendData += bind(&PacketCounter::operator++, &m_counters.getNOutDatas());
m_service->setFaceAndTransport(*this, *m_transport);
m_transport->setFaceAndLinkService(*this, *m_service);
}
Face::~Face()
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<Face>& flh)
{
const Face& face = flh.obj;
os << "[id=" << face.getId() << ",local=" << face.getLocalUri() <<
",remote=" << face.getRemoteUri() << "] ";
return os;
}
FaceId
Face::getId() const
{
return m_id;
}
// this method is private and should be used only by the FaceTable
void
Face::setId(FaceId faceId)
{
m_id = faceId;
}
void
Face::setDescription(const std::string& description)
{
m_description = description;
}
const std::string&
Face::getDescription() const
{
return m_description;
}
bool
Face::isMultiAccess() const
{
return false;
}
bool
Face::isUp() const
{
return true;
}
bool
Face::decodeAndDispatchInput(const Block& element)
{
try {
/// \todo Ensure lazy field decoding process
if (element.type() == tlv::Interest)
{
shared_ptr<Interest> i = make_shared<Interest>();
i->wireDecode(element);
this->onReceiveInterest(*i);
}
else if (element.type() == tlv::Data)
{
shared_ptr<Data> d = make_shared<Data>();
d->wireDecode(element);
this->onReceiveData(*d);
}
else
return false;
return true;
}
catch (tlv::Error&) {
return false;
}
}
void
Face::fail(const std::string& reason)
{
if (m_isFailed) {
return;
}
m_isFailed = true;
this->onFail(reason);
this->onFail.clear();
}
ndn::nfd::FaceStatus
Face::getFaceStatus() const
{
ndn::nfd::FaceStatus status;
status.setFaceId(getId())
.setRemoteUri(getRemoteUri().toString())
.setLocalUri(getLocalUri().toString())
.setFlags(getFaceFlags(*this));
this->getCounters().copyTo(status);
return status;
}
} //namespace nfd
} // namespace face
} // namespace nfd
+238 -178
View File
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -23,190 +23,265 @@
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_FACE_HPP
#define NFD_DAEMON_FACE_FACE_HPP
#ifndef NFD_DAEMON_FACE_HPP
#define NFD_DAEMON_FACE_HPP
#include "common.hpp"
#include "core/event-emitter.hpp"
#include "core/face-uri.hpp"
#include "transport.hpp"
#include "link-service.hpp"
#include "face-counters.hpp"
#include <ndn-cxx/management/nfd-face-status.hpp>
#include "face-log.hpp"
namespace nfd {
namespace face {
/** \class FaceId
* \brief identifies a face
/** \brief identifies a face
*/
typedef int FaceId;
typedef uint64_t FaceId;
/// indicates an invalid FaceId
const FaceId INVALID_FACEID = -1;
const FaceId INVALID_FACEID = 0;
/// identifies the InternalFace used in management
const FaceId FACEID_INTERNAL_FACE = 1;
/// identifies a packet comes from the ContentStore, in LocalControlHeader incomingFaceId
/// identifies a packet comes from the ContentStore
const FaceId FACEID_CONTENT_STORE = 254;
/// identifies the NullFace that drops every packet
const FaceId FACEID_NULL = 255;
/// upper bound of reserved FaceIds
const FaceId FACEID_RESERVED_MAX = 255;
/// pratical limit of packet size in octets
const size_t MAX_NDN_PACKET_SIZE = 8800;
/** \brief represents a face
/** \brief indicates the state of a face
*/
class Face : noncopyable, public enable_shared_from_this<Face>
typedef TransportState FaceState;
/** \brief generalization of a network interface
*
* A face generalizes a network interface.
* It provides best-effort network-layer packet delivery services
* on a physical interface, an overlay tunnel, or a link to a local application.
*
* A face combines two parts: LinkService and Transport.
* Transport is the lower part, which provides best-effort TLV block deliveries.
* LinkService is the upper part, which translates between network-layer packets
* and TLV blocks, and may provide additional services such as fragmentation and reassembly.
*/
class Face
#ifndef WITH_TESTS
DECL_CLASS_FINAL
#endif
: public enable_shared_from_this<Face>, noncopyable
{
public:
/**
* \brief Face-related error
Face(unique_ptr<LinkService> service, unique_ptr<Transport> transport);
LinkService*
getLinkService();
Transport*
getTransport();
public: // upper interface connected to forwarding
/** \brief sends Interest on Face
*/
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
void
sendInterest(const Interest& interest);
Face(const FaceUri& remoteUri, const FaceUri& localUri, bool isLocal = false);
virtual
~Face();
/// fires when an Interest is received
EventEmitter<Interest> onReceiveInterest;
/// fires when a Data is received
EventEmitter<Data> onReceiveData;
/// fires when an Interest is sent out
EventEmitter<Interest> onSendInterest;
/// fires when a Data is sent out
EventEmitter<Data> onSendData;
/// fires when face disconnects or fails to perform properly
EventEmitter<std::string/*reason*/> onFail;
/// send an Interest
virtual void
sendInterest(const Interest& interest) = 0;
/// send a Data
virtual void
sendData(const Data& data) = 0;
/** \brief Close the face
*
* This terminates all communication on the face and cause
* onFail() method event to be invoked
/** \brief sends Data on Face
*/
virtual void
close() = 0;
void
sendData(const Data& data);
public: // attributes
/** \brief sends Nack on Face
*/
void
sendNack(const lp::Nack& nack);
/** \brief signals on Interest received
*/
signal::Signal<LinkService, Interest>& afterReceiveInterest;
/** \brief signals on Data received
*/
signal::Signal<LinkService, Data>& afterReceiveData;
/** \brief signals on Nack received
*/
signal::Signal<LinkService, lp::Nack>& afterReceiveNack;
public: // static properties
/** \return face ID
*/
FaceId
getId() const;
/** \brief Set the description
/** \brief sets face ID
* \note Normally, this should only be invoked by FaceTable.
*/
void
setId(FaceId id);
/** \return a FaceUri representing local endpoint
*/
FaceUri
getLocalUri() const;
/** \return a FaceUri representing remote endpoint
*/
FaceUri
getRemoteUri() const;
/** \return whether face is local or non-local for scope control purpose
*/
ndn::nfd::FaceScope
getScope() const;
/** \return face persistency setting
*/
ndn::nfd::FacePersistency
getPersistency() const;
/** \brief changes face persistency setting
*/
void
setPersistency(ndn::nfd::FacePersistency persistency);
/** \return whether face is point-to-point or multi-access
*/
ndn::nfd::LinkType
getLinkType() const;
public: // dynamic properties
/** \return face state
*/
FaceState
getState() const;
/** \brief signals after face state changed
*/
signal::Signal<Transport, FaceState/*old*/, FaceState/*new*/>& afterStateChange;
/** \return expiration time of the face
* \retval time::steady_clock::TimePoint::max() the face has an indefinite lifetime
*/
time::steady_clock::TimePoint
getExpirationTime() const;
/** \brief request the face to be closed
*
* This is typically invoked by mgmt on set description command
*/
virtual void
setDescription(const std::string& description);
/// Get the description
virtual const std::string&
getDescription() const;
/** \brief Get whether face is connected to a local app
*/
bool
isLocal() const;
/** \brief Get whether packets sent this Face may reach multiple peers
* This operation is effective only if face is in UP or DOWN state,
* otherwise it has no effect.
* The face changes state to CLOSING, and performs cleanup procedure.
* The state will be changed to CLOSED when cleanup is complete, which may
* happen synchronously or asynchronously.
*
* In this base class this property is always false.
* \warning the face must not be deallocated until its state changes to CLOSED
*/
virtual bool
isMultiAccess() const;
/** \brief Get whether underlying communication is up
*
* In this base class this property is always true.
*/
virtual bool
isUp() const;
/** \brief Get whether face is created on demand or explicitly via FaceManagement protocol
*/
bool
isOnDemand() const;
void
close();
const FaceCounters&
getCounters() const;
/** \return a FaceUri that represents the remote endpoint
*/
const FaceUri&
getRemoteUri() const;
/** \return a FaceUri that represents the local endpoint (NFD side)
*/
const FaceUri&
getLocalUri() const;
/** \return FaceStatus data structure filled with the current Face status
*/
virtual ndn::nfd::FaceStatus
getFaceStatus() const;
protected:
// this is a non-virtual method
bool
decodeAndDispatchInput(const Block& element);
FaceCounters&
getMutableCounters();
void
setOnDemand(bool isOnDemand);
/** \brief fail the face and raise onFail event if it's UP; otherwise do nothing
*/
void
fail(const std::string& reason);
private:
void
setId(FaceId faceId);
private:
FaceId m_id;
std::string m_description;
bool m_isLocal; // for scoping purposes
unique_ptr<LinkService> m_service;
unique_ptr<Transport> m_transport;
FaceCounters m_counters;
FaceUri m_remoteUri;
FaceUri m_localUri;
bool m_isOnDemand;
bool m_isFailed;
// allow setting FaceId
friend class FaceTable;
};
inline bool
Face::isLocal() const
inline LinkService*
Face::getLinkService()
{
return m_isLocal;
return m_service.get();
}
inline Transport*
Face::getTransport()
{
return m_transport.get();
}
inline void
Face::sendInterest(const Interest& interest)
{
m_service->sendInterest(interest);
}
inline void
Face::sendData(const Data& data)
{
m_service->sendData(data);
}
inline void
Face::sendNack(const lp::Nack& nack)
{
m_service->sendNack(nack);
}
inline FaceId
Face::getId() const
{
return m_id;
}
inline void
Face::setId(FaceId id)
{
m_id = id;
}
inline FaceUri
Face::getLocalUri() const
{
return m_transport->getLocalUri();
}
inline FaceUri
Face::getRemoteUri() const
{
return m_transport->getRemoteUri();
}
inline ndn::nfd::FaceScope
Face::getScope() const
{
return m_transport->getScope();
}
inline ndn::nfd::FacePersistency
Face::getPersistency() const
{
return m_transport->getPersistency();
}
inline void
Face::setPersistency(ndn::nfd::FacePersistency persistency)
{
return m_transport->setPersistency(persistency);
}
inline ndn::nfd::LinkType
Face::getLinkType() const
{
return m_transport->getLinkType();
}
inline FaceState
Face::getState() const
{
return m_transport->getState();
}
inline time::steady_clock::TimePoint
Face::getExpirationTime() const
{
return m_transport->getExpirationTime();
}
inline void
Face::close()
{
m_transport->close();
}
inline const FaceCounters&
@@ -215,36 +290,21 @@ Face::getCounters() const
return m_counters;
}
inline FaceCounters&
Face::getMutableCounters()
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<Face>& flh);
template<typename T>
typename std::enable_if<std::is_base_of<Face, T>::value, std::ostream&>::type
operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
{
return m_counters;
return os << FaceLogHelper<Face>(flh.obj);
}
inline const FaceUri&
Face::getRemoteUri() const
{
return m_remoteUri;
}
} // namespace face
inline const FaceUri&
Face::getLocalUri() const
{
return m_localUri;
}
inline void
Face::setOnDemand(bool isOnDemand)
{
m_isOnDemand = isOnDemand;
}
inline bool
Face::isOnDemand() const
{
return m_isOnDemand;
}
using face::FaceId;
using face::Face;
} // namespace nfd
#endif // NFD_DAEMON_FACE_FACE_HPP
#endif // NFD_DAEMON_FACE_HPP
+313
View File
@@ -0,0 +1,313 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "generic-link-service.hpp"
namespace nfd {
namespace face {
NFD_LOG_INIT("GenericLinkService");
GenericLinkServiceCounters::GenericLinkServiceCounters(const LpReassembler& reassembler)
: nReassembling(reassembler)
{
}
GenericLinkService::Options::Options()
: allowLocalFields(false)
, allowFragmentation(false)
, allowReassembly(false)
{
}
GenericLinkService::GenericLinkService(const GenericLinkService::Options& options)
: GenericLinkServiceCounters(m_reassembler)
, m_options(options)
, m_fragmenter(m_options.fragmenterOptions, this)
, m_reassembler(m_options.reassemblerOptions, this)
, m_lastSeqNo(-2)
{
m_reassembler.beforeTimeout.connect(bind([this] { ++this->nReassemblyTimeouts; }));
}
void
GenericLinkService::doSendInterest(const Interest& interest)
{
lp::Packet lpPacket(interest.wireEncode());
if (m_options.allowLocalFields) {
encodeLocalFields(interest, lpPacket);
}
this->sendNetPacket(std::move(lpPacket));
}
void
GenericLinkService::doSendData(const Data& data)
{
lp::Packet lpPacket(data.wireEncode());
if (m_options.allowLocalFields) {
encodeLocalFields(data, lpPacket);
}
this->sendNetPacket(std::move(lpPacket));
}
void
GenericLinkService::doSendNack(const lp::Nack& nack)
{
lp::Packet lpPacket(nack.getInterest().wireEncode());
lpPacket.add<lp::NackField>(nack.getHeader());
if (m_options.allowLocalFields) {
encodeLocalFields(nack, lpPacket);
}
this->sendNetPacket(std::move(lpPacket));
}
void
GenericLinkService::encodeLocalFields(const ndn::TagHost& netPkt, lp::Packet& lpPacket)
{
shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = netPkt.getTag<lp::IncomingFaceIdTag>();
if (incomingFaceIdTag != nullptr) {
lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
}
}
void
GenericLinkService::sendNetPacket(lp::Packet&& pkt)
{
std::vector<lp::Packet> frags;
const ssize_t mtu = this->getTransport()->getMtu();
if (m_options.allowFragmentation && mtu != MTU_UNLIMITED) {
bool isOk = false;
std::tie(isOk, frags) = m_fragmenter.fragmentPacket(pkt, mtu);
if (!isOk) {
// fragmentation failed (warning is logged by LpFragmenter)
++this->nFragmentationErrors;
return;
}
}
else {
frags.push_back(pkt);
}
if (frags.size() > 1) {
// sequence is needed only if packet is fragmented
this->assignSequences(frags);
}
else {
// even if indexed fragmentation is enabled, the fragmenter should not
// fragment the packet if it can fit in MTU
BOOST_ASSERT(frags.size() > 0);
BOOST_ASSERT(!frags.front().has<lp::FragIndexField>());
BOOST_ASSERT(!frags.front().has<lp::FragCountField>());
}
for (const lp::Packet& frag : frags) {
Transport::Packet tp(frag.wireEncode());
if (mtu != MTU_UNLIMITED && tp.packet.size() > static_cast<size_t>(mtu)) {
++this->nOutOverMtu;
NFD_LOG_FACE_WARN("attempt to send packet over MTU limit");
continue;
}
this->sendPacket(std::move(tp));
}
}
void
GenericLinkService::assignSequence(lp::Packet& pkt)
{
pkt.set<lp::SequenceField>(++m_lastSeqNo);
}
void
GenericLinkService::assignSequences(std::vector<lp::Packet>& pkts)
{
std::for_each(pkts.begin(), pkts.end(), bind(&GenericLinkService::assignSequence, this, _1));
}
void
GenericLinkService::doReceivePacket(Transport::Packet&& packet)
{
try {
lp::Packet pkt(packet.packet);
if (!pkt.has<lp::FragmentField>()) {
NFD_LOG_FACE_TRACE("received IDLE packet: DROP");
return;
}
if ((pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) &&
!m_options.allowReassembly) {
NFD_LOG_FACE_WARN("received fragment, but reassembly disabled: DROP");
return;
}
bool isReassembled = false;
Block netPkt;
lp::Packet firstPkt;
std::tie(isReassembled, netPkt, firstPkt) = m_reassembler.receiveFragment(packet.remoteEndpoint,
pkt);
if (isReassembled) {
this->decodeNetPacket(netPkt, firstPkt);
}
}
catch (const tlv::Error& e) {
++this->nInLpInvalid;
NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
}
}
void
GenericLinkService::decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt)
{
try {
switch (netPkt.type()) {
case tlv::Interest:
if (firstPkt.has<lp::NackField>()) {
this->decodeNack(netPkt, firstPkt);
}
else {
this->decodeInterest(netPkt, firstPkt);
}
break;
case tlv::Data:
this->decodeData(netPkt, firstPkt);
break;
default:
++this->nInNetInvalid;
NFD_LOG_FACE_WARN("unrecognized network-layer packet TLV-TYPE " << netPkt.type() << ": DROP");
return;
}
}
catch (const tlv::Error& e) {
++this->nInNetInvalid;
NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
}
}
void
GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt)
{
BOOST_ASSERT(netPkt.type() == tlv::Interest);
BOOST_ASSERT(!firstPkt.has<lp::NackField>());
// forwarding expects Interest to be created with make_shared
auto interest = make_shared<Interest>(netPkt);
if (firstPkt.has<lp::NextHopFaceIdField>()) {
if (m_options.allowLocalFields) {
interest->setTag(make_shared<lp::NextHopFaceIdTag>(firstPkt.get<lp::NextHopFaceIdField>()));
}
else {
NFD_LOG_FACE_WARN("received NextHopFaceId, but local fields disabled: DROP");
return;
}
}
if (firstPkt.has<lp::CachePolicyField>()) {
++this->nInNetInvalid;
NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
return;
}
if (firstPkt.has<lp::IncomingFaceIdField>()) {
NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
}
this->receiveInterest(*interest);
}
void
GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt)
{
BOOST_ASSERT(netPkt.type() == tlv::Data);
// forwarding expects Data to be created with make_shared
auto data = make_shared<Data>(netPkt);
if (firstPkt.has<lp::NackField>()) {
++this->nInNetInvalid;
NFD_LOG_FACE_WARN("received Nack with Data: DROP");
return;
}
if (firstPkt.has<lp::NextHopFaceIdField>()) {
++this->nInNetInvalid;
NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
return;
}
if (firstPkt.has<lp::CachePolicyField>()) {
if (m_options.allowLocalFields) {
// In case of an invalid CachePolicyType, get<lp::CachePolicyField> will throw,
// so it's unnecessary to check here.
data->setTag(make_shared<lp::CachePolicyTag>(firstPkt.get<lp::CachePolicyField>()));
}
else {
NFD_LOG_FACE_WARN("received CachePolicy, but local fields disabled: IGNORE");
}
}
if (firstPkt.has<lp::IncomingFaceIdField>()) {
NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
}
this->receiveData(*data);
}
void
GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt)
{
BOOST_ASSERT(netPkt.type() == tlv::Interest);
BOOST_ASSERT(firstPkt.has<lp::NackField>());
lp::Nack nack((Interest(netPkt)));
nack.setHeader(firstPkt.get<lp::NackField>());
if (firstPkt.has<lp::NextHopFaceIdField>()) {
++this->nInNetInvalid;
NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
return;
}
if (firstPkt.has<lp::CachePolicyField>()) {
++this->nInNetInvalid;
NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
return;
}
if (firstPkt.has<lp::IncomingFaceIdField>()) {
NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
}
this->receiveNack(nack);
}
} // namespace face
} // namespace nfd
+250
View File
@@ -0,0 +1,250 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_GENERIC_LINK_SERVICE_HPP
#define NFD_DAEMON_FACE_GENERIC_LINK_SERVICE_HPP
#include "common.hpp"
#include "core/logger.hpp"
#include "link-service.hpp"
#include "lp-fragmenter.hpp"
#include "lp-reassembler.hpp"
namespace nfd {
namespace face {
/** \brief counters provided by GenericLinkService
* \note The type name 'GenericLinkServiceCounters' is implementation detail.
* Use 'GenericLinkService::Counters' in public API.
*/
class GenericLinkServiceCounters : public virtual LinkService::Counters
{
public:
explicit
GenericLinkServiceCounters(const LpReassembler& reassembler);
/** \brief count of failed fragmentations
*/
PacketCounter nFragmentationErrors;
/** \brief count of outgoing LpPackets dropped due to exceeding MTU limit
*
* If this counter is non-zero, the operator should enable fragmentation.
*/
PacketCounter nOutOverMtu;
/** \brief count of invalid LpPackets dropped before reassembly
*/
PacketCounter nInLpInvalid;
/** \brief count of network-layer packets currently being reassembled
*/
SizeCounter<LpReassembler> nReassembling;
/** \brief count of dropped partial network-layer packets due to reassembly timeout
*/
PacketCounter nReassemblyTimeouts;
/** \brief count of invalid reassembled network-layer packets dropped
*/
PacketCounter nInNetInvalid;
};
/** \brief GenericLinkService is a LinkService that implements the NDNLPv2 protocol
* \sa http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
*/
class GenericLinkService : public LinkService
, protected virtual GenericLinkServiceCounters
{
public:
/** \brief Options that control the behavior of GenericLinkService
*/
class Options
{
public:
Options();
public:
/** \brief enables encoding of IncomingFaceId, and decoding of NextHopFaceId and CachePolicy
*/
bool allowLocalFields;
/** \brief enables fragmentation
*/
bool allowFragmentation;
/** \brief options for fragmentation
*/
LpFragmenter::Options fragmenterOptions;
/** \brief enables reassembly
*/
bool allowReassembly;
/** \brief options for reassembly
*/
LpReassembler::Options reassemblerOptions;
};
/** \brief counters provided by GenericLinkService
*/
typedef GenericLinkServiceCounters Counters;
explicit
GenericLinkService(const Options& options = Options());
/** \brief get Options used by GenericLinkService
*/
const Options&
getOptions() const;
/** \brief sets Options used by GenericLinkService
*/
void
setOptions(const Options& options);
virtual const Counters&
getCounters() const DECL_OVERRIDE;
private: // send path
/** \brief send Interest
*/
void
doSendInterest(const Interest& interest) DECL_OVERRIDE;
/** \brief send Data
*/
void
doSendData(const Data& data) DECL_OVERRIDE;
/** \brief send Nack
*/
void
doSendNack(const ndn::lp::Nack& nack) DECL_OVERRIDE;
/** \brief encode local fields from tags onto outgoing LpPacket
* \param pkt LpPacket containing a complete network layer packet
*/
static void
encodeLocalFields(const ndn::TagHost& netPkt, lp::Packet& lpPacket);
/** \brief send a complete network layer packet
* \param pkt LpPacket containing a complete network layer packet
*/
void
sendNetPacket(lp::Packet&& pkt);
/** \brief assign a sequence number to an LpPacket
*/
void
assignSequence(lp::Packet& pkt);
/** \brief assign consecutive sequence numbers to LpPackets
*/
void
assignSequences(std::vector<lp::Packet>& pkts);
private: // receive path
/** \brief receive Packet from Transport
*/
void
doReceivePacket(Transport::Packet&& packet) DECL_OVERRIDE;
/** \brief decode incoming network-layer packet
* \param netPkt reassembled network-layer packet
* \param firstPkt LpPacket of first fragment
*
* If decoding is successful, a receive signal is emitted;
* otherwise, a warning is logged.
*/
void
decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt);
/** \brief decode incoming Interest
* \param netPkt reassembled network-layer packet; TLV-TYPE must be Interest
* \param firstPkt LpPacket of first fragment; must not have Nack field
*
* If decoding is successful, receiveInterest signal is emitted;
* otherwise, a warning is logged.
*
* \throw tlv::Error parse error in an LpHeader field
*/
void
decodeInterest(const Block& netPkt, const lp::Packet& firstPkt);
/** \brief decode incoming Interest
* \param netPkt reassembled network-layer packet; TLV-TYPE must be Data
* \param firstPkt LpPacket of first fragment
*
* If decoding is successful, receiveData signal is emitted;
* otherwise, a warning is logged.
*
* \throw tlv::Error parse error in an LpHeader field
*/
void
decodeData(const Block& netPkt, const lp::Packet& firstPkt);
/** \brief decode incoming Interest
* \param netPkt reassembled network-layer packet; TLV-TYPE must be Interest
* \param firstPkt LpPacket of first fragment; must have Nack field
*
* If decoding is successful, receiveNack signal is emitted;
* otherwise, a warning is logged.
*
* \throw tlv::Error parse error in an LpHeader field
*/
void
decodeNack(const Block& netPkt, const lp::Packet& firstPkt);
private:
Options m_options;
LpFragmenter m_fragmenter;
LpReassembler m_reassembler;
lp::Sequence m_lastSeqNo;
};
inline const GenericLinkService::Options&
GenericLinkService::getOptions() const
{
return m_options;
}
inline void
GenericLinkService::setOptions(const GenericLinkService::Options& options)
{
m_options = options;
}
inline const GenericLinkService::Counters&
GenericLinkService::getCounters() const
{
return *this;
}
} // namespace face
} // namespace nfd
#endif // NFD_DAEMON_FACE_GENERIC_LINK_SERVICE_HPP
+53
View File
@@ -0,0 +1,53 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "internal-face.hpp"
#include "generic-link-service.hpp"
#include "internal-transport.hpp"
#include "core/global-io.hpp"
namespace nfd {
namespace face {
std::tuple<shared_ptr<Face>, shared_ptr<ndn::Face>>
makeInternalFace(ndn::KeyChain& clientKeyChain)
{
GenericLinkService::Options serviceOpts;
serviceOpts.allowLocalFields = true;
auto face = make_shared<Face>(make_unique<GenericLinkService>(serviceOpts),
make_unique<InternalForwarderTransport>());
auto forwarderTransport = static_cast<InternalForwarderTransport*>(face->getTransport());
auto clientTransport = make_shared<InternalClientTransport>();
clientTransport->connectToForwarder(forwarderTransport);
auto clientFace = make_shared<ndn::Face>(clientTransport, getGlobalIoService(), clientKeyChain);
return std::make_tuple(face, clientFace);
}
} // namespace face
} // namespace nfd
+51
View File
@@ -0,0 +1,51 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_INTERNAL_FACE_HPP
#define NFD_DAEMON_FACE_INTERNAL_FACE_HPP
#include "face.hpp"
#include <ndn-cxx/face.hpp>
namespace nfd {
namespace face {
/** \brief make a pair of forwarder-side face and client-side face
* that are connected with each other
*
* Network-layer packets sent by one face will be received by the other face
* after io.poll().
*
* \param clientKeyChain A KeyChain used by client-side face to sign
* prefix registration commands.
* \return a forwarder-side face and a client-side face connected with each other
*/
std::tuple<shared_ptr<Face>, shared_ptr<ndn::Face>>
makeInternalFace(ndn::KeyChain& clientKeyChain);
} // namespace face
} // namespace nfd
#endif // NFD_DAEMON_FACE_INTERNAL_FACE_HPP
+139
View File
@@ -0,0 +1,139 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "internal-transport.hpp"
#include "core/global-io.hpp"
namespace nfd {
namespace face {
NFD_LOG_INCLASS_DEFINE(InternalForwarderTransport, "InternalForwarderTransport");
InternalForwarderTransport::InternalForwarderTransport(
const FaceUri& localUri, const FaceUri& remoteUri,
ndn::nfd::FaceScope scope, ndn::nfd::LinkType linkType)
{
this->setLocalUri(localUri);
this->setRemoteUri(remoteUri);
this->setScope(scope);
this->setPersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
this->setLinkType(linkType);
this->setMtu(MTU_UNLIMITED);
NFD_LOG_FACE_INFO("Creating transport");
}
void
InternalForwarderTransport::beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
{
if (newPersistency != ndn::nfd::FACE_PERSISTENCY_PERMANENT) {
BOOST_THROW_EXCEPTION(
std::invalid_argument("InternalForwarderTransport supports only FACE_PERSISTENCY_PERMANENT"));
}
}
void
InternalForwarderTransport::receiveFromLink(const Block& packet)
{
NFD_LOG_FACE_TRACE(__func__);
Packet p;
p.packet = packet;
this->receive(std::move(p));
}
void
InternalForwarderTransport::doSend(Packet&& packet)
{
NFD_LOG_FACE_TRACE(__func__);
this->emitSignal(afterSend, packet.packet);
}
void
InternalForwarderTransport::doClose()
{
NFD_LOG_FACE_TRACE(__func__);
this->setState(TransportState::CLOSED);
}
NFD_LOG_INCLASS_DEFINE(InternalClientTransport, "InternalClientTransport");
static void
asyncReceive(InternalTransportBase* recipient, const Block& packet)
{
getGlobalIoService().post([packet, recipient] {
recipient->receiveFromLink(packet);
});
}
void
InternalClientTransport::connectToForwarder(InternalForwarderTransport* forwarderTransport)
{
NFD_LOG_DEBUG(__func__ << " " << forwarderTransport);
m_fwToClientTransmitConn.disconnect();
m_clientToFwTransmitConn.disconnect();
m_fwTransportStateConn.disconnect();
if (forwarderTransport != nullptr) {
m_fwToClientTransmitConn = forwarderTransport->afterSend.connect(bind(&asyncReceive, this, _1));
m_clientToFwTransmitConn = this->afterSend.connect(bind(&asyncReceive, forwarderTransport, _1));
m_fwTransportStateConn = forwarderTransport->afterStateChange.connect(
[this] (TransportState oldState, TransportState newState) {
if (newState == TransportState::CLOSED) {
this->connectToForwarder(nullptr);
}
});
}
}
void
InternalClientTransport::receiveFromLink(const Block& packet)
{
if (m_receiveCallback) {
m_receiveCallback(packet);
}
}
void
InternalClientTransport::send(const Block& wire)
{
this->emitSignal(afterSend, wire);
}
void
InternalClientTransport::send(const Block& header, const Block& payload)
{
ndn::EncodingBuffer encoder(header.size() + payload.size(), header.size() + payload.size());
encoder.appendByteArray(header.wire(), header.size());
encoder.appendByteArray(payload.wire(), payload.size());
this->send(encoder.block());
}
} // namespace face
} // namespace nfd
+130
View File
@@ -0,0 +1,130 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_INTERNAL_TRANSPORT_HPP
#define NFD_DAEMON_FACE_INTERNAL_TRANSPORT_HPP
#include "transport.hpp"
#include <ndn-cxx/transport/transport.hpp>
namespace nfd {
namespace face {
/** \brief abstracts a transport that can be paired with another
*/
class InternalTransportBase
{
public:
/** \brief causes the transport to receive a link-layer packet
*/
virtual void
receiveFromLink(const Block& packet) = 0;
signal::Signal<InternalTransportBase, Block> afterSend;
protected:
DECLARE_SIGNAL_EMIT(afterSend)
};
/** \brief implements a forwarder-side transport that can be paired with another
*/
class InternalForwarderTransport : public face::Transport, public InternalTransportBase
{
public:
InternalForwarderTransport(const FaceUri& localUri = FaceUri("internal://"),
const FaceUri& remoteUri = FaceUri("internal://"),
ndn::nfd::FaceScope scope = ndn::nfd::FACE_SCOPE_LOCAL,
ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_POINT_TO_POINT);
virtual void
receiveFromLink(const Block& packet) DECL_OVERRIDE;
protected:
virtual void
beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_OVERRIDE;
virtual void
doClose() DECL_OVERRIDE;
private:
virtual void
doSend(Packet&& packet) DECL_OVERRIDE;
private:
NFD_LOG_INCLASS_DECLARE();
};
/** \brief implements a client-side transport that can be paired with another
*/
class InternalClientTransport : public ndn::Transport, public InternalTransportBase
{
public:
/** \brief connect to a forwarder-side transport
* \param forwarderTransport the forwarder-side transport to connect to; may be nullptr
*
* The connected forwarder-side transport will be disconnected automatically if this method
* is called again, or if that transport is closed.
* It's safe to use InternalClientTransport without a connected forwarder-side transport:
* all sent packets would be lost, and nothing would be received.
*/
void
connectToForwarder(InternalForwarderTransport* forwarderTransport);
virtual void
receiveFromLink(const Block& packet) DECL_OVERRIDE;
virtual void
close() DECL_OVERRIDE
{
}
virtual void
pause() DECL_OVERRIDE
{
}
virtual void
resume() DECL_OVERRIDE
{
}
virtual void
send(const Block& wire) DECL_OVERRIDE;
virtual void
send(const Block& header, const Block& payload) DECL_OVERRIDE;
private:
NFD_LOG_INCLASS_DECLARE();
signal::ScopedConnection m_fwToClientTransmitConn;
signal::ScopedConnection m_clientToFwTransmitConn;
signal::ScopedConnection m_fwTransportStateConn;
};
} // namespace face
} // namespace nfd
#endif // NFD_DAEMON_FACE_INTERNAL_TRANSPORT_HPP
+132
View File
@@ -0,0 +1,132 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "link-service.hpp"
#include "face.hpp"
namespace nfd {
namespace face {
NFD_LOG_INIT("LinkService");
LinkService::LinkService()
: m_face(nullptr)
, m_transport(nullptr)
{
}
LinkService::~LinkService()
{
}
void
LinkService::setFaceAndTransport(Face& face, Transport& transport)
{
BOOST_ASSERT(m_face == nullptr);
BOOST_ASSERT(m_transport == nullptr);
m_face = &face;
m_transport = &transport;
}
void
LinkService::sendInterest(const Interest& interest)
{
BOOST_ASSERT(m_transport != nullptr);
NFD_LOG_FACE_TRACE(__func__);
++this->nOutInterests;
doSendInterest(interest);
}
void
LinkService::sendData(const Data& data)
{
BOOST_ASSERT(m_transport != nullptr);
NFD_LOG_FACE_TRACE(__func__);
++this->nOutData;
doSendData(data);
}
void
LinkService::sendNack(const ndn::lp::Nack& nack)
{
BOOST_ASSERT(m_transport != nullptr);
NFD_LOG_FACE_TRACE(__func__);
++this->nOutNacks;
doSendNack(nack);
}
void
LinkService::receiveInterest(const Interest& interest)
{
NFD_LOG_FACE_TRACE(__func__);
++this->nInInterests;
afterReceiveInterest(interest);
}
void
LinkService::receiveData(const Data& data)
{
NFD_LOG_FACE_TRACE(__func__);
++this->nInData;
afterReceiveData(data);
}
void
LinkService::receiveNack(const ndn::lp::Nack& nack)
{
NFD_LOG_FACE_TRACE(__func__);
++this->nInNacks;
afterReceiveNack(nack);
}
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<LinkService>& flh)
{
const Face* face = flh.obj.getFace();
if (face == nullptr) {
os << "[id=0,local=unknown,remote=unknown] ";
}
else {
os << "[id=" << face->getId() << ",local=" << face->getLocalUri()
<< ",remote=" << face->getRemoteUri() << "] ";
}
return os;
}
} // namespace face
} // namespace nfd
+244
View File
@@ -0,0 +1,244 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_LINK_SERVICE_HPP
#define NFD_DAEMON_FACE_LINK_SERVICE_HPP
#include "core/counter.hpp"
#include "transport.hpp"
#include "face-log.hpp"
namespace nfd {
namespace face {
class Face;
/** \brief counters provided by LinkService
* \note The type name 'LinkServiceCounters' is implementation detail.
* Use 'LinkService::Counters' in public API.
*/
class LinkServiceCounters
{
public:
/** \brief count of incoming Interests
*/
PacketCounter nInInterests;
/** \brief count of outgoing Interests
*/
PacketCounter nOutInterests;
/** \brief count of incoming Data
*/
PacketCounter nInData;
/** \brief count of outgoing Data
*/
PacketCounter nOutData;
/** \brief count of incoming Nacks
*/
PacketCounter nInNacks;
/** \brief count of outgoing Nacks
*/
PacketCounter nOutNacks;
};
/** \brief the upper part of a Face
* \sa Face
*/
class LinkService : protected virtual LinkServiceCounters, noncopyable
{
public:
/** \brief counters provided by LinkService
*/
typedef LinkServiceCounters Counters;
public:
LinkService();
virtual
~LinkService();
/** \brief set Face and Transport for LinkService
* \pre setFaceAndTransport has not been called
*/
void
setFaceAndTransport(Face& face, Transport& transport);
/** \return Face to which this LinkService is attached
*/
const Face*
getFace() const;
/** \return Transport to which this LinkService is attached
*/
const Transport*
getTransport() const;
/** \return Transport to which this LinkService is attached
*/
Transport*
getTransport();
virtual const Counters&
getCounters() const;
public: // upper interface to be used by forwarding
/** \brief send Interest
* \pre setTransport has been called
*/
void
sendInterest(const Interest& interest);
/** \brief send Data
* \pre setTransport has been called
*/
void
sendData(const Data& data);
/** \brief send Nack
* \pre setTransport has been called
*/
void
sendNack(const ndn::lp::Nack& nack);
/** \brief signals on Interest received
*/
signal::Signal<LinkService, Interest> afterReceiveInterest;
/** \brief signals on Data received
*/
signal::Signal<LinkService, Data> afterReceiveData;
/** \brief signals on Nack received
*/
signal::Signal<LinkService, lp::Nack> afterReceiveNack;
public: // lower interface to be invoked by Transport
/** \brief performs LinkService specific operations to receive a lower-layer packet
*/
void
receivePacket(Transport::Packet&& packet);
protected: // upper interface to be invoked in subclass (receive path termination)
/** \brief delivers received Interest to forwarding
*/
void
receiveInterest(const Interest& interest);
/** \brief delivers received Data to forwarding
*/
void
receiveData(const Data& data);
/** \brief delivers received Nack to forwarding
*/
void
receiveNack(const lp::Nack& nack);
protected: // lower interface to be invoked in subclass (send path termination)
/** \brief sends a lower-layer packet via Transport
*/
void
sendPacket(Transport::Packet&& packet);
private: // upper interface to be overridden in subclass (send path entrypoint)
/** \brief performs LinkService specific operations to send an Interest
*/
virtual void
doSendInterest(const Interest& interest) = 0;
/** \brief performs LinkService specific operations to send a Data
*/
virtual void
doSendData(const Data& data) = 0;
/** \brief performs LinkService specific operations to send a Nack
*/
virtual void
doSendNack(const lp::Nack& nack) = 0;
private: // lower interface to be overridden in subclass
virtual void
doReceivePacket(Transport::Packet&& packet) = 0;
private:
Face* m_face;
Transport* m_transport;
};
inline const Face*
LinkService::getFace() const
{
return m_face;
}
inline const Transport*
LinkService::getTransport() const
{
return m_transport;
}
inline Transport*
LinkService::getTransport()
{
return m_transport;
}
inline const LinkService::Counters&
LinkService::getCounters() const
{
return *this;
}
inline void
LinkService::receivePacket(Transport::Packet&& packet)
{
doReceivePacket(std::move(packet));
}
inline void
LinkService::sendPacket(Transport::Packet&& packet)
{
m_transport->send(std::move(packet));
}
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<LinkService>& flh);
template<typename T>
typename std::enable_if<std::is_base_of<LinkService, T>::value &&
!std::is_same<LinkService, T>::value, std::ostream&>::type
operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
{
return os << FaceLogHelper<LinkService>(flh.obj);
}
} // namespace face
} // namespace nfd
#endif // NFD_DAEMON_FACE_LINK_SERVICE_HPP
-210
View File
@@ -1,210 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NFD_DAEMON_FACE_LOCAL_FACE_HPP
#define NFD_DAEMON_FACE_LOCAL_FACE_HPP
#include "face.hpp"
#include <ndn-cxx/management/nfd-control-parameters.hpp>
namespace nfd {
using ndn::nfd::LocalControlFeature;
using ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID;
using ndn::nfd::LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID;
/** \brief represents a face
*/
class LocalFace : public Face
{
public:
LocalFace(const FaceUri& remoteUri, const FaceUri& localUri);
/** \brief get whether any LocalControlHeader feature is enabled
*
* \returns true if any feature is enabled.
*/
bool
isLocalControlHeaderEnabled() const;
/** \brief get whether a specific LocalControlHeader feature is enabled
*
* \param feature The feature.
* \returns true if the specified feature is enabled.
*/
bool
isLocalControlHeaderEnabled(LocalControlFeature feature) const;
/** \brief enable or disable a LocalControlHeader feature
*
* \param feature The feature. Cannot be LOCAL_CONTROL_FEATURE_ANY
* or LOCAL_CONTROL_FEATURE_MAX
*/
void
setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled = true);
public:
static const size_t LOCAL_CONTROL_FEATURE_MAX = 3; /// upper bound of LocalControlFeature enum
static const size_t LOCAL_CONTROL_FEATURE_ANY = 0; /// any feature
protected:
// statically overridden from Face
/** \brief Decode block into Interest/Data, considering potential LocalControlHeader
*
* If LocalControlHeader is present, the encoded data is filtered out, based
* on enabled features on the face.
*/
bool
decodeAndDispatchInput(const Block& element);
// LocalFace-specific methods
/** \brief Check if LocalControlHeader needs to be included, taking into account
* both set parameters in supplied LocalControlHeader and features
* enabled on the local face.
*/
bool
isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const;
/** \brief Create LocalControlHeader, considering enabled features
*/
template<class Packet>
Block
filterAndEncodeLocalControlHeader(const Packet& packet);
private:
std::vector<bool> m_localControlHeaderFeatures;
};
inline
LocalFace::LocalFace(const FaceUri& remoteUri, const FaceUri& localUri)
: Face(remoteUri, localUri, true)
, m_localControlHeaderFeatures(LocalFace::LOCAL_CONTROL_FEATURE_MAX)
{
}
inline bool
LocalFace::isLocalControlHeaderEnabled() const
{
return m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY];
}
inline bool
LocalFace::isLocalControlHeaderEnabled(LocalControlFeature feature) const
{
BOOST_ASSERT(0 < feature &&
static_cast<size_t>(feature) < m_localControlHeaderFeatures.size());
return m_localControlHeaderFeatures[feature];
}
inline void
LocalFace::setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled/* = true*/)
{
BOOST_ASSERT(0 < feature &&
static_cast<size_t>(feature) < m_localControlHeaderFeatures.size());
m_localControlHeaderFeatures[feature] = enabled;
m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY] =
std::find(m_localControlHeaderFeatures.begin() + 1,
m_localControlHeaderFeatures.end(), true) <
m_localControlHeaderFeatures.end();
// 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
}
inline bool
LocalFace::decodeAndDispatchInput(const Block& element)
{
try {
const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
// If received LocalControlHeader, but it is not enabled on the face
if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
return false;
if (payload.type() == tlv::Interest)
{
shared_ptr<Interest> i = make_shared<Interest>();
i->wireDecode(payload);
if (&payload != &element)
{
i->getLocalControlHeader().wireDecode(element,
false,
this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
}
this->onReceiveInterest(*i);
}
else if (payload.type() == tlv::Data)
{
shared_ptr<Data> d = make_shared<Data>();
d->wireDecode(payload);
/// \todo Uncomment and correct the following when we have more
/// options in LocalControlHeader that apply for incoming
/// Data packets (if ever)
// if (&payload != &element)
// {
//
// d->getLocalControlHeader().wireDecode(element,
// false,
// false);
// }
this->onReceiveData(*d);
}
else
return false;
return true;
}
catch (tlv::Error&) {
return false;
}
}
inline bool
LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
{
if (!this->isLocalControlHeaderEnabled())
return true;
return header.empty(this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
false);
}
template<class Packet>
inline Block
LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
{
return packet.getLocalControlHeader().wireEncode(packet,
this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
false);
}
} // namespace nfd
#endif // NFD_DAEMON_FACE_LOCAL_FACE_HPP
+162
View File
@@ -0,0 +1,162 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "lp-fragmenter.hpp"
#include "link-service.hpp"
#include <ndn-cxx/encoding/tlv.hpp>
namespace nfd {
namespace face {
NFD_LOG_INIT("LpFragmenter");
static_assert(lp::tlv::LpPacket < 253, "LpPacket TLV-TYPE must fit in 1 octet");
static_assert(lp::tlv::Sequence < 253, "Sequence TLV-TYPE must fit in 1 octet");
static_assert(lp::tlv::FragIndex < 253, "FragIndex TLV-TYPE must fit in 1 octet");
static_assert(lp::tlv::FragCount < 253, "FragCount TLV-TYPE must fit in 1 octet");
static_assert(lp::tlv::Fragment < 253, "Fragment TLV-TYPE must fit in 1 octet");
/** \brief maximum overhead on a single fragment,
* not counting other NDNLPv2 headers
*/
static const size_t MAX_SINGLE_FRAG_OVERHEAD =
1 + 9 + // LpPacket TLV-TYPE and TLV-LENGTH
1 + 1 + 8 + // Sequence TLV
1 + 9; // Fragment TLV-TYPE and TLV-LENGTH
/** \brief maximum overhead of adding fragmentation to payload,
* not counting other NDNLPv2 headers
*/
static const size_t MAX_FRAG_OVERHEAD =
1 + 9 + // LpPacket TLV-TYPE and TLV-LENGTH
1 + 1 + 8 + // Sequence TLV
1 + 1 + 8 + // FragIndex TLV
1 + 1 + 8 + // FragCount TLV
1 + 9; // Fragment TLV-TYPE and TLV-LENGTH
LpFragmenter::Options::Options()
: nMaxFragments(400)
{
}
LpFragmenter::LpFragmenter(const LpFragmenter::Options& options, const LinkService* linkService)
: m_options(options)
, m_linkService(linkService)
{
}
void
LpFragmenter::setOptions(const Options& options)
{
m_options = options;
}
const LinkService*
LpFragmenter::getLinkService() const
{
return m_linkService;
}
std::tuple<bool, std::vector<lp::Packet>>
LpFragmenter::fragmentPacket(const lp::Packet& packet, size_t mtu)
{
BOOST_ASSERT(packet.has<lp::FragmentField>());
BOOST_ASSERT(!packet.has<lp::FragIndexField>());
BOOST_ASSERT(!packet.has<lp::FragCountField>());
if (MAX_SINGLE_FRAG_OVERHEAD + packet.wireEncode().size() <= mtu) {
// fast path: fragmentation not needed
// To qualify for fast path, the packet must have space for adding a sequence number,
// because another NDNLPv2 feature may require the sequence number.
return std::make_tuple(true, std::vector<lp::Packet>{packet});
}
ndn::Buffer::const_iterator netPktBegin, netPktEnd;
std::tie(netPktBegin, netPktEnd) = packet.get<lp::FragmentField>();
size_t netPktSize = std::distance(netPktBegin, netPktEnd);
// compute size of other NDNLPv2 headers to be placed on the first fragment
size_t firstHeaderSize = 0;
const Block& packetWire = packet.wireEncode();
if (packetWire.type() == lp::tlv::LpPacket) {
for (const Block& element : packetWire.elements()) {
if (element.type() != lp::tlv::Fragment) {
firstHeaderSize += element.size();
}
}
}
// compute payload size
if (MAX_FRAG_OVERHEAD + firstHeaderSize + 1 > mtu) { // 1-octet fragment
NFD_LOG_FACE_WARN("fragmentation error, MTU too small for first fragment: DROP");
return std::make_tuple(false, std::vector<lp::Packet>{});
}
size_t firstPayloadSize = std::min(netPktSize, mtu - firstHeaderSize - MAX_FRAG_OVERHEAD);
size_t payloadSize = mtu - MAX_FRAG_OVERHEAD;
size_t fragCount = 1 + ((netPktSize - firstPayloadSize) / payloadSize) +
((netPktSize - firstPayloadSize) % payloadSize != 0);
// compute FragCount
if (fragCount > m_options.nMaxFragments) {
NFD_LOG_FACE_WARN("fragmentation error, FragCount over limit: DROP");
return std::make_pair(false, std::vector<lp::Packet>{});
}
// populate fragments
std::vector<lp::Packet> frags(fragCount);
frags.front() = packet; // copy input packet to preserve other NDNLPv2 fields
size_t fragIndex = 0;
auto fragBegin = netPktBegin,
fragEnd = fragBegin + firstPayloadSize;
while (fragBegin < netPktEnd) {
lp::Packet& frag = frags[fragIndex];
frag.add<lp::FragIndexField>(fragIndex);
frag.add<lp::FragCountField>(fragCount);
frag.set<lp::FragmentField>(std::make_pair(fragBegin, fragEnd));
BOOST_ASSERT(frag.wireEncode().size() <= mtu);
++fragIndex;
fragBegin = fragEnd;
fragEnd = std::min(netPktEnd, fragBegin + payloadSize);
}
BOOST_ASSERT(fragIndex == fragCount);
return std::make_pair(true, frags);
}
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<LpFragmenter>& flh)
{
if (flh.obj.getLinkService() == nullptr) {
os << "[id=0,local=unknown,remote=unknown] ";
}
else {
os << FaceLogHelper<LinkService>(*flh.obj.getLinkService());
}
return os;
}
} // namespace face
} // namespace nfd
+92
View File
@@ -0,0 +1,92 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_LP_FRAGMENTER_HPP
#define NFD_DAEMON_FACE_LP_FRAGMENTER_HPP
#include "face-log.hpp"
#include <ndn-cxx/lp/packet.hpp>
namespace nfd {
namespace face {
class LinkService;
/** \brief fragments network-layer packets into NDNLPv2 link-layer packets
* \sa http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
*/
class LpFragmenter
{
public:
/** \brief Options that control the behavior of LpFragmenter
*/
class Options
{
public:
Options();
public:
/** \brief maximum number of fragments in a packet
*/
size_t nMaxFragments;
};
explicit
LpFragmenter(const Options& options = Options(), const LinkService* linkService = nullptr);
/** \brief set options for fragmenter
*/
void
setOptions(const Options& options);
/** \return LinkService that owns this instance
*
* This is only used for logging, and may be nullptr.
*/
const LinkService*
getLinkService() const;
/** \brief fragments a network-layer packet into link-layer packets
* \param packet an LpPacket that contains a network-layer packet;
* must have Fragment field, must not have FragIndex and FragCount fields
* \param mtu maximum allowable LpPacket size after fragmentation and sequence number assignment
* \return whether fragmentation succeeded, fragmented packets without sequence number
*/
std::tuple<bool, std::vector<lp::Packet>>
fragmentPacket(const lp::Packet& packet, size_t mtu);
private:
Options m_options;
const LinkService* m_linkService;
};
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<LpFragmenter>& flh);
} // namespace face
} // namespace nfd
#endif // NFD_DAEMON_FACE_LP_FRAGMENTER_HPP
+176
View File
@@ -0,0 +1,176 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "lp-reassembler.hpp"
#include "link-service.hpp"
#include <numeric>
namespace nfd {
namespace face {
NFD_LOG_INIT("LpReassembler");
LpReassembler::Options::Options()
: nMaxFragments(400)
, reassemblyTimeout(time::milliseconds(500))
{
}
LpReassembler::LpReassembler(const LpReassembler::Options& options, const LinkService* linkService)
: m_options(options)
, m_linkService(linkService)
{
}
std::tuple<bool, Block, lp::Packet>
LpReassembler::receiveFragment(Transport::EndpointId remoteEndpoint, const lp::Packet& packet)
{
BOOST_ASSERT(packet.has<lp::FragmentField>());
static auto FALSE_RETURN = std::make_tuple(false, Block(), lp::Packet());
// read and check FragIndex and FragCount
uint64_t fragIndex = 0;
uint64_t fragCount = 1;
if (packet.has<lp::FragIndexField>()) {
fragIndex = packet.get<lp::FragIndexField>();
}
if (packet.has<lp::FragCountField>()) {
fragCount = packet.get<lp::FragCountField>();
}
if (fragIndex >= fragCount) {
NFD_LOG_FACE_WARN("reassembly error, FragIndex>=FragCount: DROP");
return FALSE_RETURN;
}
if (fragCount > m_options.nMaxFragments) {
NFD_LOG_FACE_WARN("reassembly error, FragCount over limit: DROP");
return FALSE_RETURN;
}
// check for fast path
if (fragIndex == 0 && fragCount == 1) {
ndn::Buffer::const_iterator fragBegin, fragEnd;
std::tie(fragBegin, fragEnd) = packet.get<lp::FragmentField>();
Block netPkt(&*fragBegin, std::distance(fragBegin, fragEnd));
return std::make_tuple(true, netPkt, packet);
}
// check Sequence and compute message identifier
if (!packet.has<lp::SequenceField>()) {
NFD_LOG_FACE_WARN("reassembly error, Sequence missing: DROP");
return FALSE_RETURN;
}
lp::Sequence messageIdentifier = packet.get<lp::SequenceField>() - fragIndex;
Key key = std::make_tuple(remoteEndpoint, messageIdentifier);
// add to PartialPacket
PartialPacket& pp = m_partialPackets[key];
if (pp.fragCount == 0) { // new PartialPacket
pp.fragCount = fragCount;
pp.nReceivedFragments = 0;
pp.fragments.resize(fragCount);
}
else {
if (fragCount != pp.fragCount) {
NFD_LOG_FACE_WARN("reassembly error, FragCount changed: DROP");
return FALSE_RETURN;
}
}
if (pp.fragments[fragIndex].has<lp::SequenceField>()) {
NFD_LOG_FACE_TRACE("fragment already received: DROP");
return FALSE_RETURN;
}
pp.fragments[fragIndex] = packet;
++pp.nReceivedFragments;
// check complete condition
if (pp.nReceivedFragments == pp.fragCount) {
Block reassembled = doReassembly(key);
lp::Packet firstFrag(std::move(pp.fragments[0]));
m_partialPackets.erase(key);
return std::make_tuple(true, reassembled, firstFrag);
}
// set drop timer
pp.dropTimer = scheduler::schedule(m_options.reassemblyTimeout,
bind(&LpReassembler::timeoutPartialPacket, this, key));
return FALSE_RETURN;
}
Block
LpReassembler::doReassembly(const Key& key)
{
PartialPacket& pp = m_partialPackets[key];
size_t payloadSize = std::accumulate(pp.fragments.begin(), pp.fragments.end(), 0,
[&] (size_t sum, const lp::Packet& pkt) -> size_t {
ndn::Buffer::const_iterator fragBegin, fragEnd;
std::tie(fragBegin, fragEnd) = pkt.get<lp::FragmentField>();
return sum + std::distance(fragBegin, fragEnd);
});
ndn::Buffer fragBuffer(payloadSize);
ndn::Buffer::iterator it = fragBuffer.begin();
for (const lp::Packet& frag : pp.fragments) {
ndn::Buffer::const_iterator fragBegin, fragEnd;
std::tie(fragBegin, fragEnd) = frag.get<lp::FragmentField>();
it = std::copy(fragBegin, fragEnd, it);
}
return Block(&*(fragBuffer.cbegin()), std::distance(fragBuffer.cbegin(), fragBuffer.cend()));
}
void
LpReassembler::timeoutPartialPacket(const Key& key)
{
auto it = m_partialPackets.find(key);
if (it == m_partialPackets.end()) {
return;
}
this->beforeTimeout(std::get<0>(key), it->second.nReceivedFragments);
m_partialPackets.erase(it);
}
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<LpReassembler>& flh)
{
if (flh.obj.getLinkService() == nullptr) {
os << "[id=0,local=unknown,remote=unknown] ";
}
else {
os << FaceLogHelper<LinkService>(*flh.obj.getLinkService());
}
return os;
}
} // namespace face
} // namespace nfd
+160
View File
@@ -0,0 +1,160 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_LP_REASSEMBLER_HPP
#define NFD_DAEMON_FACE_LP_REASSEMBLER_HPP
#include "core/scheduler.hpp"
#include "face-log.hpp"
#include "transport.hpp"
#include <ndn-cxx/lp/packet.hpp>
namespace nfd {
namespace face {
class LinkService;
/** \brief reassembles fragmented network-layer packets
* \sa http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
*/
class LpReassembler : noncopyable
{
public:
/** \brief Options that control the behavior of LpReassembler
*/
class Options
{
public:
Options();
public:
/** \brief maximum number of fragments in a packet
*
* LpPackets with FragCount over this limit are dropped.
*/
size_t nMaxFragments;
/** \brief timeout before a partially reassembled packet is dropped
*/
time::nanoseconds reassemblyTimeout;
};
explicit
LpReassembler(const Options& options = Options(), const LinkService* linkService = nullptr);
/** \brief set options for reassembler
*/
void
setOptions(const Options& options);
/** \return LinkService that owns this instance
*
* This is only used for logging, and may be nullptr.
*/
const LinkService*
getLinkService() const;
/** \brief adds received fragment to buffer
* \param remoteEndpoint endpoint whose sends the packet
* \param packet received fragment;
* must have Fragment field
* \return whether network-layer packet has been completely received,
* the reassembled network-layer packet,
* and the first fragment for inspecting other NDNLPv2 headers
* \throw tlv::Error packet is malformed
*/
std::tuple<bool, Block, lp::Packet>
receiveFragment(Transport::EndpointId remoteEndpoint, const lp::Packet& packet);
/** \brief count of partial packets
*/
size_t
size() const;
/** \brief signals before a partial packet is dropped due to timeout
*
* If a partial packet is incomplete and no new fragment is received
* within Options::reassemblyTimeout, it would be dropped due to timeout.
* Before it's erased, this signal is emitted with the remote endpoint,
* and the number of fragments being dropped.
*/
signal::Signal<LpReassembler, Transport::EndpointId, size_t> beforeTimeout;
private:
/** \brief holds all fragments of packet until reassembled
*/
struct PartialPacket
{
std::vector<lp::Packet> fragments;
size_t fragCount; ///< total fragments
size_t nReceivedFragments; ///< number of received fragments
scheduler::ScopedEventId dropTimer;
};
/** \brief index key for PartialPackets
*/
typedef std::tuple<
Transport::EndpointId, // remoteEndpoint
lp::Sequence // message identifier (sequence of the first fragment)
> Key;
Block
doReassembly(const Key& key);
void
timeoutPartialPacket(const Key& key);
private:
Options m_options;
std::map<Key, PartialPacket> m_partialPackets;
const LinkService* m_linkService;
};
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<LpReassembler>& flh);
inline void
LpReassembler::setOptions(const Options& options)
{
m_options = options;
}
inline const LinkService*
LpReassembler::getLinkService() const
{
return m_linkService;
}
inline size_t
LpReassembler::size() const
{
return m_partialPackets.size();
}
} // namespace face
} // namespace nfd
#endif // NFD_DAEMON_FACE_LP_REASSEMBLER_HPP
-87
View File
@@ -1,87 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "multicast-udp-face.hpp"
namespace nfd {
NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(DatagramFace,
MulticastUdpFace::protocol, Multicast,
"MulticastUdpFace");
MulticastUdpFace::MulticastUdpFace(const shared_ptr<MulticastUdpFace::protocol::socket>& recvSocket,
const shared_ptr<MulticastUdpFace::protocol::socket>& sendSocket,
const MulticastUdpFace::protocol::endpoint& localEndpoint,
const MulticastUdpFace::protocol::endpoint& multicastEndpoint)
: DatagramFace<protocol, Multicast>(FaceUri(multicastEndpoint),
FaceUri(localEndpoint),
recvSocket, false)
, m_multicastGroup(multicastEndpoint)
, m_sendSocket(sendSocket)
{
NFD_LOG_INFO("Creating multicast UDP face for group " << m_multicastGroup);
}
const MulticastUdpFace::protocol::endpoint&
MulticastUdpFace::getMulticastGroup() const
{
return m_multicastGroup;
}
void
MulticastUdpFace::sendBlock(const Block& block)
{
m_sendSocket->async_send_to(boost::asio::buffer(block.wire(), block.size()),
m_multicastGroup,
bind(&MulticastUdpFace::handleSend, this, _1, _2, block));
}
void
MulticastUdpFace::sendInterest(const Interest& interest)
{
onSendInterest(interest);
NFD_LOG_DEBUG("Sending interest");
sendBlock(interest.wireEncode());
}
void
MulticastUdpFace::sendData(const Data& data)
{
/// \todo After this method implements duplicate suppression, onSendData event should
/// be triggered only when data is actually sent out
onSendData(data);
NFD_LOG_DEBUG("Sending data");
sendBlock(data.wireEncode());
}
bool
MulticastUdpFace::isMultiAccess() const
{
return true;
}
} // namespace nfd
-72
View File
@@ -1,72 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_MULTICAST_UDP_FACE_HPP
#define NFD_DAEMON_FACE_MULTICAST_UDP_FACE_HPP
#include "datagram-face.hpp"
namespace nfd {
/**
* \brief Implementation of Face abstraction that uses
* multicast UDP as underlying transport mechanism
*/
class MulticastUdpFace : public DatagramFace<boost::asio::ip::udp, Multicast>
{
public:
/**
* \brief Creates a UDP-based face for multicast communication
*/
MulticastUdpFace(const shared_ptr<protocol::socket>& recvSocket,
const shared_ptr<protocol::socket>& sendSocket,
const protocol::endpoint& localEndpoint,
const protocol::endpoint& multicastEndpoint);
const protocol::endpoint&
getMulticastGroup() const;
// from Face
virtual void
sendInterest(const Interest& interest);
virtual void
sendData(const Data& data);
virtual bool
isMultiAccess() const;
private:
void
sendBlock(const Block& block);
private:
protocol::endpoint m_multicastGroup;
shared_ptr<protocol::socket> m_sendSocket;
};
} // namespace nfd
#endif // NFD_DAEMON_FACE_MULTICAST_UDP_FACE_HPP
+102
View File
@@ -0,0 +1,102 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "multicast-udp-transport.hpp"
#include "udp-protocol.hpp"
namespace nfd {
namespace face {
NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(DatagramTransport, MulticastUdpTransport::protocol,
Multicast, "MulticastUdpTransport");
MulticastUdpTransport::MulticastUdpTransport(const protocol::endpoint& localEndpoint,
const protocol::endpoint& multicastGroup,
protocol::socket&& recvSocket,
protocol::socket&& sendSocket)
: DatagramTransport(std::move(recvSocket))
, m_multicastGroup(multicastGroup)
, m_sendSocket(std::move(sendSocket))
{
this->setLocalUri(FaceUri(localEndpoint));
this->setRemoteUri(FaceUri(multicastGroup));
this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
this->setPersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
this->setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS);
this->setMtu(udp::computeMtu(localEndpoint));
NFD_LOG_FACE_INFO("Creating transport");
}
void
MulticastUdpTransport::beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
{
if (newPersistency != ndn::nfd::FACE_PERSISTENCY_PERMANENT) {
BOOST_THROW_EXCEPTION(
std::invalid_argument("MulticastUdpTransport supports only FACE_PERSISTENCY_PERMANENT"));
}
}
void
MulticastUdpTransport::doSend(Transport::Packet&& packet)
{
NFD_LOG_FACE_TRACE(__func__);
m_sendSocket.async_send_to(boost::asio::buffer(packet.packet), m_multicastGroup,
bind(&MulticastUdpTransport::handleSend, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
packet.packet));
}
void
MulticastUdpTransport::doClose()
{
if (m_sendSocket.is_open()) {
NFD_LOG_FACE_TRACE("Closing sending socket");
// Cancel all outstanding operations and close the socket.
// Use the non-throwing variants and ignore errors, if any.
boost::system::error_code error;
m_sendSocket.cancel(error);
m_sendSocket.close(error);
}
DatagramTransport::doClose();
}
template<>
Transport::EndpointId
DatagramTransport<boost::asio::ip::udp, Multicast>::makeEndpointId(const protocol::endpoint& ep)
{
// IPv6 multicast is not supported
BOOST_ASSERT(ep.address().is_v4());
return (static_cast<uint64_t>(ep.port()) << 32) |
static_cast<uint64_t>(ep.address().to_v4().to_ulong());
}
} // namespace face
} // namespace nfd
+79
View File
@@ -0,0 +1,79 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FACE_MULTICAST_UDP_TRANSPORT_HPP
#define NFD_DAEMON_FACE_MULTICAST_UDP_TRANSPORT_HPP
#include "datagram-transport.hpp"
namespace nfd {
namespace face {
// Explicit specialization of makeEndpointId for the UDP multicast case.
// Note that this "shall be declared before the first use of the specialization
// that would cause an implicit instantiation to take place, in every translation
// unit in which such a use occurs".
template<>
Transport::EndpointId
DatagramTransport<boost::asio::ip::udp, Multicast>::makeEndpointId(const protocol::endpoint& ep);
/**
* \brief A Transport that communicates on a UDP multicast group
*/
class MulticastUdpTransport DECL_CLASS_FINAL : public DatagramTransport<boost::asio::ip::udp, Multicast>
{
public:
/**
* \brief Creates a UDP-based transport for multicast communication
* \param localEndpoint local endpoint
* \param multicastGroup multicast group
* \param recvSocket socket used to receive packets
* \param sendSocket socket used to send to the multicast group
*/
MulticastUdpTransport(const protocol::endpoint& localEndpoint,
const protocol::endpoint& multicastGroup,
protocol::socket&& recvSocket,
protocol::socket&& sendSocket);
protected:
virtual void
beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_FINAL;
private:
virtual void
doSend(Transport::Packet&& packet) DECL_FINAL;
virtual void
doClose() DECL_FINAL;
private:
protocol::endpoint m_multicastGroup;
protocol::socket m_sendSocket;
};
} // namespace face
} // namespace nfd
#endif // NFD_DAEMON_FACE_MULTICAST_UDP_TRANSPORT_HPP
-92
View File
@@ -1,92 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "ndnlp-parse.hpp"
namespace nfd {
namespace ndnlp {
void
NdnlpData::wireDecode(const Block& wire)
{
if (wire.type() != tlv::NdnlpData) {
throw ParseError("top element is not NdnlpData");
}
wire.parse();
const Block::element_container& elements = wire.elements();
if (elements.size() < 2) {
throw ParseError("NdnlpData element has incorrect number of children");
}
const Block& sequenceElement = elements.front();
if (sequenceElement.type() != tlv::NdnlpSequence) {
throw ParseError("NdnlpSequence element is missing");
}
if (sequenceElement.value_size() != sizeof(uint64_t)) {
throw ParseError("NdnlpSequence element has incorrect length");
}
m_seq = be64toh(*reinterpret_cast<const uint64_t*>(&*sequenceElement.value_begin()));
const Block& payloadElement = elements.back();
if (payloadElement.type() != tlv::NdnlpPayload) {
throw ParseError("NdnlpPayload element is missing");
}
m_payload = payloadElement;
if (elements.size() == 2) { // single wire packet
m_fragIndex = 0;
m_fragCount = 1;
return;
}
if (elements.size() != 4) {
throw ParseError("NdnlpData element has incorrect number of children");
}
const Block& fragIndexElement = elements.at(1);
if (fragIndexElement.type() != tlv::NdnlpFragIndex) {
throw ParseError("NdnlpFragIndex element is missing");
}
uint64_t fragIndex = ndn::readNonNegativeInteger(fragIndexElement);
if (fragIndex > std::numeric_limits<uint16_t>::max()) {
throw ParseError("NdnlpFragIndex is too large");
}
m_fragIndex = static_cast<uint16_t>(fragIndex);
const Block& fragCountElement = elements.at(2);
if (fragCountElement.type() != tlv::NdnlpFragCount) {
throw ParseError("NdnlpFragCount element is missing");
}
uint64_t fragCount = ndn::readNonNegativeInteger(fragCountElement);
if (fragCount > std::numeric_limits<uint16_t>::max()) {
throw ParseError("NdnlpFragCount is too large");
}
m_fragCount = static_cast<uint16_t>(fragCount);
if (m_fragIndex >= m_fragCount) {
throw ParseError("NdnlpFragIndex must be less than NdnlpFragCount");
}
}
} // namespace ndnlp
} // namespace nfd
-70
View File
@@ -1,70 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NFD_DAEMON_FACE_NDNLP_PARSE_HPP
#define NFD_DAEMON_FACE_NDNLP_PARSE_HPP
#include "common.hpp"
#include "ndnlp-tlv.hpp"
namespace nfd {
namespace ndnlp {
struct ParseError : public std::runtime_error
{
ParseError(const std::string& what)
: std::runtime_error(what)
{
}
};
/** \brief represents a NdnlpData packet
*
* NdnlpData ::= NDNLP-DATA-TYPE TLV-LENGTH
* NdnlpSequence
* NdnlpFragIndex?
* NdnlpFragCount?
* NdnlpPayload
*/
class NdnlpData
{
public:
/** \brief parse a NdnlpData packet
*
* \exception ParseError packet is malformated
*/
void
wireDecode(const Block& wire);
public:
uint64_t m_seq;
uint16_t m_fragIndex;
uint16_t m_fragCount;
Block m_payload;
};
} // namespace ndnlp
} // namespace nfd
#endif // NFD_DAEMON_FACE_NDNLP_PARSE_HPP
-137
View File
@@ -1,137 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "ndnlp-partial-message-store.hpp"
namespace nfd {
namespace ndnlp {
PartialMessage::PartialMessage()
: m_fragCount(0)
, m_received(0)
, m_totalLength(0)
{
}
bool
PartialMessage::add(uint16_t fragIndex, uint16_t fragCount, const Block& payload)
{
if (m_received == 0) { // first packet
m_fragCount = fragCount;
m_payloads.resize(fragCount);
}
if (m_fragCount != fragCount || fragIndex >= m_fragCount) {
return false;
}
if (!m_payloads[fragIndex].empty()) { // duplicate
return false;
}
m_payloads[fragIndex] = payload;
++m_received;
m_totalLength += payload.value_size();
return true;
}
bool
PartialMessage::isComplete() const
{
return m_received == m_fragCount;
}
Block
PartialMessage::reassemble()
{
BOOST_ASSERT(this->isComplete());
ndn::BufferPtr buffer = make_shared<ndn::Buffer>(m_totalLength);
uint8_t* buf = buffer->get();
for (std::vector<Block>::const_iterator it = m_payloads.begin();
it != m_payloads.end(); ++it) {
const Block& payload = *it;
memcpy(buf, payload.value(), payload.value_size());
buf += payload.value_size();
}
return Block(buffer);
}
PartialMessageStore::PartialMessageStore(const time::nanoseconds& idleDuration)
: m_idleDuration(idleDuration)
{
}
PartialMessageStore::~PartialMessageStore()
{
}
void
PartialMessageStore::receiveNdnlpData(const Block& pkt)
{
NdnlpData parsed;
parsed.wireDecode(pkt);
if (parsed.m_fragCount == 1) { // single fragment
this->onReceive(parsed.m_payload.blockFromValue());
return;
}
uint64_t messageIdentifier = parsed.m_seq - parsed.m_fragIndex;
shared_ptr<PartialMessage> pm = m_partialMessages[messageIdentifier];
if (!static_cast<bool>(pm)) {
m_partialMessages[messageIdentifier] = pm = make_shared<PartialMessage>();
}
this->scheduleCleanup(messageIdentifier, pm);
pm->add(parsed.m_fragIndex, parsed.m_fragCount, parsed.m_payload);
if (pm->isComplete()) {
this->onReceive(pm->reassemble());
this->cleanup(messageIdentifier);
}
}
void
PartialMessageStore::scheduleCleanup(uint64_t messageIdentifier,
shared_ptr<PartialMessage> partialMessage)
{
partialMessage->m_expiry = scheduler::schedule(m_idleDuration,
bind(&PartialMessageStore::cleanup, this, messageIdentifier));
}
void
PartialMessageStore::cleanup(uint64_t messageIdentifier)
{
std::map<uint64_t, shared_ptr<PartialMessage> >::iterator it =
m_partialMessages.find(messageIdentifier);
if (it == m_partialMessages.end()) {
return;
}
scheduler::cancel(it->second->m_expiry);
m_partialMessages.erase(it);
}
} // namespace ndnlp
} // namespace nfd
-106
View File
@@ -1,106 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NFD_DAEMON_FACE_NDNLP_PARTIAL_MESSAGE_STORE_HPP
#define NFD_DAEMON_FACE_NDNLP_PARTIAL_MESSAGE_STORE_HPP
#include "ndnlp-parse.hpp"
#include "core/event-emitter.hpp"
#include "core/scheduler.hpp"
namespace nfd {
namespace ndnlp {
/** \brief represents a partially received message
*/
class PartialMessage : noncopyable
{
public:
PartialMessage();
bool
add(uint16_t fragIndex, uint16_t fragCount, const Block& payload);
bool
isComplete() const;
/** \brief reassemble network layer packet
*
* isComplete() must be true before calling this method
*
* \exception ndn::Block::Error packet is malformated
* \return network layer packet
*/
Block
reassemble();
public:
EventId m_expiry;
private:
size_t m_fragCount;
size_t m_received;
std::vector<Block> m_payloads;
size_t m_totalLength;
};
/** \brief provides reassembly feature at receiver
*/
class PartialMessageStore : noncopyable
{
public:
explicit
PartialMessageStore(const time::nanoseconds& idleDuration = time::milliseconds(100));
virtual
~PartialMessageStore();
/** \brief receive a NdnlpData packet
*
* \exception ParseError NDNLP packet is malformated
* \exception ndn::Block::Error network layer packet is malformated
*/
void
receiveNdnlpData(const Block& pkt);
/// fires when network layer packet is received
EventEmitter<Block> onReceive;
private:
void
scheduleCleanup(uint64_t messageIdentifier, shared_ptr<PartialMessage> partialMessage);
void
cleanup(uint64_t messageIdentifier);
private:
std::map<uint64_t, shared_ptr<PartialMessage> > m_partialMessages;
time::nanoseconds m_idleDuration;
};
} // namespace ndnlp
} // namespace nfd
#endif // NFD_DAEMON_FACE_NDNLP_PARTIAL_MESSAGE_STORE_HPP
-90
View File
@@ -1,90 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NFD_DAEMON_FACE_NDNLP_SEQUENCE_GENERATOR_HPP
#define NFD_DAEMON_FACE_NDNLP_SEQUENCE_GENERATOR_HPP
#include "common.hpp"
namespace nfd {
namespace ndnlp {
/** \brief represents a block of sequence numbers
*/
class SequenceBlock
{
public:
SequenceBlock(uint64_t start, size_t count);
/** \return{ the pos-th sequence number }
*/
uint64_t
operator[](size_t pos) const;
size_t
count() const;
private:
uint64_t m_start;
size_t m_count;
};
inline uint64_t
SequenceBlock::operator[](size_t pos) const
{
if (pos >= m_count)
throw std::out_of_range("pos");
return m_start + static_cast<uint64_t>(pos);
}
inline size_t
SequenceBlock::count() const
{
return m_count;
}
/** \class SequenceGenerator
* \brief generates sequence numbers
*/
class SequenceGenerator : noncopyable
{
public:
SequenceGenerator();
/** \brief generates a block of consecutive sequence numbers
*
* This block must not overlap with a recent block.
*/
SequenceBlock
nextBlock(size_t count);
private:
/// next sequence number
uint64_t m_next;
};
} // namespace ndnlp
} // namespace nfd
#endif // NFD_DAEMON_FACE_NDNLP_SEQUENCE_GENERATOR_HPP
-130
View File
@@ -1,130 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "ndnlp-slicer.hpp"
#include <ndn-cxx/encoding/encoding-buffer.hpp>
namespace nfd {
namespace ndnlp {
Slicer::Slicer(size_t mtu)
: m_mtu(mtu)
{
this->estimateOverhead();
}
Slicer::~Slicer()
{
}
template<bool T>
static inline size_t
Slicer_encodeFragment(ndn::EncodingImpl<T>& blk,
uint64_t seq, uint16_t fragIndex, uint16_t fragCount,
const uint8_t* payload, size_t payloadSize)
{
size_t totalLength = 0;
// NdnlpPayload
size_t payloadLength = blk.prependByteArray(payload, payloadSize);
totalLength += payloadLength;
totalLength += blk.prependVarNumber(payloadLength);
totalLength += blk.prependVarNumber(tlv::NdnlpPayload);
bool needFragIndexAndCount = fragCount > 1;
if (needFragIndexAndCount) {
// NdnlpFragCount
size_t fragCountLength = blk.prependNonNegativeInteger(fragCount);
totalLength += fragCountLength;
totalLength += blk.prependVarNumber(fragCountLength);
totalLength += blk.prependVarNumber(tlv::NdnlpFragCount);
// NdnlpFragIndex
size_t fragIndexLength = blk.prependNonNegativeInteger(fragIndex);
totalLength += fragIndexLength;
totalLength += blk.prependVarNumber(fragIndexLength);
totalLength += blk.prependVarNumber(tlv::NdnlpFragIndex);
}
// NdnlpSequence
uint64_t sequenceBE = htobe64(seq);
size_t sequenceLength = blk.prependByteArray(
reinterpret_cast<uint8_t*>(&sequenceBE), sizeof(sequenceBE));
totalLength += sequenceLength;
totalLength += blk.prependVarNumber(sequenceLength);
totalLength += blk.prependVarNumber(tlv::NdnlpSequence);
// NdnlpData
totalLength += blk.prependVarNumber(totalLength);
totalLength += blk.prependVarNumber(tlv::NdnlpData);
return totalLength;
}
void
Slicer::estimateOverhead()
{
ndn::EncodingEstimator estimator;
size_t estimatedSize = Slicer_encodeFragment(estimator,
0, 0, 2, 0, m_mtu);
size_t overhead = estimatedSize - m_mtu;
m_maxPayload = m_mtu - overhead;
}
PacketArray
Slicer::slice(const Block& block)
{
BOOST_ASSERT(block.hasWire());
const uint8_t* networkPacket = block.wire();
size_t networkPacketSize = block.size();
uint16_t fragCount = static_cast<uint16_t>(
(networkPacketSize / m_maxPayload) +
(networkPacketSize % m_maxPayload == 0 ? 0 : 1)
);
PacketArray pa = make_shared<std::vector<Block> >();
pa->reserve(fragCount);
SequenceBlock seqBlock = m_seqgen.nextBlock(fragCount);
for (uint16_t fragIndex = 0; fragIndex < fragCount; ++fragIndex) {
size_t payloadOffset = fragIndex * m_maxPayload;
const uint8_t* payload = networkPacket + payloadOffset;
size_t payloadSize = std::min(m_maxPayload, networkPacketSize - payloadOffset);
ndn::EncodingBuffer buffer(m_mtu, 0);
size_t pktSize = Slicer_encodeFragment(buffer,
seqBlock[fragIndex], fragIndex, fragCount, payload, payloadSize);
BOOST_ASSERT(pktSize <= m_mtu);
pa->push_back(buffer.block());
}
return pa;
}
} // namespace ndnlp
} // namespace nfd
Loaded 100 of 494 files, more files were not shown because too many files have changed in this diff. Show more