Compare commits

...
461 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
Steve DiBenedetto 62a939462e doc: streamline NFD homepage and README documentation
refs: #1905

Change-Id: I7e03c05467cadd440efc0e0b1deb3abac930fd78
2014-08-24 19:34:38 -07:00
Alexander Afanasyev 186c316dfe docs: Updated release notes
Change-Id: I4c56a4ed41fc186b44e6ad284c7a9c18a82889ba
2014-08-24 13:07:00 -07:00
Alexander Afanasyev e918621ca8 build: Disable Ethernet face support on OSX with Boost 1.56
Change-Id: Ib3415d5fa1d64e76877bb0f1dcfda783cfe47ca7
Refs: #1877
2014-08-24 13:06:52 -07:00
Alexander Afanasyev 48f5a3ca47 build: Enable detailed version information when built from shallow clone or tarball
Change-Id: Ie2cc05687f4bce136451d316f32e9bab3e82844a
Refs: #1915
2014-08-23 20:02:05 -07:00
Junxiao Shi 986b8497c6 fw: Best Route Strategy version 2
refs #1871

Change-Id: I196a5ff0839f72caf9210af61ad54066242ba9c2
2014-08-23 07:26:28 -07:00
Vince Lehman 26b215c603 rib: Add periodic invalid face clean up
refs: #1744, #1875

Change-Id: I4e6780ef6abb95b2c4ad7c1e6291897693cb551a
2014-08-21 16:14:01 -05:00
Vince Lehman 281ded753b rib: Cancel expiration on unregistration
refs: #1902

Change-Id: I85a75370ecc3677c8a9ebf3a48f3c0857598da2d
2014-08-21 14:51:13 -05:00
Chengyu Fan 1c630ba026 tools: display RIB flags by name in nfd-status page
refs #1870

Change-Id: I327ef9a672dc845f814930c818982fa2700f6402
2014-08-20 13:27:58 -05:00
Junxiao Shi ad3f1cbc87 fw: when Interest matches CS, set straggler timer on PIT entry
refs #1882

Change-Id: I2291783ff3175912ab646fabf247e29dba530e25
2014-08-18 14:05:48 -07:00
Vince Lehman bc05b761a4 rib: Log individual FIB updates
refs: #1868

Change-Id: I400d9bed369c7c27237c2ebd7f3c31865b5c9853
2014-08-18 11:58:15 -05:00
Chengyu Fan 671796414b tools: display face flags and expiration in nfd-status page
refs #1862

Change-Id: I62919316ee503a8a6b816bdce995c693c3b436d2
2014-08-16 17:49:44 -06:00
Alexander Afanasyev 6a75b763f4 build: Do not warn about C99 extensions
Change-Id: I21317771b43bfd3a6d3e1c5a3067e6ff6dc19f9d
Refs: #1865
2014-08-14 19:49:36 -07:00
Alexander Afanasyev f056c11fd4 tools: Process auto-registration for faces that existed prior to start of nfd-autoreg
Change-Id: I3848f1a20a0d816258759f95d427cf91cb3b9713
Refs: #1863
2014-08-14 17:21:40 -07:00
Alexander Afanasyev 81c1a2a267 tools: Enable "all-faces-prefix" option to register prefix for all face (on-demand and non-on-demand)
Change-Id: I6f2e894f2b46ba80c33c501623e47ca08a294795
Refs: #1861
2014-08-14 16:50:21 -07:00
Chengyu Fan a55663d729 tools: fixing bug of misleading lifetime and plural time unit for RIB in HTTP status page
refs #1854 #1855

Change-Id: Ifa112a88210e7882120f529f8c5c3f524d85aa03
2014-08-14 16:50:10 -07:00
Davide Pesavento 4c1a0786db face: increment link layer byte counters in EthernetFace
refs #1780

Change-Id: I27b9c19ef70b976c83f35bcd569dc7eb7f9802cd
2014-08-14 11:13:53 -07:00
Alexander Afanasyev 483efd1668 rib: Disable FaceId check for self-registrations
Change-Id: I9e022d3067c5c4ecb3ec0a10a4446e9af49c68eb
Refs: #1852
2014-08-14 10:51:18 -07:00
Junxiao Shi cbb490a6de fw: NccStrategy always sets pitEntryEntry->maxInterval
Change-Id: I675745cbd40e8d9c6651e6a728deb194ff37d189
refs: #1853
2014-08-13 12:24:24 -07:00
Alexander Afanasyev 585e5a6ff8 rib+tools: Make use of ndn::nfd::FaceMonitor from the ndn-cxx library
NFD still uses its own NotificationStream, as ApiFace needs to be
changed to use library's version of the class.

Change-Id: Ifc5727a555528a1aa48ccf7379fcbb61a33049d7
2014-08-12 11:50:17 -07:00
Junxiao Shi 15b12e759d core: use markers in StatusDataset and NotificationStream
This commit also refactors FaceMonitor as generic NotificationSubscriber,
and refactors AutoregServer to use FaceMonitor.

refs #1837 #1838

Change-Id: I8b40dfae118853d1224c8290cf92e7cc0daa116f
2014-08-10 19:23:09 -07:00
Alexander Afanasyev b3033247ee table: Fix segfault during Fib::removeNextHopFromAllEntries
Change-Id: I905a3c0da2f2a9197942cfeba7fd698b779e6e4a
Refs: #1816
2014-08-08 16:09:44 -07:00
Vince Lehman cd613c5008 rib: Verify face before route registration
refs: #1811

Change-Id: If99f59734b29a46eca4f6139d35361a8563a9010
2014-08-07 14:35:29 -07:00
Wentao Shang e612e2f9bf face: increment link layer byte counters in WebSocketFace
Change-Id: I88b7dea1cbd291765345982ce193700aacd73eb3
Refs: #1781
2014-08-04 17:40:51 -07:00
Chengyu Fan 8a53caf629 tools: include the key name in keylocator as the NFD id in nfd-status
refs #1807

Change-Id: I28f17c459efb720f957f33a6fc27a55edde719ea
2014-08-03 22:52:27 -06:00
Alexander Afanasyev 68bc1e0dce Merge remote-tracking branch 'named-data/master' into release-0.2.0
Change-Id: I5c62c7de04027d40f083c871d6d5b6f42a6f8965
2014-07-28 17:46:13 -07:00
Chengyu Fan 3331cfa76d tools: Visualize per-face link-layer byte counts in nfd-status
refs #1768

Change-Id: Ic70567501903f6d386a9dc5fdc81e70eeb8c5fd7
2014-07-28 14:02:19 -07:00
Alexander Afanasyev 2fdbe86df8 build: Fix bug in instructions to get websocketpp library
Change-Id: I7eb7585a67cd738768b31b51298852ea380d5a04
2014-07-27 20:35:08 -07:00
Junxiao Shi ee5a444344 table: erase NameTree entry when FIB/Measurements/StrategyChoice entry is erased
This commit also optimizes Measurements table to make use of NameTree shortcuts.

refs #1803

Change-Id: Ib0e465750ed5e8ff9ed129a926a7bc852db4e9e1
2014-07-27 17:13:43 -07:00
Junxiao Shi 5dd26c3ef8 face: increment link layer byte counters in StreamFace and DatagramFace
refs #1766

Change-Id: I69377fa561ae1ee845808aa02ae1b85b1771899e
2014-07-24 15:55:31 -07:00
Chengyu Fan 30aa207a8f tools: visualize RIB dataset in nfd-status
refs #1749

Change-Id: Ia11b88187635ffa4eda4b829afd6a20120765d58
2014-07-23 16:02:26 -07:00
Alexander Afanasyev 4e9a98f392 core: Force SegmentPublisher to publish at least one Data packet, which could have empty content
Change-Id: I8338f78ebfa4c2641eaae606b28c1112f06619c9
Refs: #1662
2014-07-23 16:02:26 -07:00
Vince Lehman cd16c83f35 rib: Add RIB dataset publisher
refs: #1662
Change-Id: I97885c07af131a7ea78d074b39df884178f09416
2014-07-23 16:02:26 -07:00
Vince Lehman 5144f829b9 mgmt+core: Moving SegmentPublisher to core/ and removing KeyChain from nfd::AppFace
This change ensures interface uniformity between nfd::AppFace and
ndn::Face and allow now templated version of SegmentPublisher to be used
with either.

Change-Id: I82e29528b13b37bd2ae27ef47db30e8c87c15a38
Refs: #1749
2014-07-23 16:01:27 -07:00
Alexander Afanasyev e5966b7ac3 face: Serializing StreamFace::send(Interest|Data) operations using queue
Change-Id: I254d5e3030c94fac224e81e66bcbc58ffa752c0e
Refs: #1777
2014-07-21 13:48:35 -07:00
Junxiao Shi 632a62089a mgmt: expose link layer counters in Face Dataset
refs #1767

Change-Id: If0b66ead4c2f2741c83396f251cce9a0d83c1520
2014-07-20 19:47:06 -07:00
Junxiao Shi 7b984c6d8e face: reserved FaceIds and NullFace
refs #1620, #1622

Change-Id: I315ae262c7e0813a64b69d3e7d67de61b7b88c55
2014-07-20 14:58:26 -07:00
Alexander Afanasyev 97a9c2c828 rib: Create response Data as shared_ptr to avoid copy inside Face::put
Change-Id: I1fff93f162cda443e09b62db10ea0d7f3c04628d
Refs: #1775
2014-07-20 14:58:16 -07:00
Junxiao Shi 651b75e214 table: capacity limit in PIT NonceList
refs #1770

Change-Id: Ia5722968cca1d9a4bbf3ef19e57be73eac702a69
2014-07-19 10:14:30 -07:00
Junxiao Shi 33152f18b1 face: link layer byte counts in FaceCounters
This commit declares the counters, but does not increment the new counters.

refs #1729

Change-Id: I9cd136fc65955192a92d567629a9aba2df8090f3
2014-07-19 01:14:05 -07:00
Alexander Afanasyev b609f00cbe rib: Fixing bug with RibUnregister when route origin is not specified
Change-Id: Ica250a1c45ed42f1dc7862a12916f893fa846312
Refs: #1773
2014-07-18 17:34:11 -07:00
Alexander Afanasyev 56356b2134 rib: Fixing bug with RibUnregister when route origin is not specified
Change-Id: Ica250a1c45ed42f1dc7862a12916f893fa846312
Refs: #1773
2014-07-18 17:33:50 -07:00
Alexander Afanasyev f67cf0899c rib: Update to properly handle optional ExpirationPeriod in RibRegister command
Change-Id: I9f18988f295a993e53dc03547f2f20967431dc10
Refs: #1772
2014-07-18 17:33:49 -07:00
Alexander Afanasyev 8a093763b6 tools: Corrections and visual improvements for nfd-status-http-server
Change-Id: I123020f023d9dc52268a35d4ad7aa4752e79309b
Refs: #1690
2014-07-18 14:23:11 -07:00
Alexander Afanasyev fb1c808832 rib: Fix to correctly set default expiration for self-registrations
Change-Id: I598fc8b0395118156fe2f394798b9ee846348c4f
Refs: #1772
2014-07-17 15:16:15 -07:00
Chengyu Fan 45d1a76140 tools: nfd-status-http-server: serve XML
refs #1690

Change-Id: Ie5de0b8e5041f91cf9bdf1ec7e2c24cde5ffbe38
2014-07-16 16:23:16 -07:00
Alexander Afanasyev a57f8b4194 fw: set unsatisfy timer in incoming Interest pipeline
Change-Id: I478de1482f79f96f81162ab5e6e8df490061b852
Refs: #1754
2014-07-14 19:59:44 -07:00
Alexander Afanasyev 28d586a16b table: Store shared_ptr<Interest> instead of just Interest to avoid extra copy
Change-Id: I240ea4cbe2c9e14b4c1ca2df87d40da8042b78d1
Refs: #1753
2014-07-14 19:20:55 -07:00
Alexander Afanasyev 7bbe80cf74 mgmt: Change InternalFace::processEvents to accept shared_ptr, instead of weak_ptr
Change-Id: I13af9a4b07a339cf66be1fa8783dc0475ded75f0
Refs: #1753
2014-07-13 12:10:29 -07:00
Vince Lehman 72446ecb93 rib: Unit tests for RibManager
Change-Id: I8096089f6cc8a6eea7be51278b29700c79e68d5c
Refs: #1501
2014-07-11 12:43:04 -07:00
Steve DiBenedetto fbea590074 mgmt: mark tables as configured after applying default configuration
refs: #1743

Change-Id: I8fa82462ff1dc328f70a1c6b335ef42c52d1f06f
2014-07-08 15:30:08 -06:00
Steve DiBenedetto 9bcc88fe8d mgmt,main: configure tables with defaults when missing config section/values
refs: #1743

Change-Id: Id0c24bd2b2e86df763892d194f9c04777a369d0c
2014-07-08 12:51:15 -07:00
Syed Obaid 3313a370a7 rib-manager: deleting expired entries from the rib and fib.
refs #1326
Change-Id: I865bff19da766560f920b1818bdf3eaa91e7dbb1
2014-07-08 12:21:38 -07:00
Alexander Afanasyev 29d1fab41e face: Avoid calls to socket::local_endpoint()
Change-Id: I0cb9152efb95faa105a0d0e08ebfb263581d4d43
Refs: #1741
2014-07-08 10:59:02 -07:00
Alexander Afanasyev 63108c4ace rib: Request Face create/destroy notification as early as possible
This commit does not completely solve the problem, as depending on
ContentStore size and amount of updates, some notification still can be
missed.  However, this commit reduces chances for this to happen.

Change-Id: I5456667c1fba1031146b379195de852f1561fd5d
Refs: #1742
2014-07-07 20:51:04 -07:00
Alexander Afanasyev 7465d5fc0c face: Workaround to Boost.Asio bug 8795 with async_connect
Change-Id: I033a9ae719306f1af605124d982df60b9a8e7372
Refs: #1736
2014-07-07 19:52:19 -07:00
Junxiao Shi 0e173b7690 fw: permit setStragglerTimer with unexpired OutRecord
refs #1733

Change-Id: I899ce2f826d84b048536bcf56aec2ff038534901
2014-07-07 16:15:51 -07:00
Wentao Shang 3d36c2bc6c face: handle exceptions in WebSocket sending path
Change-Id: I231f201d0999f74369fab5ff98b24b2185e45815
Refs: #1732
2014-07-07 12:29:43 -07:00
Junxiao Shi 223271ba39 fw: require valid FaceId in outgoing Interest/Data pipelines
This is to avoid sending via a failed/closed face.

refs #1732

Change-Id: I31b205c2b97185e7955107a2591f8c4d2b7f0cc0
2014-07-03 22:52:00 -07:00
Syed Obaid 818e8a609e nfdc: setting default expiration time to time::milliseconds::max()
refs #1727

Change-Id: I6da174d18053fa05cf10804d398605d076475fe8
2014-07-03 00:59:46 -07:00
Alexander Afanasyev 84e2977be7 docs: Update source installation instructions and other additions
Change-Id: Ie4976f728e0f091d829ba05539eb27c2e328e496
Refs: #1728
2014-07-02 15:26:06 -07:00
Junxiao Shi dda0b467bc tools: autoreg uses RibRegisterCommand
refs #1710

Change-Id: I158817af5f25d97f11a81b4e03d2523157f49c7d
2014-07-02 15:25:44 -07:00
Junxiao Shi a753f1b988 tools: autoconfig prefix registration changes
After establishing HUB connectivity,
the prefix registration for TESTBED_PREFIX (/ndn) sets:
* Origin=autoconf
* Cost=100
* ExpirationPeriod=(practically) infinity

refs #1726

Change-Id: I7d2cf0982626c02efa6fbded677e47cdb14336ef
2014-07-02 14:47:02 -07:00
Alexander Afanasyev 40ee381e32 docs: Release notes for version 0.2.0
Change-Id: Ied19433005fb01dee3f182ed2848cb8cf5ab37b0
Refs: #1714
2014-07-01 22:01:10 -07:00
Haowei Yuan d5b68593cc core: Commented out SSE4.2 instruction set related code block in city-hash.c
Change-Id: I40cd04c0edc44922bd43a07cf5aa907072a884c8
Refs: #1721
2014-07-01 20:37:38 -07:00
Alexander Afanasyev 583760b22b face: Cleaning up onFail EventEmitter after event is fired from Face::fail
Change-Id: I3e90ae4af6843c2cd6d24835e0d3dab98f4c94df
Refs: #1718
2014-06-30 23:14:53 -07:00
Davide Pesavento a75305892c face: remove pointless method UdpFace::handleFirstReceive
Simply call DatagramFace::receiveDatagram directly.

Change-Id: Icec976fb9f4a008d08ece56c28ac652ea615bc76
2014-06-30 23:14:53 -07:00
Alexander Afanasyev 40c61f77cc tools: Showing ExpirationPeriod if it is present in FaceStatus
Change-Id: I8e5b1350179830a1d12866c02c16393068e06369
Refs: #1686
2014-06-30 23:14:49 -07:00
Alexander Afanasyev e515f0a989 face: Moving idle UdpFace closing logic to UdpFace class
Change-Id: Ia7310fa18681f17d93c8214ce744da909fea7022
Refs: #1686
2014-06-30 19:54:33 -07:00
Alexander Afanasyev d3967a2e11 tools: Visualizing local and on-demand Face flags
Change-Id: I639da99bc009777c316b52333f7a8bc4d9b02c7a
Refs: #1716
2014-06-30 12:24:19 -07:00
Junxiao Shi 6b597e7e23 core: bump version to 0.2.0
refs #1709

Change-Id: I52dadd87ebc1f36f2b48070a4e809f07716369d7
2014-06-30 10:16:38 -07:00
Vince Lehman 4387e78005 rib: Generate FIB updates using route flags
refs: #1325

Change-Id: I5c567da1c06819caeba5cc5b024914666ba70ab6
2014-06-29 17:41:49 -07:00
Davide Pesavento dc26b2796a build: minor fix for python3 compatibility.
refs #1302 note #12

Change-Id: I58679c7b5223adf15a9317c53b76e5e77882bf17
2014-06-27 16:41:51 +02:00
Alexander Afanasyev d9479aa9fa face: Fixing compilation failure with libpcap version 1.0.0
Change-Id: If285f1ed11a4e66bdafb50cbb7314faaed3d95f7
Refs: #1703
2014-06-26 13:54:22 -07:00
Vince Lehman 14e76dd70e rib: Add "common.hpp" to rib/face-entry.hpp
refs: #1702

Change-Id: I94a56590cbe14a511fd8b156a9a3523b984587b4
2014-06-26 15:51:10 -05:00
Davide Pesavento 0e76f628d2 face: disable path MTU discovery on unicast UDPv4 faces.
refs #1651

Change-Id: I81a664f6dedac8e983e2459700d2cd8e358a4ef4
2014-06-26 07:42:34 +02:00
Junxiao Shi 1983804963 table: set initial lifetime for Measurements entry
refs #1665

Change-Id: Idc83d158616c7a1833d2dbb33e25c35ec1e47f32
2014-06-22 23:36:17 -07:00
Syed Obaid f93f9d9203 nfdc: support for specifying Origin in unregister command.
refs #1688

Change-Id: I8fb42eb4935902f59991c66c0a0fff33dccea4d3
2014-06-22 17:58:12 -07:00
Chengyu Fan ee92fc7543 docs, tools: expand nfd-status manpage for -c -s -x
Refs: #1689

Change-Id: I5b04f8a89e2b267d07339237ec42dceda3724125
2014-06-21 15:11:05 -06:00
Steve DiBenedetto 2aa4eca578 face: prevent creation of duplicate tcp/udp faces due to async calls
refs: #1680

Change-Id: I0e685d6bde1f6745902c86f782d41c9070aecb21
2014-06-20 19:37:20 -07:00
Alexander Afanasyev 4b3fc86c96 table: Offload the implicit digest calculation to the library
Change-Id: I8577ec3ee194d639cce74b53fb5f02c7e718cbc3
Refs: #1678
2014-06-20 17:29:19 -07:00
Wentao Shang 93ef6c971f test: basic unit-test for WebSocket face
Change-Id: I41dcc2ecff57225db1aff8e359d507f0e89d4c96
Refs: #1553
2014-06-20 12:25:43 -07:00
Alexander Afanasyev 6fce07859d tools: Set broadcast strategy for HUB discovery prefix
Change-Id: Iaaf680e73be302b4068410e5c00260f3798b47fe
Refs: #1595
2014-06-20 10:00:35 -07:00
Alexander Afanasyev dc01700b45 face: Switching to 2 sockets in MulticastUdpFace for sending and receiving
To send over UDP multicast, we should not bind to multicast address.
This is true at least on OSX 10.9, which generates "Can't assign
requested address" error (error code: 49).  However, without binding to
the multicast address, the socket may receive unnecessary unrelated
packets.  To solve this problem, this commit splits sending and
receiving into two sockets, one for sending and one for receiving.

Change-Id: Ibce05c7071fd683a26b3c88cd2a168546c5dc605
Refs: #1668
2014-06-20 09:55:29 -07:00
Alexander Afanasyev cd591e1781 face: Parametrizing DatagramFace to correct MulticastUdpFace logging
Change-Id: I8a117dd0209b3babe3b7df35cd692c268c059866
Refs: #1675
2014-06-20 09:46:11 -07:00
Yingdi Yu 676a55a780 rib: Change validator configuration since ValidatorConfig can check timestamp now
Refs: #1643

Change-Id: I0a0b55fc4b817d6c554de800cd483cdeb6af56b8
2014-06-19 09:02:41 -07:00
Alexander Afanasyev bb964663a9 docs: Updating list of NFD authors
Change-Id: I485a204af624ae7800fc3a151d86ec91ae6cacb3
2014-06-18 16:30:07 -07:00
Syed Obaid 4ae0ce3108 nfdc: support for specifying expiration time and origin during prefix registration
refs #1664

Change-Id: I705a15884ec59e00145a4b7d9241aefee11ef64b
2014-06-17 18:01:56 -07:00
Junxiao Shi af6569aa7e core: unify randomization
Non-security randomizations are changed to use boost::random,
with a global random number generator.

refs #1369

Change-Id: I5000fd02f170fa47058af790e2bea767f9c65650
2014-06-17 17:34:39 -07:00
Vince 12e49466bb rib: Implement RIB as trie
refs: #1271

Change-Id: Idbd6d4d67f8a88b474ea0b20280c79e367bc98e5
2014-06-17 14:11:09 -05:00
Alexander Afanasyev 554ef7aae2 tools: Registering /localhop/ndn-autoconf/hub prefix towards all UDP4 multicast faces
Change-Id: I0cd619f9c600862e4402bd6a1811751706223575
Refs: #1595
2014-06-16 12:51:15 -07:00
Alexander Afanasyev c026d25adb tests: Small fixes to eliminate false test failures due to recent changes in the library
Change-Id: I4656809d39d77248bfe9652f173861f80d4cd615
2014-06-16 12:51:12 -07:00
Alexander Afanasyev 1886180829 faces: Replace deadline_timer usage in TcpChannel with Scheduler-based events
Change-Id: I37a7a3203b3187e029697a21e3314cfacbbed314
Refs: #1368
2014-06-13 20:30:55 -07:00
Alexander Afanasyev f86b5c44ae build: Disable unneeded-internal-declaration warning
Change-Id: I48c99d7a1c224faebc63339d40f700a9a675d2da
Refs: #1588
2014-06-13 20:29:15 -07:00
Steve DiBenedetto 3a4f83dc7e mgmt, main: add "tables" configuration file section and processor
refs: #1623

Change-Id: If54097ba738381f7a75d755933e20b35387ff1d4
2014-06-13 17:10:41 -07:00
Alexander Afanasyev 0417d2adf7 tools: Add retrieval of ChannelStatus and StrategyChoice datasets
Change-Id: I55afae058845a934321ac242e80bc2b9ab6d9b15
Fixes: #1503, #1525, #1652
2014-06-13 12:27:40 -07:00
Steve DiBenedetto ef04f27892 face, mgmt: add channel status dataset publisher
Expose channel maps in protocol factories

Change-Id: I057b1bba638bfc9372867318653d71ba7d0e9888
Refs: #1631, #1653
2014-06-13 11:30:36 -07:00
Junxiao Shi 08d07a764e face: avoid multiple onFail events
refs #1497

Change-Id: I8fda3fea5cd8a314b30eef45da104109e9748afc
2014-06-10 20:41:42 -07:00
Alexander Afanasyev 281b916a35 tables: Adjust pre-allocated CS entry queue on Cs::setLimit call
Change-Id: I7611dfb671060864e40cadb707ad0a89f0359c07
Fixes: #1646
2014-06-09 08:44:03 +03:00
Steve DiBenedetto 3fff5614a5 mgmt: publish Strategy Choice dataset
refs: #1632

Change-Id: I4ed09d191433fd80071367e7b2ffcd2ac81c5c17
2014-06-07 22:35:39 -07:00
Alexander Afanasyev c87bbf8d7f face: "Closing" WebSocket face when WebSocket tunnel closes
Change-Id: Ief2d643b09469eac7fc92aa5139e41bcb8d1e210
Refs: #1637
2014-06-06 07:36:54 +03:00
Alexander Afanasyev b56c5b91e9 tests: Prevent false failures of test cases for Ethernet face
Change-Id: I2a767278560209c2e1ee88a3321e6b8e320039fb
Refs: #1393
2014-06-06 07:36:51 +03:00
Alexander Afanasyev 5959b014c5 mgmt: Reinitialize multicast faces and partially reload config file on HUP signal
The following elements from the config file are reloaded:
- effective user/group
- log levels
- multicast faces (enable/disable)
- security

Change-Id: I6ddf124702b30610dd0404d8fbaa9a9d800f02bf
Refs: #1584
2014-06-04 09:15:03 +03:00
Alexander Afanasyev 251f3c1317 face: fire onFail event on WebSocket and Ethernet face close
Change-Id: I3d24c7b2e5003253ff04dab68ec1a2cb37b7d023
Refs: #1637
2014-06-03 18:37:04 +03:00
Alexander Afanasyev f4e89b4000 src: Small improvements
Change-Id: I9850cd6ec2330482915f815d94a2ac2ccaeae7f1
2014-05-31 15:54:18 +03:00
Alexander Afanasyev 58ea458a10 build: Updated precompiled header support (enabled by default)
Change-Id: Iaab62c740ac87b84256a3f71d934760865a54be5
2014-05-31 15:51:18 +03:00
Junxiao Shi 5cc1e34aca core: FaceUri recognizes IPv4-mapped IPv6 address
refs #1635

Change-Id: I5fc54b3945fc77869a4531a31c1fc27e7c434447
2014-05-29 06:32:16 -07:00
Junxiao Shi b5888d2ed9 table: make StrategyChoice enumerable
refs #1633

Change-Id: I203d76645649cc8ef2e3dcfbd254fa4ebab6e9dc
2014-05-26 13:53:15 -07:00
Steve DiBenedetto 2599928409 mgmt: update face created Control Response with URI's canonical form
refs: #1619

Change-Id: I7c0304ce390de9757d2352e182a075ac902020d2
2014-05-22 15:27:06 -06:00
Junxiao Shi 02e32247ac fw: RttEstimator
refs #1568

Change-Id: Ife59d8d4715e293aec44f8fbe24582bb684452c4
2014-05-20 01:21:34 -07:00
Junxiao Shi a3295741d6 rib: fix FibAddNextHopCommand parameters
refs #1618

Change-Id: I6f8003bee785f0eaaadbf4fa3c5c8281a2cf48da
2014-05-16 22:40:10 -07:00
Junxiao Shi da006f5a05 fw: incoming Data pipeline avoid sending to inFace
refs #1556

Change-Id: I1e38e3142f9c6536180f2aa494d7e2032ad76c2d
2014-05-16 11:18:00 -07:00
Alexander Afanasyev b3893c9950 src: Updating code to compile with the latest ndn-cxx library
This commit includes updates against the latest Face API and replaces
uses of deprecated methods.

Change-Id: I33ad398d26f8faf9f9627ff329ce0936e0911ab2
2014-05-15 21:52:26 -07:00
Alexander Afanasyev 8552a38c1d build: Enabling ability to use precompiled headers and some other build fixes
Change-Id: If2b216e5674fc762338929026733f3dcb801bb1b
Refs: #1588
2014-05-15 21:52:23 -07:00
Junxiao Shi d938a6bb89 fw: Strategy::sendInterest allows changing Nonce
This commit also includes some tweaks in forwarding pipelines.

refs #1596

Change-Id: I65a4129be24089357b28fa9d35a3451e0d9ae258
2014-05-15 11:37:53 -07:00
Alexander Afanasyev f6980284e6 src: Remove unnecessary uses of boost::cref in make_shared and replace boost::cref/boost::ref with just cref/ref
In some cases, due to argument-dependent lookup, it is necessary to use
ndn::ref, instead of just ref.

Change-Id: I682180a007609535855f77511b49622154ad4f11
Refs: #1591
2014-05-15 09:52:28 -07:00
Alexander Afanasyev 39a7d6ab00 build: Fixing dependency detection
When detecting location of the library, `includes` and `libpath`
variables must be used instead of `cxxflags` and `linkflags` to specify
path to includes and path to the libraries.

Change-Id: I81048a9c80f3e743630a0e80231fc6290aa782ec
2014-05-12 17:29:57 -07:00
Alexander Afanasyev 0c3e93d341 docs: Updating README.md to include links to NFD's homepage and NFD wiki
Change-Id: I3ccc66826b2a366976db003396e99c46047c6ba8
2014-05-12 15:52:22 -07:00
Alexander Afanasyev f7bbe47a15 build: Small fix to support Python3
Change-Id: I8e6218522ee9f03c9d9ee6357609f9003cc0cbad
Refs: #1302
2014-05-11 21:39:15 -07:00
Junxiao Shi 66f91f87a3 table: PIT entry InRecord/OutRecord getters
refs #1569

Change-Id: I52d9516fa6154036904e163f918890579a745e4f
2014-05-10 23:58:08 -07:00
Alexander Afanasyev 37a05f6f2a startup: Adding example upstart scripts (e.g., for Ubuntu Linux)
Change-Id: Ia43e0e5e83d54d4f5bff2120ca3424b43849feb2
Refs: #1188
2014-05-10 14:07:52 -07:00
Alexander Afanasyev c6e6142aa1 startup: Adding launchd.plists to manage run of nfd/nrd on OSX
Change-Id: Ib457fe129ea6c514ab442ea57ecab84644c2e150
Refs: #1188
2014-05-10 14:07:01 -07:00
Alexander Afanasyev 47fc9400a3 docs: Small fix in FAQ
Change-Id: Ie08ac93eb47297d3ac52813b7230f7472f12a2e6
2014-05-10 14:06:57 -07:00
Davide Pesavento a4e71b4ee2 build: simplify Unix sockets check.
Change-Id: Ib7b8691aca2686deaadaf7215e05ad52ce950a68
2014-05-08 17:28:59 -07:00
Davide Pesavento f0ae4421a6 face: enable immediate mode for packet capture on EthernetFace.
Fixes #1511

Change-Id: I6551de8d650c5d14e27713258d958ac3c77a1649
2014-05-08 17:16:43 -07:00
Wentao Shang 53df163b62 face: Implement WebSocket channel, face, and factory.
Change-Id: Ic4dbb1abdbbdbec028746ba14b11be8ab9cc1edb
Refs: #1468
2014-05-08 17:16:43 -07:00
Alexander Afanasyev ff489a230a core: Fixing regression in PrivilegeHelper that prevented running as non-root
PrivilegeHelper was properly initialized only when general section was
present.  When section was omitted, s_privilegedUid/s_privilegedGid/s_normalUid/s_normalGid
variables was not properly initialized (set to 0), resulting in
exception during the subsequent PrivilegeHelper::drop call.

Change-Id: Iffd7f05e7e6c86d227da2c9b7920ca6e3b607211
2014-05-08 17:16:43 -07:00
Chengyu Fan 514ed5e913 nfd-status: Define format and implement --xml option
The ether URI format "ether://01:00:5e:00:17:aa" violates
the URI specification, so it has been changed to
ether://[01:00:5e:00:17:aa] in this commit.

refs: #1438

Change-Id: I1218374b75f919a5e1ab158bbab2e217e64aced3
2014-05-08 17:16:43 -07:00
Steve DiBenedetto 24b9a64298 core: add support for temporary privilege drop and elevation
Added "user" and "group" options to general section of configuration file.
NFD will attempt to set the effective group and user id to these values
after initializing all management modules.

Added privilege helper to drop and temporarily elevate privileges on demand.

Updated README.md with instructions to configure NFD to drop privileges.

Added handler for general confguration file section.

refs: #1370

Change-Id: Id27140ad2dc2ca14751058691511132a35649d58
2014-05-08 17:14:52 -07:00
499 changed files with 49347 additions and 25846 deletions

No files matched your search

+3 -1
View File
@@ -1,6 +1,8 @@
.DS*
.waf-1*
.waf3-*
.lock*
**/*.pyc
build/
VERSION
unit-tests.conf
+3
View File
@@ -0,0 +1,3 @@
[submodule "websocketpp"]
path = websocketpp
url = https://github.com/zaphoyd/websocketpp.git
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
+23
View File
@@ -0,0 +1,23 @@
# -*- 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
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 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):
conf.define('HAVE_ASIO_PCAP_SUPPORT', 1)
conf.env['HAVE_ASIO_PCAP_SUPPORT'] = True
+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']
flags = CompilerFlags()
Logs.warn('The code has not yet been tested with %s compiler' % cxx)
defaultFlags += ['-pedantic', '-Wall', '-Wno-long-long']
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
+2 -2
View File
@@ -18,8 +18,8 @@ def checkDependency(self, name, **kw):
kw['mandatory'] = kw.get('mandatory', True)
if root:
isOk = self.check_cxx(cxxflags="-I%s/include" % root,
linkflags="-L%s/lib" % root,
isOk = self.check_cxx(includes="%s/include" % root,
libpath="%s/lib" % root,
**kw)
else:
isOk = self.check_cxx(**kw)
+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', [])
+153
View File
@@ -0,0 +1,153 @@
#! /usr/bin/env python
# encoding: utf-8
# Alexander Afanasyev (UCLA), 2014
"""
Enable precompiled C++ header support (currently only clang++ and g++ are supported)
To use this tool, wscript should look like:
def options(opt):
opt.load('pch')
# This will add `--with-pch` configure option.
# Unless --with-pch during configure stage specified, the precompiled header support is disabled
def configure(conf):
conf.load('pch')
# this will set conf.env.WITH_PCH if --with-pch is specified and the supported compiler is used
# Unless conf.env.WITH_PCH is set, the precompiled header support is disabled
def build(bld):
bld(features='cxx pch',
target='precompiled-headers',
name='precompiled-headers',
headers='a.h b.h c.h', # headers to pre-compile into `precompiled-headers`
# Other parameters to compile precompiled headers
# includes=...,
# export_includes=...,
# use=...,
# ...
# Exported parameters will be propagated even if precompiled headers are disabled
)
bld(
target='test',
features='cxx cxxprogram',
source='a.cpp b.cpp d.cpp main.cpp',
use='precompiled-headers',
)
# or
bld(
target='test',
features='pch cxx cxxprogram',
source='a.cpp b.cpp d.cpp main.cpp',
headers='a.h b.h c.h',
)
Note that precompiled header must have multiple inclusion guards. If the guards are missing, any benefit of precompiled header will be voided and compilation may fail in some cases.
"""
import os
from waflib import Task, TaskGen, Logs, Utils
from waflib.Tools import c_preproc, cxx
PCH_COMPILER_OPTIONS = {
'clang++': [['-include'], '.pch', ['-x', 'c++-header']],
'g++': [['-include'], '.gch', ['-x', 'c++-header']],
}
def options(opt):
opt.add_option('--without-pch', action='store_false', default=True, dest='with_pch', help='''Try to use precompiled header to speed up compilation (only g++ and clang++)''')
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]
conf.env.CXXPCH_EXT = flags[1]
conf.env.CXXPCH_FLAGS = flags[2]
@TaskGen.feature('pch')
@TaskGen.before('process_source')
def apply_pch(self):
if not self.env.WITH_PCH:
return
if getattr(self.bld, 'pch_tasks', None) is None:
self.bld.pch_tasks = {}
if getattr(self, 'headers', None) is None:
return
self.headers = self.to_nodes(self.headers)
if getattr(self, 'name', None):
try:
task = self.bld.pch_tasks[self.name]
self.bld.fatal("Duplicated 'pch' task with name %r" % self.name)
except KeyError:
pass
out = '%s.%d%s' % (self.target, self.idx, self.env['CXXPCH_EXT'])
out = self.path.find_or_declare(out)
task = self.create_task('gchx', self.headers, out)
# target should be an absolute path of `out`, but without precompiled header extension
task.target = out.abspath()[:-len(out.suffix())]
self.pch_task = task
if getattr(self, 'name', None):
self.bld.pch_tasks[self.name] = task
@TaskGen.feature('cxx')
@TaskGen.after_method('process_source', 'propagate_uselib_vars')
def add_pch(self):
if not (self.env['WITH_PCH'] and getattr(self, 'use', None) and getattr(self, 'compiled_tasks', None) and getattr(self.bld, 'pch_tasks', None)):
return
pch = None
# find pch task, if any
if getattr(self, 'pch_task', None):
pch = self.pch_task
else:
for use in Utils.to_list(self.use):
try:
pch = self.bld.pch_tasks[use]
except KeyError:
pass
if pch:
for x in self.compiled_tasks:
x.env.append_value('CXXFLAGS', self.env['CXXPCH_F'] + [pch.target])
class gchx(Task.Task):
run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CPPFLAGS} ${CXXPCH_FLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXXPCH_F:SRC} ${CXX_SRC_F}${SRC[0].abspath()} ${CXX_TGT_F}${TGT[0].abspath()}'
scan = c_preproc.scan
color = 'BLUE'
ext_out=['.h']
def runnable_status(self):
try:
node_deps = self.generator.bld.node_deps[self.uid()]
except KeyError:
node_deps = []
ret = Task.Task.runnable_status(self)
if ret == Task.SKIP_ME and self.env.CXX_NAME == 'clang':
t = os.stat(self.outputs[0].abspath()).st_mtime
for n in self.inputs + node_deps:
if os.stat(n.abspath()).st_mtime > t:
return Task.RUN_ME
return ret
+2 -2
View File
@@ -12,8 +12,8 @@ class sphinx_build(Task.Task):
def __str__(self):
env = self.env
src_str = ' '.join([a.nice_path()for a in self.inputs])
tgt_str = ' '.join([a.nice_path()for a in self.outputs])
src_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.inputs])
tgt_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.outputs])
if self.outputs: sep = ' -> '
else: sep = ''
return'%s [%s]: %s%s%s\n'%(self.__class__.__name__.replace('_task',''),
+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 -11
View File
@@ -7,29 +7,22 @@
from waflib import Options
BOOST_ASIO_HAS_LOCAL_SOCKETS_CHECK = '''
#include <iostream>
#include <boost/asio.hpp>
int main() {
#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS
return 0;
#else
#ifndef BOOST_ASIO_HAS_LOCAL_SOCKETS
#error "Unix sockets are not available on this platform"
#endif
return 0;
}
'''
def addUnixOptions(self, opt):
opt.add_option('--force-unix-socket', action='store_true', default=False,
dest='force_unix_socket', help='''Forcefully enable UNIX sockets support''')
dest='force_unix_socket', help='''Forcefully enable Unix sockets support''')
setattr(Options.OptionsContext, "addUnixOptions", addUnixOptions)
def configure(conf):
def boost_asio_has_local_sockets():
return conf.check_cxx(features="cxx",
msg='Checking if UNIX sockets are supported',
return conf.check_cxx(msg='Checking if Unix sockets are supported',
fragment=BOOST_ASIO_HAS_LOCAL_SOCKETS_CHECK,
use='BOOST', mandatory=False)
features='cxx', use='BOOST', mandatory=False)
if conf.options.force_unix_socket or boost_asio_has_local_sockets():
conf.define('HAVE_UNIX_SOCKETS', 1)
+79
View File
@@ -0,0 +1,79 @@
# encoding: utf-8
from waflib import Options, Logs, Errors
from waflib.Configure import conf
import re
def addWebsocketOptions(self, opt):
opt.add_option('--without-websocket', action='store_false', default=True,
dest='with_websocket',
help='Disable WebSocket face support')
setattr(Options.OptionsContext, "addWebsocketOptions", addWebsocketOptions)
@conf
def checkWebsocket(self, **kw):
if not self.options.with_websocket:
return
isMandatory = kw.get('mandatory', True)
self.start_msg('Checking for WebSocket includes')
try:
websocketDir = self.path.find_dir('websocketpp/websocketpp')
if not websocketDir:
raise Errors.WafError('Not found')
versionFile = websocketDir.find_node('version.hpp')
if not websocketDir:
raise Errors.WafError('Corrupted: WebSocket version file not found')
try:
txt = versionFile.read()
except (OSError, IOError):
raise Errors.WafError('Corrupted: cannot read WebSocket version file')
# Looking for the following:
# static int const major_version = 0;
# static int const minor_version = 5;
# static int const patch_version = 1;
version = [None, None, None]
majorVersion = re.compile('^static int const major_version = (\\d+);$', re.M)
version[0] = majorVersion.search(txt)
minorVersion = re.compile('^static int const minor_version = (\\d+);$', re.M)
version[1] = minorVersion.search(txt)
patchVersion = re.compile('^static int const patch_version = (\\d+);$', re.M)
version[2] = patchVersion.search(txt)
if not version[0] or not version[1] or not version[2]:
raise Errors.WafError('Corrupted: cannot detect websocket version')
self.env['WEBSOCKET_VERSION'] = [i.group(1) for i in version]
# todo: version checking, if necessary
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:
self.end_msg(str(error), color='RED')
Logs.warn('If you are using git NFD repository, checkout websocketpp submodule: ')
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/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")
else:
self.end_msg(str(error))
+20 -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
@@ -38,6 +38,7 @@ volunteers.
* Colorado State University
* Steve DiBenedetto <http://www.cs.colostate.edu/~dibenede/>
* Chengyu Fan <chengyu@cs.colostate.edu>
* Christos Papadopoulos <http://www.cs.colostate.edu/~christos/>
* University Pierre & Marie Curie, Sorbonne University
@@ -60,4 +61,22 @@ volunteers.
* The University of Memphis
* 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
---------------
+12 -20
View File
@@ -1,6 +1,11 @@
NFD - Named Data Networking Forwarding Daemon
=============================================
For complete documentation, including step-by-step installation instructions and
tutorials, please visit the [NFD homepage](http://named-data.net/doc/NFD/).
## Overview
NFD is a network forwarder that implements and evolves together with the Named Data
Networking (NDN) [protocol](http://named-data.net/doc/ndn-tlv/). After the initial
release, NFD will become a core component of the
@@ -16,10 +21,11 @@ limitation, refer to
NFD is developed by a community effort. Although the first release was mostly done by the
members of [NSF-sponsored NDN project team](http://named-data.net/project/participants/),
it already contains significant contributions from people outside the project team (for
more details, refer to [`AUTHORS.md`](https://github.com/named-data/NFD/blob/master/AUTHORS.md)).
We strongly encourage participation from all interested parties, since broader community
support is key for NDN to succeed as a new Internet architecture. Bug reports and
feedback are highly appreciated and can be made through
more details, refer to
[`AUTHORS.md`](https://github.com/named-data/NFD/blob/master/AUTHORS.md)). We strongly
encourage participation from all interested parties, since broader community support is
key for NDN to succeed as a new Internet architecture. Bug reports and feedback are
highly appreciated and can be made through
[Redmine site](http://redmine.named-data.net/projects/nfd) and the
[ndn-interest mailing list](http://www.lists.cs.ucla.edu/mailman/listinfo/ndn-interest).
@@ -32,19 +38,5 @@ algorithms; over time, better implementations may emerge within the same design
NFD will keep evolving in three aspects: improvement of the modularity framework, keeping
up with the NDN protocol spec, and addition of other new features. We hope to keep the
modular framework stable and lean, allowing researchers to implement and experiment
with various features, some of which may eventually work into the protocol spec.
The design and development of NFD benefited from our earlier experience with
[CCNx](http://www.ccnx.org) software package. However, NFD is not in any part derived from
CCNx codebase and does not maintain compatibility with CCNx.
Documentation
-------------
For more information refer to
* [Release notes `docs/RELEASE_NOTES.rst`](https://github.com/named-data/NFD/blob/master/docs/RELEASE_NOTES.rst)
* [Installation instruction `docs/INSTALL.rst`](https://github.com/named-data/NFD/blob/master/docs/INSTALL.rst)
* [Hints on configuration `docs/README.rst`](https://github.com/named-data/NFD/blob/master/docs/README.rst)
* Other documentation in [`docs/`](https://github.com/named-data/NFD/blob/master/docs) folder
modular framework stable and lean, allowing researchers to implement and experiment with
various features, some of which may eventually work into the protocol spec.
+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
+90 -23
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_COMMON_HPP
#define NFD_COMMON_HPP
@@ -39,43 +40,109 @@
#define PROTECTED_WITH_TESTS_ELSE_PRIVATE private
#endif
#include <ndn-cxx/common.hpp>
/** \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 <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#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>
#include <boost/assert.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
#include <boost/ref.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/throw_exception.hpp>
namespace nfd {
using boost::noncopyable;
using boost::scoped_ptr;
using std::size_t;
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 boost::noncopyable;
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
+127
View File
@@ -0,0 +1,127 @@
Starting NFD on OSX >= 10.8
===========================
OSX provides a standard way to start system daemons, monitor their health, and restart
when they die.
Initial setup
-------------
Edit `net.named-data.nfd` correcting paths for `nfd` binary, configuration and log files.
# Copy launchd.plist for NFD
sudo cp net.named-data.nfd.plist /Library/LaunchDaemons/
sudo chown root /Library/LaunchDaemons/net.named-data.nfd.plist
### Assumptions in the default scripts
* `nfd` is installed into `/usr/local/bin`
* Configuration 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 `ndn` user does not exists, it needs to be manually created (procedure copied from
[macports script](https://trac.macports.org/browser/trunk/base/src/port1.0/portutil.tcl)).
Update uid/gid if 6363 is already used.
# Create user `ndn`
sudo dscl . -create /Users/ndn UniqueID 6363
# These are implicitly added on Mac OSX Lion. AuthenticationAuthority
# causes the user to be visible in the Users & Groups Preference Pane,
# and the others are just noise, so delete them.
# https://trac.macports.org/ticket/30168
sudo dscl . -delete /Users/ndn AuthenticationAuthority
sudo dscl . -delete /Users/ndn PasswordPolicyOptions
sudo dscl . -delete /Users/ndn dsAttrTypeNative:KerberosKeys
sudo dscl . -delete /Users/ndn dsAttrTypeNative:ShadowHashData
sudo dscl . -create /Users/ndn RealName "NDN User"
sudo dscl . -create /Users/ndn Password "{*}"
sudo dscl . -create /Users/ndn PrimaryGroupID 6363
sudo dscl . -create /Users/ndn NFSHomeDirectory /var/empty
sudo dscl . -create /Users/ndn UserShell /usr/bin/false
# Create group `ndn`
sudo dscl . -create /Groupsndn Password "{*}"
sudo dscl . -create /Groups/ndn RealName "NDN User"
sudo dscl . -create /Groups/ndn PrimaryGroupID 6363
### 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 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:
# 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.
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:
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 management of faces and updating strategy choice by
anybody, 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 `localhost_daemons_nfd.ndncert` file:
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
Disable auto-start
------------------
sudo launchctl unload -w /Library/LaunchDaemons/net.named-data.nfd.plist
@@ -0,0 +1,23 @@
<?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.nfd</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/nfd</string>
<string>--config</string>
<string>/usr/local/etc/ndn/nfd.conf</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>HOME</key><string>/usr/local/var/lib/ndn/nfd</string>
</dict>
<key>Debug</key><true/>
<key>Disabled</key><true/>
<key>KeepAlive</key><true/>
<key>StandardErrorPath</key><string>/usr/local/var/log/ndn/nfd.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
+125
View File
@@ -0,0 +1,125 @@
Starting NFD on Linux with upstart
==================================
Some Linux distributions, such as Ubuntu, use [upstart](http://upstart.ubuntu.com/) as a
standard mechanism to start system daemons, monitor their health, and restart
when they die.
Initial setup
-------------
* Edit `nfd.conf` correcting paths for `nfd` binary, configuration and log files.
* Copy upstart config file for NFD
sudo cp nfd.conf /etc/init/
### Assumptions in the default scripts
* `nfd` is installed into `/usr/local/bin`
* Configuration 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 `ndn` user and group does not exists, they need to be manually created.
# Create group `ndn`
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 deamon.
# 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; \
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 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:
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 management of faces and updating strategy choice by
anybody, 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 `localhost_daemons_nfd.ndncert` file:
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 script, `nfd` daemon will automatically run after the reboot.
To manually start them, use the following commands:
sudo start nfd
Disable auto-start
------------------
To stop `nfd` daemon, use the following commands:
sudo stop nfd
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
+26
View File
@@ -0,0 +1,26 @@
# nfd.conf
#
# NDN Forwarding Daemon
description "NDN forwarding daemon"
start on (local-filesystems and net-device-up IFACE!=lo)
stop on runlevel [!2345]
respawn
respawn limit unlimited
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
+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
+11
View File
@@ -505,6 +505,16 @@ uint128 CityHash128(const char *s, size_t len) {
CityHash128WithSeed(s, len, uint128(k0, k1));
}
// NFD NOTE
// The following code block is commented out due to the following reasons.
// - It requires the "citycrc.h" header file, which is not included in the
// NFD code base.
// - The functions defined below are not used by the current NFD
// implementation.
// The header file "citycrc.h" is available at
// https://code.google.com/p/cityhash/source/browse/trunk/src/citycrc.h
/*
#ifdef __SSE4_2__
#include <citycrc.h>
#include <nmmintrin.h>
@@ -637,3 +647,4 @@ uint128 CityHashCrc128(const char *s, size_t len) {
}
#endif
*/
+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
-343
View File
@@ -1,343 +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_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> m_eventName;
* To subscribe to an event:
* eventSource->m_eventName += eventHandler;
* Multiple functions can subscribe to the same event.
* To trigger an event:
* m_eventName(args);
* To clear event subscriptions:
* m_eventName.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)();
}
}
// 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);
}
}
// 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);
}
}
// 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);
}
}
// 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);
}
}
} // 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
-165
View File
@@ -1,165 +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-monitor.hpp"
#include "core/logger.hpp"
#include <ndn-cxx/face.hpp>
namespace nfd {
NFD_LOG_INIT("FaceMonitor");
FaceMonitor::FaceMonitor(ndn::Face& face)
: m_face(face)
, m_isStopped(true)
{
}
FaceMonitor::~FaceMonitor()
{
}
void
FaceMonitor::removeAllSubscribers()
{
m_notificationCallbacks.clear();
m_timeoutCallbacks.clear();
stopNotifications();
}
void
FaceMonitor::stopNotifications()
{
if (static_cast<bool>(m_lastInterestId))
m_face.removePendingInterest(m_lastInterestId);
m_isStopped = true;
}
void
FaceMonitor::startNotifications()
{
if (m_isStopped == false)
return; // Notifications cycle has been started.
m_isStopped = false;
Interest interest("/localhost/nfd/faces/events");
interest
.setMustBeFresh(true)
.setChildSelector(1)
.setInterestLifetime(time::seconds(60))
;
NFD_LOG_DEBUG("startNotification: Interest Sent: " << interest);
m_lastInterestId = m_face.expressInterest(interest,
bind(&FaceMonitor::onNotification, this, _2),
bind(&FaceMonitor::onTimeout, this));
}
void
FaceMonitor::addSubscriber(const NotificationCallback& notificationCallback)
{
addSubscriber(notificationCallback, TimeoutCallback());
}
void
FaceMonitor::addSubscriber(const NotificationCallback& notificationCallback,
const TimeoutCallback& timeoutCallback)
{
if (static_cast<bool>(notificationCallback))
m_notificationCallbacks.push_back(notificationCallback);
if (static_cast<bool>(timeoutCallback))
m_timeoutCallbacks.push_back(timeoutCallback);
}
void
FaceMonitor::onTimeout()
{
if (m_isStopped)
return;
std::vector<TimeoutCallback>::iterator it;
for (it = m_timeoutCallbacks.begin();
it != m_timeoutCallbacks.end(); ++it) {
(*it)();
//One of the registered callbacks has cleared the vector,
//return now as the iterator has been invalidated and
//the vector is empty.
if (m_timeoutCallbacks.empty()) {
return;
}
}
Interest newInterest("/localhost/nfd/faces/events");
newInterest
.setMustBeFresh(true)
.setChildSelector(1)
.setInterestLifetime(time::seconds(60))
;
NFD_LOG_DEBUG("In onTimeout, sending interest: " << newInterest);
m_lastInterestId = m_face.expressInterest(newInterest,
bind(&FaceMonitor::onNotification, this, _2),
bind(&FaceMonitor::onTimeout, this));
}
void
FaceMonitor::onNotification(const Data& data)
{
if (m_isStopped)
return;
m_lastSequence = data.getName().get(-1).toSegment();
ndn::nfd::FaceEventNotification notification(data.getContent().blockFromValue());
std::vector<NotificationCallback>::iterator it;
for (it = m_notificationCallbacks.begin();
it != m_notificationCallbacks.end(); ++it) {
(*it)(notification);
if (m_notificationCallbacks.empty()) {
//One of the registered callbacks has cleared the vector.
//return back, as no one is interested in notifications anymore.
return;
}
}
//Setting up next notification
Name nextNotification("/localhost/nfd/faces/events");
nextNotification.appendSegment(m_lastSequence + 1);
Interest interest(nextNotification);
interest.setInterestLifetime(time::seconds(60));
NFD_LOG_DEBUG("onNotification: Interest sent: " << interest);
m_lastInterestId = m_face.expressInterest(interest,
bind(&FaceMonitor::onNotification, this, _2),
bind(&FaceMonitor::onTimeout, this));
}
} // namespace nfd
-105
View File
@@ -1,105 +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_FACE_MONITOR_HPP
#define NFD_CORE_FACE_MONITOR_HPP
#include "common.hpp"
#include <ndn-cxx/management/nfd-face-event-notification.hpp>
namespace ndn {
class Face;
struct PendingInterestId;
}
namespace nfd {
using ndn::nfd::FaceEventNotification;
/**
* \brief Helper class to subscribe to face notification events
*
* \todo Write test cases
*/
class FaceMonitor : noncopyable
{
public:
typedef function<void(const ndn::nfd::FaceEventNotification&)> NotificationCallback;
typedef function<void()> TimeoutCallback;
typedef std::vector<NotificationCallback> NotificationCallbacks;
typedef std::vector<TimeoutCallback> TimeoutCallbacks;
explicit
FaceMonitor(ndn::Face& face);
~FaceMonitor();
/** \brief Stops all notifications. This method doesn't remove registered callbacks.
*/
void
stopNotifications();
/** \brief Resumes notifications for added subscribers.
*/
void
startNotifications();
/** \brief Removes all notification subscribers.
*/
void
removeAllSubscribers();
/** \brief Adds a notification subscriber. This method doesn't return on timeouts.
*/
void
addSubscriber(const NotificationCallback& notificationCallback);
/** \brief Adds a notification subscriber.
*/
void
addSubscriber(const NotificationCallback& notificationCallback,
const TimeoutCallback& timeoutCallback);
private:
void
onTimeout();
void
onNotification(const Data& data);
private:
ndn::Face& m_face;
uint64_t m_lastSequence;
bool m_isStopped;
NotificationCallbacks m_notificationCallbacks;
TimeoutCallbacks m_timeoutCallbacks;
const ndn::PendingInterestId* m_lastInterestId;
};
} // namespace nfd
#endif // NFD_CORE_FACE_MONITOR_HPP
-151
View File
@@ -1,151 +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 "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/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, 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());
}
#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(false)
{
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
-191
View File
@@ -1,191 +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);
#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;
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 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;
}
+87 -75
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,27 +72,40 @@ 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 ((LOG_NONE <= levelNo && levelNo <= 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) {
}
if (levelString.empty()) {
BOOST_THROW_EXCEPTION(LoggerFactory::Error("No logging level found for option \"" + key + "\""));
}
return parseLevel(levelString);
}
void
LoggerFactory::onConfig(const ConfigSection& section,
@@ -106,62 +126,51 @@ LoggerFactory::onConfig(const ConfigSection& section,
// Forwarder WARN
// }
// std::cerr << "loading logging configuration" << std::endl;
for (ConfigSection::const_iterator item = section.begin();
item != section.end();
++item)
{
std::string levelString;
try
{
levelString = item->second.get_value<std::string>();
}
catch (const boost::property_tree::ptree_error& error)
{
}
if (levelString.empty())
{
throw LoggerFactory::Error("No logging level found for option \"" + item->first + "\"");
}
LogLevel level = parseLevel(levelString);
if (item->first == "default_level")
{
if (!isDryRun)
{
setDefaultLevel(level);
}
}
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);
}
}
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);
}
}
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&
@@ -176,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)));
@@ -185,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;
}
+19 -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"
@@ -81,6 +87,9 @@ private:
LogLevel
parseLevel(const std::string& level);
LogLevel
extractLevel(const ConfigSection& item, const std::string& key);
private:
typedef std::map<std::string, LogLevel> LevelMap;
@@ -92,6 +101,7 @@ private:
typedef std::pair<std::string, Logger> NameAndLogger;
LoggerMap m_loggers;
mutable std::mutex m_loggersGuard;
LogLevel m_defaultLevel;
};
@@ -104,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
+36 -64
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;
@@ -110,7 +82,7 @@ operator>>(std::istream& is, Network& network)
if (address.is_v4())
{
ip::address_v4::bytes_type maskBytes = {};
ip::address_v4::bytes_type maskBytes = boost::initialized_value;
for (size_t i = 0; i < mask; i++)
{
size_t byteId = i / 8;
@@ -133,7 +105,7 @@ operator>>(std::istream& is, Network& network)
}
else
{
ip::address_v6::bytes_type maskBytes = {};
ip::address_v6::bytes_type maskBytes = boost::initialized_value;
for (size_t i = 0; i < mask; i++)
{
size_t byteId = i / 8;
@@ -158,4 +130,4 @@ operator>>(std::istream& is, Network& network)
return is;
}
#endif // NFD_TOOLS_NETWORK_HPP
} // namespace nfd
+95
View File
@@ -0,0 +1,95 @@
/* -*- 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_NETWORK_HPP
#define NFD_CORE_NETWORK_HPP
#include <boost/asio.hpp>
#include <boost/utility/value_init.hpp>
#include <boost/lexical_cast.hpp>
namespace nfd {
class Network
{
public:
Network()
{
}
Network(const boost::asio::ip::address& minAddress,
const boost::asio::ip::address& maxAddress)
: m_minAddress(minAddress)
, m_maxAddress(maxAddress)
{
}
void
print(std::ostream& os) const;
bool
doesContain(const boost::asio::ip::address& address) const
{
return (m_minAddress <= address && address <= m_maxAddress);
}
static const Network&
getMaxRangeV4();
static const Network&
getMaxRangeV6();
bool
operator==(const Network& rhs) const
{
return m_minAddress == rhs.m_minAddress && m_maxAddress == rhs.m_maxAddress;
}
bool
operator!=(const Network& rhs) const
{
return !(*this == rhs);
}
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);
};
std::ostream&
operator<<(std::ostream& os, const Network& network);
std::istream&
operator>>(std::istream& is, Network& network);
} // namespace nfd
#endif // NFD_CORE_NETWORK_HPP
+212
View File
@@ -0,0 +1,212 @@
/* -*- 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 "privilege-helper.hpp"
#include "core/logger.hpp"
#include <pwd.h>
#include <grp.h>
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;
static const size_t FALLBACK_GROUP_BUFFER_SIZE = 1024;
static const size_t FALLBACK_PASSWD_BUFFER_SIZE = 1024;
NFD_LOG_TRACE("initializing privilege helper with user \"" << userName << "\""
<< " group \"" << groupName << "\"");
// workflow from man getpwnam_r
if (!groupName.empty())
{
static int groupSize = ::sysconf(_SC_GETGR_R_SIZE_MAX);
if (groupSize == -1)
{
groupSize = FALLBACK_GROUP_BUFFER_SIZE;
}
std::vector<char> groupBuffer(groupSize);
struct group group;
struct group* groupResult = 0;
int errorCode = getgrnam_r(groupName.c_str(), &group,
&groupBuffer[0], groupSize, &groupResult);
while (errorCode == ERANGE)
{
if (groupBuffer.size() * 2 > MAX_GROUP_BUFFER_SIZE)
{
throw PrivilegeHelper::Error("Cannot allocate large enough buffer for struct group");
}
groupBuffer.resize(groupBuffer.size() * 2);
errorCode = getgrnam_r(groupName.c_str(), &group,
&groupBuffer[0], groupBuffer.size(), &groupResult);
}
if (errorCode != 0 || !groupResult)
{
throw PrivilegeHelper::Error("Failed to get gid for \"" + groupName + "\"");
}
s_normalGid = group.gr_gid;
}
if (!userName.empty())
{
static int passwdSize = ::sysconf(_SC_GETPW_R_SIZE_MAX);
if (passwdSize == -1)
{
passwdSize = FALLBACK_PASSWD_BUFFER_SIZE;
}
std::vector<char> passwdBuffer(passwdSize);
struct passwd passwd;
struct passwd* passwdResult = 0;
int errorCode =
getpwnam_r(userName.c_str(), &passwd,
&passwdBuffer[0], passwdBuffer.size(), &passwdResult);
while (errorCode == ERANGE)
{
if (passwdBuffer.size() * 2 > MAX_PASSWD_BUFFER_SIZE)
{
throw PrivilegeHelper::Error("Cannot allocate large enough buffer for struct passwd");
}
passwdBuffer.resize(passwdBuffer.size() * 2);
errorCode = getpwnam_r(userName.c_str(), &passwd,
&passwdBuffer[0], passwdBuffer.size(), &passwdResult);
}
if (errorCode != 0 || !passwdResult)
{
throw PrivilegeHelper::Error("Failed to get uid for \"" + userName + "\"");
}
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)
{
std::stringstream error;
error << "Failed to drop to effective gid=" << s_normalGid;
throw PrivilegeHelper::Error(error.str());
}
NFD_LOG_TRACE("dropping to effective uid=" << s_normalUid);
if (::seteuid(s_normalUid) != 0)
{
std::stringstream error;
error << "Failed to drop to effective uid=" << s_normalUid;
throw PrivilegeHelper::Error(error.str());
}
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)
{
std::stringstream error;
error << "Failed to elevate to effective uid=" << s_privilegedUid;
throw PrivilegeHelper::Error(error.str());
}
NFD_LOG_TRACE("elevating to effective gid=" << s_privilegedGid);
if (::setegid(s_privilegedGid) != 0)
{
std::stringstream error;
error << "Failed to elevate to effective gid=" << s_privilegedGid;
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
PrivilegeHelper::runElevated(function<void()> f)
{
raise();
try
{
f();
}
catch (...)
{
drop();
throw;
}
drop();
}
} // namespace nfd
+89
View File
@@ -0,0 +1,89 @@
/* -*- 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_PRIVILEGE_HELPER_HPP
#define NFD_CORE_PRIVILEGE_HELPER_HPP
#include "common.hpp"
#include <unistd.h>
namespace nfd {
class PrivilegeHelper
{
public:
/** \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:
explicit
Error(const std::string& what)
: m_whatMessage(what)
{
}
const char*
what() const
{
return m_whatMessage.c_str();
}
private:
const std::string m_whatMessage;
};
static void
initialize(const std::string& userName, const std::string& groupName);
static void
drop();
static void
runElevated(function<void()> f);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
static void
raise();
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
#endif // NFD_CORE_PRIVILEGE_HELPER_HPP
@@ -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,31 +21,28 @@
*
* 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-sequence-generator.hpp"
#include "random.hpp"
#include <boost/thread/tss.hpp>
namespace nfd {
namespace ndnlp {
SequenceBlock::SequenceBlock(uint64_t start, size_t count)
: m_start(start)
, m_count(count)
static boost::thread_specific_ptr<boost::random::mt19937> g_rng;
boost::random::mt19937&
getGlobalRng()
{
if (g_rng.get() == nullptr) {
g_rng.reset(new boost::random::mt19937());
}
return *g_rng;
}
SequenceGenerator::SequenceGenerator()
: m_next(0)
void
resetGlobalRng()
{
g_rng.reset();
}
SequenceBlock
SequenceGenerator::nextBlock(size_t count)
{
SequenceBlock sb(m_next, count);
m_next += count;
return sb;
}
} // namespace ndnlp
} // namespace nfd
+49
View File
@@ -0,0 +1,49 @@
/* -*- 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/>.
*/
/**
* This file declares the global random number generator
* All random numbers in NFD should use this global random number generator,
* so that the generator can be properly seeded when necessary.
*
* This random number generator is not suitable for security purposes;
* security-critical code should use CryptoPP random number generator instead.
*/
#ifndef NFD_CORE_RANDOM_HPP
#define NFD_CORE_RANDOM_HPP
#include <boost/random/mersenne_twister.hpp>
namespace nfd {
/** \return the global random number generator instance
*/
boost::random::mt19937&
getGlobalRng();
} // namespace nfd
#endif // NFD_CORE_RANDOM_HPP
-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>(boost::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
+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/>.
*/
#ifndef NFD_CORE_SEGMENT_PUBLISHER_HPP
#define NFD_CORE_SEGMENT_PUBLISHER_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 Status Dataset or other segmented octet stream
* \sa http://redmine.named-data.net/projects/nfd/wiki/StatusDataset
*/
template <class FaceBase>
class SegmentPublisher : noncopyable
{
public:
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)
{
}
virtual
~SegmentPublisher()
{
}
static size_t
getMaxSegmentSize()
{
static const size_t MAX_SEGMENT_SIZE = ndn::MAX_NDN_PACKET_SIZE >> 1;
return MAX_SEGMENT_SIZE;
}
static constexpr time::milliseconds
getDefaultFreshness()
{
return time::milliseconds(1000);
}
void
publish()
{
ndn::EncodingBuffer buffer;
generate(buffer);
const uint8_t* rawBuffer = buffer.buf();
const uint8_t* segmentBegin = rawBuffer;
const uint8_t* end = rawBuffer + buffer.size();
Name segmentPrefix(m_prefix);
segmentPrefix.appendVersion();
uint64_t segmentNo = 0;
do {
const uint8_t* segmentEnd = segmentBegin + getMaxSegmentSize();
if (segmentEnd > end) {
segmentEnd = end;
}
Name segmentName(segmentPrefix);
segmentName.appendSegment(segmentNo);
shared_ptr<Data> data = make_shared<Data>(segmentName);
data->setContent(segmentBegin, segmentEnd - segmentBegin);
data->setFreshnessPeriod(m_freshnessPeriod);
segmentBegin = segmentEnd;
if (segmentBegin >= end) {
data->setFinalBlockId(segmentName[-1]);
}
publishSegment(data);
++segmentNo;
} while (segmentBegin < end);
}
protected:
/** \brief In a derived class, write the octets into outBuffer.
*/
virtual size_t
generate(ndn::EncodingBuffer& outBuffer) = 0;
private:
void
publishSegment(shared_ptr<Data>& data)
{
m_keyChain.sign(*data);
m_face.put(*data);
}
private:
FaceBase& m_face;
const Name m_prefix;
ndn::KeyChain& m_keyChain;
const time::milliseconds m_freshnessPeriod;
};
} // namespace nfd
#endif // NFD_CORE_SEGMENT_PUBLISHER_HPP
+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
-337
View File
@@ -1,337 +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_DATAGRAM_FACE_HPP
#define NFD_DAEMON_FACE_DATAGRAM_FACE_HPP
#include "face.hpp"
#include "core/logger.hpp"
namespace nfd {
template <class Protocol>
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
handleSend(const boost::system::error_code& error,
const Block& wire);
void
handleReceive(const boost::system::error_code& error,
size_t nBytesReceived);
/**
* \brief Set m_hasBeenUsedRecently to false
*/
void
resetRecentUsage();
bool
hasBeenUsedRecently() const;
void
setOnDemand(bool isOnDemand);
protected:
void
receiveDatagram(const uint8_t* buffer,
size_t nBytesReceived,
const boost::system::error_code& error);
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>
inline
DatagramFace<T>::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>::handleReceive, this, _1, _2));
}
template <class T>
inline
DatagramFace<T>::~DatagramFace()
{
}
template <class T>
inline void
DatagramFace<T>::sendInterest(const Interest& interest)
{
this->onSendInterest(interest);
m_socket->async_send(boost::asio::buffer(interest.wireEncode().wire(),
interest.wireEncode().size()),
bind(&DatagramFace<T>::handleSend, this, _1, interest.wireEncode()));
// anything else should be done here?
}
template <class T>
inline void
DatagramFace<T>::sendData(const Data& data)
{
this->onSendData(data);
m_socket->async_send(boost::asio::buffer(data.wireEncode().wire(),
data.wireEncode().size()),
bind(&DatagramFace<T>::handleSend, this, _1, data.wireEncode()));
// anything else should be done here?
}
template <class T>
inline void
DatagramFace<T>::handleSend(const boost::system::error_code& error,
const Block& wire)
{
if (error != 0) {
if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
return;
if (!m_socket->is_open())
{
onFail("Tunnel closed");
return;
}
NFD_LOG_WARN("[id:" << this->getId()
<< ",endpoint:" << m_socket->local_endpoint()
<< "] Send operation failed, closing socket: "
<< error.category().message(error.value()));
closeSocket();
if (error == boost::asio::error::eof)
{
onFail("Tunnel closed");
}
else
{
onFail("Send operation failed, closing socket: " +
error.category().message(error.value()));
}
return;
}
NFD_LOG_TRACE("[id:" << this->getId()
<< ",endpoint:" << m_socket->local_endpoint()
<< "] Successfully sent: " << wire.size() << " bytes");
// do nothing (needed to retain validity of wire memory block
}
template <class T>
inline void
DatagramFace<T>::close()
{
if (!m_socket->is_open())
return;
NFD_LOG_INFO("[id:" << this->getId()
<< ",endpoint:" << m_socket->local_endpoint()
<< "] Close tunnel");
closeSocket();
onFail("Close tunnel");
}
template <class T>
inline void
DatagramFace<T>::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>::handleReceive, this, _1, _2));
}
template <class T>
inline void
DatagramFace<T>::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())
{
onFail("Tunnel closed");
return;
}
NFD_LOG_WARN("[id:" << this->getId()
<< ",endpoint:" << m_socket->local_endpoint()
<< "] Receive operation failed: "
<< error.category().message(error.value()));
closeSocket();
if (error == boost::asio::error::eof)
{
onFail("Tunnel closed");
}
else
{
onFail("Receive operation failed, closing socket: " +
error.category().message(error.value()));
}
return;
}
NFD_LOG_TRACE("[id:" << this->getId()
<< ",endpoint:" << m_socket->local_endpoint()
<< "] Received: " << nBytesReceived << " bytes");
Block element;
bool isOk = Block::fromBuffer(buffer, nBytesReceived, element);
if (!isOk)
{
NFD_LOG_WARN("[id:" << this->getId()
<< ",endpoint:" << m_socket->local_endpoint()
<< "] Failed to parse incoming packet");
// This message won't extend the face lifetime
return;
}
if (element.size() != nBytesReceived)
{
NFD_LOG_WARN("[id:" << this->getId()
<< ",endpoint:" << m_socket->local_endpoint()
<< "] 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()
<< ",endpoint:" << m_socket->local_endpoint()
<< "] Received unrecognized block of type ["
<< element.type() << "]");
// This message won't extend the face lifetime
return;
}
m_hasBeenUsedRecently = true;
}
template <class T>
inline void
DatagramFace<T>::keepFaceAliveUntilAllHandlersExecuted(const shared_ptr<Face>& face)
{
}
template <class T>
inline void
DatagramFace<T>::closeSocket()
{
NFD_LOG_DEBUG("closeSocket " << m_socket->local_endpoint());
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>::keepFaceAliveUntilAllHandlersExecuted,
this, this->shared_from_this()));
}
template <class T>
inline void
DatagramFace<T>::setOnDemand(bool isOnDemand)
{
Face::setOnDemand(isOnDemand);
}
template <class T>
inline void
DatagramFace<T>::resetRecentUsage()
{
m_hasBeenUsedRecently = false;
}
template <class T>
inline bool
DatagramFace<T>::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
-313
View File
@@ -1,313 +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-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()
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()
{
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;
}
}
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));
/// \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");
onFail("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: " << buffer.size() << " bytes");
}
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;
NFD_LOG_TRACE("[id:" << getId() << ",endpoint:" << m_interfaceName
<< "] Received: " << length << " bytes");
/// \todo Reserve space in front and at the back
/// of the underlying buffer
Block element;
bool isOk = Block::fromBuffer(packet, length, element);
if (isOk)
{
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)
{
onFail("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.category().message(error.value());
NFD_LOG_WARN("[id:" << getId() << ",endpoint:" << m_interfaceName << "] " << msg);
}
close();
onFail(msg);
}
size_t
EthernetFace::getInterfaceMtu() const
{
size_t mtu = ethernet::MAX_DATA_LEN;
#ifdef SIOCGIFMTU
ifreq ifr = {};
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
-113
View File
@@ -1,113 +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_ETHERNET_FACE_HPP
#define NFD_DAEMON_FACE_ETHERNET_FACE_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
+39 -44
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,70 +21,64 @@
*
* 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-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>(boost::ref(getGlobalIoService()));
face::GenericLinkService::Options opts;
opts.allowFragmentation = true;
opts.allowReassembly = true;
face = make_shared<EthernetFace>(boost::cref(socket),
boost::cref(interface),
boost::cref(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
{
MulticastFacesMap::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");
return nullptr;
}
} // namespace nfd
+47 -32
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,34 +21,34 @@
*
* 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:
/**
* \brief Exception of EthernetFactory
*/
struct Error : public ProtocolFactory::Error
class Error : public ProtocolFactory::Error
{
Error(const std::string& what) : ProtocolFactory::Error(what) {}
public:
explicit
Error(const std::string& what)
: ProtocolFactory::Error(what)
{
}
};
// 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
@@ -62,35 +63,49 @@ 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);
private:
void
afterFaceFailed(const std::string& interfaceName,
const ethernet::Address& address);
/**
* \brief Get map of configured multicast faces
*/
const MulticastFaceMap&
getMulticastFaces() 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:
/**
* \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;
private:
typedef std::map< std::pair<std::string, ethernet::Address>,
shared_ptr<EthernetFace> > MulticastFacesMap;
MulticastFacesMap m_multicastFaces;
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
-142
View File
@@ -1,142 +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_FACE_COUNTER_HPP
#define NFD_DAEMON_FACE_FACE_COUNTER_HPP
#include "common.hpp"
namespace nfd {
/** \class FaceCounter
* \brief represents a counter on face
*
* \todo This class should be noncopyable
*/
typedef uint64_t FaceCounter;
/** \brief contains counters on face
*/
class FaceCounters : noncopyable
{
public:
FaceCounters();
/// incoming Interest (total packets since Face establishment)
const FaceCounter&
getNInInterests() const;
FaceCounter&
getNInInterests();
/// incoming Data (total packets since Face establishment)
const FaceCounter&
getNInDatas() const;
FaceCounter&
getNInDatas();
/// outgoing Interest (total packets since Face establishment)
const FaceCounter&
getNOutInterests() const;
FaceCounter&
getNOutInterests();
/// outgoing Data (total packets since Face establishment)
const FaceCounter&
getNOutDatas() const;
FaceCounter&
getNOutDatas();
private:
FaceCounter m_nInInterests;
FaceCounter m_nInDatas;
FaceCounter m_outInterests;
FaceCounter m_outDatas;
};
inline
FaceCounters::FaceCounters()
: m_nInInterests(0)
, m_nInDatas(0)
, m_outInterests(0)
, m_outDatas(0)
{
}
inline const FaceCounter&
FaceCounters::getNInInterests() const
{
return m_nInInterests;
}
inline FaceCounter&
FaceCounters::getNInInterests()
{
return m_nInInterests;
}
inline const FaceCounter&
FaceCounters::getNInDatas() const
{
return m_nInDatas;
}
inline FaceCounter&
FaceCounters::getNInDatas()
{
return m_nInDatas;
}
inline const FaceCounter&
FaceCounters::getNOutInterests() const
{
return m_outInterests;
}
inline FaceCounter&
FaceCounters::getNOutInterests()
{
return m_outInterests;
}
inline const FaceCounter&
FaceCounters::getNOutDatas() const
{
return m_outDatas;
}
inline FaceCounter&
FaceCounters::getNOutDatas()
{
return m_outDatas;
}
} // namespace nfd
#endif // NFD_DAEMON_FACE_FACE_COUNTER_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
+91
View File
@@ -0,0 +1,91 @@
/* -*- 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_COUNTERS_HPP
#define NFD_DAEMON_FACE_FACE_COUNTERS_HPP
#include "link-service.hpp"
#include "transport.hpp"
namespace nfd {
namespace face {
/** \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.
*/
class FaceCounters
{
public:
FaceCounters(const LinkService::Counters& linkServiceCounters,
const Transport::Counters& transportCounters);
/** \return counters provided by LinkService
* \tparam T LinkService counters type
* \throw std::bad_cast counters type mismatch
*/
template<typename T>
typename std::enable_if<std::is_base_of<LinkService::Counters, T>::value, const T&>::type
get() const
{
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:
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
+28 -91
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,99 +21,35 @@
*
* 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.hpp"
#include "core/logger.hpp"
namespace nfd {
namespace face {
static inline void
increaseCounter(FaceCounter& counter)
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())
{
++counter;
m_service->setFaceAndTransport(*this, *m_transport);
m_transport->setFaceAndLinkService(*this, *m_service);
}
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)
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<Face>& flh)
{
onReceiveInterest += bind(&increaseCounter, boost::ref(m_counters.getNInInterests()));
onReceiveData += bind(&increaseCounter, boost::ref(m_counters.getNInDatas()));
onSendInterest += bind(&increaseCounter, boost::ref(m_counters.getNOutInterests()));
onSendData += bind(&increaseCounter, boost::ref(m_counters.getNOutDatas()));
const Face& face = flh.obj;
os << "[id=" << face.getId() << ",local=" << face.getLocalUri() <<
",remote=" << face.getRemoteUri() << "] ";
return os;
}
Face::~Face()
{
}
FaceId
Face::getId() const
{
return m_id;
}
// this method is private and should be used only by the Forwarder
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;
}
}
} //namespace nfd
} // namespace face
} // namespace nfd
+248 -162
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,167 +21,267 @@
*
* 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_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 "face-counter.hpp"
#include "transport.hpp"
#include "link-service.hpp"
#include "face-counters.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;
const FaceId INVALID_FACEID = -1;
/// indicates an invalid FaceId
const FaceId INVALID_FACEID = 0;
/// identifies the InternalFace used in management
const FaceId FACEID_INTERNAL_FACE = 1;
/// 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;
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;
protected:
// this is a non-virtual method
bool
decodeAndDispatchInput(const Block& element);
FaceCounters&
getMutableCounters();
void
setOnDemand(bool isOnDemand);
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;
// 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&
@@ -189,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
-83
View File
@@ -1,83 +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 "multicast-udp-face.hpp"
namespace nfd {
NFD_LOG_INIT("MulticastUdpFace");
MulticastUdpFace::MulticastUdpFace(const shared_ptr<MulticastUdpFace::protocol::socket>& socket,
const MulticastUdpFace::protocol::endpoint& localEndpoint)
: DatagramFace<protocol>(FaceUri(socket->local_endpoint()),
FaceUri(localEndpoint),
socket, false)
, m_multicastGroup(m_socket->local_endpoint())
{
NFD_LOG_INFO("Creating multicast UDP face for group " << m_multicastGroup);
}
const MulticastUdpFace::protocol::endpoint&
MulticastUdpFace::getMulticastGroup() const
{
return m_multicastGroup;
}
void
MulticastUdpFace::sendInterest(const Interest& interest)
{
onSendInterest(interest);
NFD_LOG_DEBUG("Sending interest");
m_socket->async_send_to(boost::asio::buffer(interest.wireEncode().wire(),
interest.wireEncode().size()),
m_multicastGroup,
bind(&DatagramFace<protocol>::handleSend, this, _1, interest.wireEncode()));
// anything else should be done here?
}
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");
m_socket->async_send_to(boost::asio::buffer(data.wireEncode().wire(),
data.wireEncode().size()),
m_multicastGroup,
bind(&DatagramFace<protocol>::handleSend, this, _1, data.wireEncode()));
// anything else should be done here?
}
bool
MulticastUdpFace::isMultiAccess() const
{
return true;
}
} // namespace nfd
-64
View File
@@ -1,64 +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_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>
{
public:
/**
* \brief Creates a UDP-based face for multicast communication
*/
MulticastUdpFace(const shared_ptr<protocol::socket>& socket,
const protocol::endpoint& localEndpoint);
const protocol::endpoint&
getMulticastGroup() const;
// from Face
virtual void
sendInterest(const Interest& interest);
virtual void
sendData(const Data& data);
virtual bool
isMultiAccess() const;
private:
protocol::endpoint m_multicastGroup;
};
} // 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
Loaded 100 of 499 files, more files were not shown because too many files have changed in this diff. Show more