Compare commits

..
113 Commits
Author SHA1 Message Date
SunnyQjm 9bc57b880b feat: Add qsccp sched 2023-12-03 17:57:24 +08:00
Varun Patil 9b877c3a23 docker: add HOME environment variable and default config
Change-Id: I82b8d46ba74dc648786c23e68a1d1498c893108a
2023-11-18 18:20:28 -08:00
Varun Patil 23135a4cdd Add Dockerfile for nfd-status-http-server
Change-Id: I87349b2cf351c7323d8511677ce7f4a31d944387
2023-11-18 20:21:24 -05:00
Varun PatilandJunxiao Shi 6ba08cd5cb Add initial Dockerfile and CI workflow
Co-authored-by: Junxiao Shi <git@mail1.yoursunny.com>
Change-Id: Ib8341b61edef9be4e4c5f43836ff936c3c063010
2023-11-18 17:18:25 -05:00
Davide Pesavento e277f8b9e8 tools: switch to Face::getIoContext()
Change-Id: I6be4c682d62e1061af45052d2141b9e5b9e897c5
2023-11-11 17:14:02 -05:00
Davide Pesavento 9a63bf22d0 face: add missing includes
Change-Id: I2d855f71310e824205d37d892749c3eab9f5b3c3
2023-11-11 17:12:51 -05:00
Davide Pesavento ef6a528ae0 tests: randomize port used in multicast transport tests
Change-Id: I6030317ad10cf6f3c81f29c2a3898b41a1982c0e
2023-11-03 16:50:10 -04:00
Davide Pesavento 05bd6c2d69 docs: update list of supported platforms
Change-Id: I6aad1f19b593e707e0468e24b160bf3e769376d7
2023-10-31 21:45:25 -04:00
Davide Pesavento a9ec67c52b tests: expand test coverage of EthernetFactory and UdpFactory
Change-Id: I469ac8682502ca7a0e360703b462bfb119eaedf1
2023-10-23 21:00:03 -04:00
Davide Pesavento d7083a507f tests: refactor EthernetFixture
Also, use BOOST_TEST_INFO_SCOPE in a few places.

Change-Id: I113f326207825949ed9d3d22ade0654976d49b76
2023-10-19 17:51:16 -04:00
Davide Pesavento c5a9f81fce face: more robust handling of multicast face creation errors
Refs: #5030, #5297
Change-Id: I3ca985498d9d3756cbff94873063f3734bcea288
2023-10-19 02:12:05 -04:00
Davide Pesavento 0a05f7aea6 build: disable -Wnon-virtual-dtor compiler warning
It's overkill and suffers from annoying false positives that
prevent us from applying the "protected non-virtual destructor"
idiom in several perfectly valid cases. See for instance the
GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102168

The -Wdelete-non-virtual-dtor warning (included in -Wall) is
the preferred alternative and is enough to catch the unsafe
cases without false positives.

Partially reverts 847de408cb

Change-Id: I46ee1f01e7d4e2b125c2c534c6550824ba1de4c0
2023-10-16 20:50:03 -04:00
Davide Pesavento c0df94ed10 face: minor code cleanups
Change-Id: I154d2ad4dfd9e12e1fa9756f74884286b31298e4
2023-10-08 19:26:55 -04:00
awlane 9c36a65b11 face: handle PcapHelper::Error when applying multicast configuration
When the network interface state is changed, NFD reconfigures its
multicast ethernet faces. The code responsible for this is prone to
a TOCTOU race condition, e.g., if an interface is quickly brought up
and then down again. This currently raises an uncaught exception when
we try to set a packet filter for that interface.

Prevent this issue by catching PcapHelper errors in the same manner
as we catch EthernetTransport errors, and skip creating the face.

Refs: #5297
Change-Id: I9f91ac7c42dec06de34128cb34d6de8bb57e8cf5
2023-10-08 16:52:06 -04:00
Davide Pesavento 1e0c88e184 face: use async_wait operation instead of async_read with null_buffers
Change-Id: I2914e7f8fbd1b9a9e1fa8113d53700e7d6184464
2023-10-05 03:52:52 -04:00
Davide Pesavento 9bf64cc60d face: use new-style async_accept API
Change-Id: Id9de72c0922ec9ea13e5b1d9ded27dd7edf67e38
2023-10-05 02:12:02 -04:00
Davide Pesavento d91fe6d921 core+face: avoid deprecated Boost.Asio interfaces
Change-Id: I07ec286531edf63f258babe1561b4da2a88edd10
2023-10-04 21:40:02 -04:00
Davide Pesavento 5d64263dcb daemon: use asio::defer() instead of asio::post() where appropriate
Change-Id: I24d0fab6499d6430dd500ca157daa87f48960d15
2023-10-03 00:36:08 -04:00
Davide Pesavento a9e1ab2664 build: require boost >= 1.71.0
Refs: #5276
Change-Id: Ie428541639dcf1113acfb9e9d0a80f9be87d6cd3
2023-10-02 22:42:02 -04:00
Davide Pesavento 910232fce0 build: use python f-strings
Change-Id: I955739ac40508642509521760c1bc75286c94f30
2023-09-08 14:20:02 -04:00
Davide Pesavento decaf509b4 tools: modernize nfd-status-http-server and improve error handling
Change-Id: I5715c35f79d7dcd8dbefed328ebb625e9150a846
2023-08-30 22:50:03 -04:00
Davide Pesavento 8f0b8b6063 Simplify some code with Boost.Operators
Change-Id: Ic873bcbaf6be00d5c35601cfc8090df534d815ee
2023-08-29 21:04:08 -04:00
Davide Pesavento 11f1fd8340 build: update waf to version 2.0.26
Change-Id: I896871a312983ff36f1784aa53484c5edf95ebda
2023-08-19 01:50:04 -04:00
Davide Pesavento bf2e67fb14 build: enable a few more compiler warnings
Refactor default-compiler-flags.py to reduce duplication

Change-Id: I627b05257c2eec5c3ada9994bcd2b9a9be362157
2023-08-07 17:06:02 -04:00
Davide Pesavento 5b15e2fe97 build: decrease level of debug information produced by default
Refs: #5279
Change-Id: I537ff2a0a2e411279922823ae46cb7fee6586670
2023-08-07 16:35:35 -04:00
Davide Pesavento 95afc6d8a4 fw: increment nOutNacks when sending a Nack from onInterestLoop
Also expand test coverage of all forwarder counters

Change-Id: I6948af05aca1b5589e2f1c8a1f23c002d39d0ec0
2023-08-02 21:20:05 -04:00
Alex LaneandDavide Pesavento 653eb07e29 fw: refactor strategy logging and improve ASF probe logging
Bring strategy logging in line with format from 6bf94c0.
This should also marginally improve performance when log level is raised.

Refs: #5262, #5267
Co-authored-by: Davide Pesavento <davidepesa@gmail.com>
Change-Id: I6493b6476f3d0c6ae5562b66abfa46f6c6f4903d
2023-07-28 14:14:11 -04:00
Alex Lane 6bf94c02f5 fw: add Interest nonce to Forwarder logging where appropriate
Refs: #5262
Change-Id: Id3675fe1adb973d403f1e2ba386e9a4ec686c7b6
2023-06-08 02:42:02 -04:00
Davide Pesavento 191a7a24e6 core+daemon: declare all equality operators as hidden friends
Change-Id: Id832ee1fb16fb6742879c8b87f56002f94745103
2023-05-17 22:50:32 -04:00
Davide Pesavento ae43030f6f Further reduce the use of std::bind()
And also avoid deprecated ndn-cxx type aliases

Change-Id: I87e903b9671a3cf1c1b9ab30d4594d595c3c6da9
2023-05-11 01:50:11 -04:00
Davide Pesavento 63b3ae818f tools: fix compilation with latest ndn-cxx
Change-Id: Ifded624f3256452be98f288f9193dd26e464cd36
2023-03-27 14:05:04 -04:00
Davide Pesavento 4064127b97 mgmt+tools: add missing includes
Change-Id: I53aeaa6b223b616c170697662d02a028cea67400
2023-03-16 13:31:12 -04:00
Davide Pesavento d6ea0b1e0e tests: use std::nullopt
Change-Id: I7efdc8076c1bc4ced11dd3bdab7f199609009545
2023-03-13 22:54:15 -04:00
Davide Pesavento c5e3e7a55d build: drop official support for Ubuntu 18.04 and macOS 10.15
Increase the minimum required version of clang to 7.0 on linux, because
older versions fail to compile libstdc++'s implementation of std::variant

Change-Id: I6320973cbe3ff00faa8a36cd0e7ddf564c20d965
2023-03-07 21:25:27 -05:00
Davide Pesavento bf4c131f82 docs: update several URLs to point to docs.named-data.net
Change-Id: I4bab897f17e2b929675119198c9eab0309b6cc3e
2023-02-23 20:32:01 -05:00
Davide Pesavento 39c67f6291 build: switch source archive to xz compression
And a few minor README improvements

Change-Id: Iae8dc8fb3f5ac53296ffdadc8d2b893d13b8e684
2023-02-15 00:26:26 -05:00
Davide Pesavento 269b702f3d ci: adopt reusable workflows from named-data/actions
Change-Id: Iefd142d82f56a6fb83c5039565b6eba83c6e6445
2023-02-12 16:14:56 -05:00
Davide Pesavento 3bc8e19a89 Prepare release 22.12
Refs: #5250
Change-Id: I6b9a3daab498cbffb78a108207e92bc2596be378
2022-12-31 01:40:11 -05:00
Davide Pesavento 0b0156887b face: put the pcap handle in non-blocking mode
This prevents NFD from getting stuck in pcap_next_ex()
when the network interface goes down

Change-Id: I5760fcc7c950b46aecb7619bd889508ee24133aa
2022-12-12 22:01:28 -05:00
Davide Pesavento 6b78a53cf7 build: update waf to version 2.0.24
Change-Id: I57b597fb5933e46b55979ad6b1a62a7fd40c645d
2022-12-02 18:24:16 -05:00
Ikko Ashimine a68af8129e docs: fix typo in release-notes-22.02.rst
accomodate -> accommodate

Closes: https://github.com/named-data/NFD/pull/11
Change-Id: Ibad215a723cd51881760d2e43c05694a0e8928fe
2022-11-25 22:15:12 -05:00
Davide Pesavento a42efcb408 ci: add Xcode 14.1
Change-Id: I8415fb1375da16813a69fa7a03bf37a7b0efc8b7
2022-11-15 02:43:16 -05:00
Davide Pesavento aa9e3b2148 docs: fix capitalization in doxygen comments
Change-Id: Ibf5ee5119d12d60d382b0acef8dfd08277c18fcb
2022-10-29 21:45:24 -04:00
Davide Pesavento b83d3df256 mgmt: finalize migration to the new signed Interest format
Change-Id: I6d3fe1bd092fa80e185d36746a42c188ab00a60e
2022-10-13 09:45:33 -04:00
Davide Pesavento 6d6f207661 mgmt: rename extractRequester() and support signed Interest v0.3
Change-Id: I6bb6635896fa1b9fa54beb70b902c5a35831dc9c
2022-10-13 08:55:42 -04:00
Davide Pesavento 9bfdaef62d build: link with lld if available
Change-Id: Ie390c511c711508b6bb8c326a9a62fb1eca291c5
2022-10-05 17:38:44 -04:00
Davide Pesavento 20d94f67f8 Use inline on all namespace-scope constants defined in headers
Change-Id: Ic61f8d26f59fdc2895415ca47065c02d6eec28ed
2022-09-26 03:30:53 -04:00
Davide Pesavento 36184f6893 docs: restore exception handling in conf.py
Change-Id: Ie6408385e821e509e964bcea001a39f8cfdc5da0
2022-09-25 03:48:58 -04:00
Davide Pesavento 6cc9541220 docs: simplify conf.py and fix compatibility with upcoming Sphinx 6.0
Change-Id: Iacf4a72d30babc4a7c3fab0fea619a798eff2df1
2022-09-20 19:10:55 -04:00
Davide Pesavento 279af1ceac tests: fix UDP multicast transport tests with IPv6
A valid scope id is always required on the multicast address

Change-Id: Ic676fcde0ee50daf75eb38c137e3cb917f43699f
2022-08-29 20:18:32 -04:00
Teng Liang d94b7b3b24 face: reimplement EndpointId with std::variant
Refs: #5041
Change-Id: Ib8aced49a7aa14b137fb06de4a0ae8b979f07587
2022-08-24 19:38:47 -04:00
Davide Pesavento e541d1b250 build+ci: support macOS on arm64
Refs: #5135
Change-Id: I86f1955366df12cfb8b3e6f9d5e9f202778cc211
2022-08-18 20:50:05 -04:00
Davide Pesavento 4791fcb8ba ci: refresh GitHub Actions matrix
* Add ubuntu-22.04, remove 18.04
 * Add macos-12, remove 10.15

Change-Id: I775ea45661259ba1353e3f6ee0c602abee58acbd
2022-08-14 17:40:05 -04:00
Davide Pesavento 72517b5510 ci: auto-detect the OS instead of relying on NODE_LABELS
And remove WAF_JOBS: waf already defaults to the number of available
CPUs, which is appropriate in most cases, and we can always use the
built-in JOBS variable to override it where necessary.

Change-Id: I555dda0ccc48ee791271dbdaf4225cd1cfec4f3d
2022-08-13 18:50:55 -04:00
Davide Pesavento 20cafa8715 tests: minor code cleanups
Change-Id: I9759ba4b7eb467d4d1df4b379efad91bc4f5cc3a
2022-07-25 01:15:03 -04:00
Davide Pesavento 2150da8ee5 build+docs: support CentOS Stream 9, drop CentOS 8
Refs: #5181
Change-Id: I2d8bc595bad047ceaa78bd3729848491b843e83d
2022-07-08 18:18:51 -04:00
Davide Pesavento 990620ac3b nfdc: merge canonizer.hpp and find-face.hpp into face-helpers.hpp
Change-Id: I19ca5cbce8cab54e61eb7af0a32c33c3aa73faf1
2022-06-13 16:33:25 -04:00
Davide Pesavento a9b09b6994 build: make precompiled headers more useful
This can reduce the compilation time of a release
build (without tests) by more than 40%

Refs: #5212
Change-Id: I977aff0c0c7becbfee8a8b55605b81d0c014829b
2022-06-13 16:30:11 -04:00
Davide Pesavento 9a28c3f752 fw+table: workaround bogus doxygen warnings
Change-Id: I0a093658f4b27620ba9731a0640ca71c3d03360a
2022-06-11 21:52:05 -04:00
Davide Pesavento e422f9e1e9 Refactor and modernize namespace declarations
Move all unit tests to namespace nfd::tests

Delete unused header core/algorithm.hpp

Change-Id: I5591f0c5f3bb5db67f8b45fae95471f8a555ca68
2022-06-11 20:10:26 -04:00
Davide Pesavento a3a7a4e330 Use more C++17 features
Mainly structured bindings, inline variables, and class template
argument deduction, plus many more smaller things.

Change-Id: I810d17e0adb470426e4e30c898e03b3140ad052f
2022-06-04 20:26:02 -04:00
Davide Pesavento b7bfcb904a build: switch to C++17
Change-Id: Ie68020a04b7e20b74778b6d0370544ded55c5e26
2022-05-23 03:42:32 -04:00
Junxiao Shi 4b84a2c9be tests: expect certificate name in KeyLocator
Also, delete unused KeyChainFixture::makeCert function.

refs #5112

Change-Id: I59b1ca81fca0481a37126270c447f639080ec75f
2022-04-28 03:17:05 +00:00
Davide Pesavento 6153eafa62 ci: require gcovr 5.1 for code coverage reports
Stop passing `-j`, it wasn't very useful and it's broken in gcovr 5.1

Change-Id: I17ffb97c2dc9cd8db7c900fbbd4ab5f8f92184dd
2022-04-19 19:45:03 -04:00
Ashlesh Gawande 1ef93d0316 fw: add strategy parameters to configure exponential retx suppression
Supported by ASF, BestRoute, and Multicast strategies

Refs: #4924
Change-Id: I215d9212d90b93fa622cc65278703dc5198d0c9d
2022-04-08 00:27:27 -04:00
Davide Pesavento deb5427bb4 daemon+tests: avoid deprecated ndn-cxx functions
Change-Id: Idfa341629919d63fac140eda0b465f8f8abd38e6
2022-03-11 18:51:05 -05:00
Davide Pesavento 1b22a8c156 tests: drop redundant calls to Interest::setCanBePrefix(false)
Change-Id: I6afd1028ab370633c64a74ab4310396dab3c8a03
2022-03-07 21:23:23 -05:00
Davide Pesavento c52cd5eec1 build: align minimum build dependencies with ndn-cxx
* boost 1.65.1
 * gcc 7.4
 * clang 6.0
 * Xcode 10.0 (11.3 or later recommended)

Change-Id: I5e41f2a70d6c510dcb889a083a51504121b4627d
2022-03-05 20:40:54 -05:00
Alexander Afanasyev 5006c1d6af Prepare release 22.02
Change-Id: Ie0d8db596c11c4f298755aa4b7fde5e616f32ceb
Refs: #5172, #5184
2022-02-17 16:07:18 -05:00
Davide Pesavento a599d2aac9 Convert to span and avoid deprecated ndn-cxx functions
Change-Id: I45c50527fe53498b53a3d951458bdff8e7d7778c
2022-02-16 18:52:43 -05:00
Junxiao Shi b98aa3aca6 face: handle error in TCP socket remote_endpoint
refs #5158

Change-Id: I67fa134cd01a80a4f91122bbdcfc64e089d8145e
2022-01-12 01:14:08 +00:00
Junxiao Shi 727b61087a table+fw: update ForwardingHint format
refs #5187

Change-Id: Ic8e32c83caeb60404f1b035a4f7e9841cc513f0b
2022-01-11 18:40:04 +00:00
Davide Pesavento 80111b72f9 face: adapt to API change in ndn::Transport
Change-Id: Ib424af03b7ec7d7bccce8d9498da6c593e16362f
2022-01-09 16:32:33 -05:00
Davide Pesavento 07da3fec95 build: update waf to version 2.0.23
Change-Id: I33bccd3f9aacdd22b690b6ff08fabd964dc022db
2021-12-29 19:14:42 -05:00
Alexander Afanasyev 5e02c04ca7 docs: Update sample nfd.conf to allow use of v0.3 Signed Interests
Change-Id: I72769d6caf52718b0e9ce4f6d3d8b0a29cf04925
2021-12-22 23:01:07 -05:00
Alexander Afanasyev c414ca5895 tools: Allow batch command processing by nfdc
Change-Id: Ia6f70fed88f2d4c918e2ca2b786222840dbd9076
Refs: #5169
2021-12-21 14:27:26 -05:00
Davide Pesavento f28a061c22 ci: add macOS 11 Big Sur
Remove all traces of Travis CI

Change-Id: Ie9ad527af4921c4f3c56903851200131ed0d5e87
2021-09-29 23:13:32 -04:00
Saurab Dulal af3ff5a8c6 fw: rename n-silent-timeouts to max-timeouts in AsfStrategy
Change-Id: Ie2790a4e1fd545aacf8b297d7ec33b204f2cdbfc
2021-09-19 19:45:25 -04:00
Davide Pesavento 2c61bad944 ci: use gcovr 5.0 to generate code coverage reports
Change-Id: Ib7284d1616f9bce527aa98ccbb32e58d0bfa9dfb
2021-08-30 22:40:35 -04:00
Davide Pesavento 4d030c3896 Add CITATION.cff
Remove duplicate/obsolete files. Use the corresponding
files in https://github.com/named-data/.github instead.

Change-Id: Ife0d7551dd44091a8343ea233072c22a03149a71
2021-08-30 21:48:42 -04:00
Davide Pesavento 13dae355cb ci: restrict token permissions and add badges to README.md
Change-Id: Ia7e254eefb6658aa5110a7fea5a6847cb257a84b
2021-08-13 15:40:54 -04:00
Davide Pesavento 8f0028de4e ci: add GitHub Actions
Change-Id: Idc715edf136550b088f89c19b581f5478b296653
2021-07-30 19:26:03 -04:00
Davide Pesavento 412c982a63 Reduce usage of std::bind()
C++14 lambdas are easier to read, easier to debug,
and can usually be better optimized by the compiler.

Change-Id: I294f275904f91942a8de946fe63e77078a7608a6
2021-07-02 00:21:05 -04:00
Philipp Moll a103334b1c fw: Add default HopLimit to Interest when missing
Refs: #5171
Change-Id: I5973811b5ca7c7cf5ff344872afa51b253b9cae8
2021-06-25 00:24:23 -04:00
Davide Pesavento 0498ce85b0 fw: reorder function params to make the strategy API more uniform
Also add a non-const overload of Face::getCounters to avoid const_cast

Refs: #5173
Change-Id: Iff0bfbdedb90e68a373090cf3f247d9a7501f58d
2021-06-14 14:18:03 -04:00
Davide Pesavento 7647cc7635 table: increase initial and minimum capacity of DeadNonceList
Change-Id: Iaec6299ed985fcf165e23d31a339a6cbf073b55d
2021-06-10 14:30:04 -04:00
Davide Pesavento e08cc4cd7e table: improve logging in DeadNonceList
Refs: #5165
Change-Id: I97f9e28af90d857b33808d385eb077380cafe00a
2021-06-09 03:03:32 -04:00
Varun Patil 67ad70fbd5 table: prevent duplicates in DeadNonceList
refs #5167

Change-Id: Ia7546f75b844cfa1d857a641b015fbc6e9dfaf3d
2021-06-07 16:18:02 -07:00
Davide Pesavento d69070ef50 ci+docs+tools: stop using deprecated ndnsec commands
Change-Id: If77f479b45581a9a70619c329e713524678e35fb
2021-06-04 18:50:52 -04:00
Davide Pesavento d412393379 table: DeadNonceList code cleanup/modernization
Change-Id: I7d2bb8982b60b138c979470406b0a607301f2768
2021-05-28 19:21:03 -04:00
Davide Pesavento 6a699be8cd tests: use InterestSigner instead of deprecated CommandInterestSigner
Change-Id: Iaf98026c9c0a7ee3950d79f4d810e0a7abba43b1
2021-05-17 02:13:37 -04:00
Davide Pesavento a47cca2634 build: make graphviz optional for building documentation
Change-Id: I5434bbef22c840341623bff16f9e8de129249be2
2021-04-16 02:30:11 -04:00
Eric Newberry 7249fb4d52 docs+tests: finalize migration to typed naming conventions
refs #5044

Change-Id: Ia6f52ae0a31db33ca0f9fa6c4553b8fbbc7809bc
2021-04-05 18:16:44 -04:00
Davide Pesavento 86644d36ff mgmt: don't extend the dataset expiration in ForwarderStatusManager
No other managers do this. Moreover, StatusDatasetContext::setExpiry()
has odd semantics and is being removed from ndn-cxx.

Change-Id: I5255aec5c6464e48f4b4765ae2c06f557e094044
2021-04-02 15:20:16 -04:00
Eric Newberry 358414d82f fw: remove reliance upon marker name components
refs #5044

Change-Id: Iea6c98e03dbd3e4463f7bb6fca0be4953a2cdc40
2021-03-25 21:10:38 -07:00
Davide Pesavento 22085365d2 mgmt: fix construction of CertificateRequest in CommandAuthenticatorValidationPolicy
Just pass the KeyLocator name and let CertificateRequest deal
with constructing the Interest and setting CanBePrefix

Refs: #4582
Change-Id: I323d8ac5e16605bb978addc623e525b2536238bf
2021-03-18 22:08:03 -04:00
Saurab Dulal 432be57380 fw: use per-upstream suppression in ASF strategy
Refs: #5140
Change-Id: I49b27ce6b55d01724d0eafa792785d081c6009f7
2021-03-17 16:50:10 -04:00
Davide Pesavento 3db9807200 daemon: mark some classes and methods 'final'
As suggested by gcc's -Wsuggest-final-types and -Wsuggest-final-methods

Change-Id: I1622857ee53581efd0c6ce3fe93199c72202d817
2021-03-15 18:15:01 -04:00
Davide Pesavento 03a75f6c88 tests: add test case for retx suppression in multicast strategy
Refs: #4066
Change-Id: I78953b91b1fc1c6599b83cd1f39c11722261dd98
2021-03-15 18:14:26 -04:00
Davide Pesavento 7922d12449 fw: rename BestRouteStrategy2 class to BestRouteStrategy
Also rename ad-hoc-forwarding.t.cpp to strategy-ad-hoc-face.t.cpp
and broadcast-medium.t.cpp to strategy-broadcast-medium.t.cpp,
for consistency with the other strategy-*.t.cpp test suites.

Change-Id: Ia8f5257260563732d74c7d58e35481b73a231f06
2021-03-09 20:11:24 -05:00
Davide Pesavento 580915891e fw: remove best-route strategy version 1
Change-Id: I7e86d5c19c01db65a84fdc0f289e7534f0774f4e
2021-03-09 11:45:43 -05:00
Davide Pesavento 29abf4cda2 fw: remove ncc strategy
Change-Id: I6de0acf51e965afcbda5cc943cb39daa78cabf2d
2021-03-09 01:43:46 -05:00
Junxiao Shi a6286a9e5a face: allow setting default UDP face MTU in config
refs #5138

Change-Id: Ibb3767b27aec2b046d1f41292f3d61001866f8c0
2021-02-24 12:11:45 -08:00
Alexander Afanasyev 40604e3a1f fw: Dispatch pending interests on new nexhop in multicast strategy
Change-Id: Ifac7b27c9943bd164d0a6579edc68fb959ebe887
Refs: #4931
2021-02-24 11:49:05 -05:00
Alexander Afanasyev 4400e428d4 fw: Remove NACKs from multicast strategy
Change-Id: I49b833ec0ad990dfdf547aef80915e3fc83389ec
Refs: #5146
2021-02-19 18:45:55 -05:00
Davide Pesavento 05590471e0 fw: eliminate Forwarder::dispatchToStrategy()
Change-Id: Ia2e58c66548644fe3395f7e8c65e860554484fc8
2021-02-17 15:53:27 -05:00
Davide Pesavento b21bed88ed fw: fix and simplify enumeration logic in Forwarder::onNewNextHop()
Also remove Strategy::enableNewNextHopTrigger(). Strategies can already
opt-in by overriding afterNewNextHop(), there is no need for a separate
enablement flag.

Refs: #4931
Change-Id: Ifcbdbc7e954bd20d9969fd99882a2a9aebbc8fcc
2021-02-17 15:09:32 -05:00
Davide Pesavento 264af77369 build: prepend "NFD_" to various macro names to avoid conflicts
Change-Id: Icc370968e3d38fef80ece35a2aed56450f54b653
2021-02-10 14:48:07 -05:00
Junxiao Shi 6aecc500e5 doc: accommodate certificate name in KeyLocator in sample nfd.conf
refs #5114

Change-Id: I648318e035fd06722dedc5181e03c108ac275e66
2021-02-07 13:11:56 -07:00
Junxiao Shi 7fb9071230 face: execute pcap_activate as root
refs #4647

Change-Id: Ib88bbebe5d6495e138b65b5b66865a0001aebef9
2021-01-27 10:31:16 -07:00
Davide Pesavento 9ab43e67db ci+docs: CentOS renamed the PowerTools repo to lowercase
Change-Id: I4b78986f3af17d2124824992e31b408ebe8de03a
2020-12-27 20:50:22 -05:00
Davide Pesavento cabd980030 build: upgrade waf to version 2.0.21
Change-Id: I63a240ce9386076dcfae429f954dc0eadb25f6fc
2020-11-20 01:01:43 -05:00
Davide Pesavento 2135375d36 tests: sync common testing infrastructure with ndn-cxx
Change-Id: I6feab5247231abc35b8daa96bca21ad17c9cc4b3
2020-11-20 00:43:44 -05:00
538 changed files with 11019 additions and 13300 deletions

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
Dockerfile
/build/
.waf-*-*/
.waf3-*-*/
.lock-waf*
/VERSION.info
+21
View File
@@ -0,0 +1,21 @@
name: CI
on:
push:
paths-ignore:
- 'docs/**'
- '*.conf.sample*'
- '*.md'
- '.mailmap'
workflow_dispatch:
permissions: {}
jobs:
Ubuntu:
uses: named-data/actions/.github/workflows/jenkins-script-ubuntu.yml@v1
with:
submodules: true
macOS:
uses: named-data/actions/.github/workflows/jenkins-script-macos.yml@v1
with:
submodules: true
+81
View File
@@ -0,0 +1,81 @@
name: Publish Docker image
on:
push:
branches:
- master
paths-ignore:
- '*.md'
- '.mailmap'
workflow_dispatch:
permissions:
contents: read
packages: write
env:
REGISTRY: ghcr.io
jobs:
nfd:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
- name: Login to ${{ env.REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/nfd
flavor: latest=true
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
pull: true
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
nfd-status-http-server:
needs: nfd
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Login to ${{ env.REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/nfd-status-http-server
flavor: latest=true
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./tools
file: ./tools/Dockerfile.nfd-status-http-server
pull: true
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
+24
View File
@@ -0,0 +1,24 @@
name: Docs
on:
push:
workflow_dispatch:
inputs:
skip-deploy:
description: 'Skip deployment?'
required: true
type: boolean
permissions: {}
jobs:
html:
uses: named-data/actions/.github/workflows/docs-html.yml@v1
with:
submodules: true
# Deploy only the master branch and release tags
deploy: ${{ !inputs.skip-deploy && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/NFD-')) }}
secrets: inherit
man:
uses: named-data/actions/.github/workflows/docs-man.yml@v1
with:
submodules: true
+36 -16
View File
@@ -1,32 +1,52 @@
#!/usr/bin/env bash
set -e
source .jenkins.d/util.sh
set -eo pipefail
case $(uname) in
Linux)
if [[ -e /etc/os-release ]]; then
source /etc/os-release
else
source /usr/lib/os-release
fi
export ID VERSION_ID
export ID_LIKE="${ID} ${ID_LIKE} linux"
export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
;;
Darwin)
# Emulate a subset of os-release(5)
export ID=macos
export VERSION_ID=$(sw_vers -productVersion)
export PATH="/usr/local/bin${PATH:+:}${PATH}"
if [[ -x /opt/homebrew/bin/brew ]]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [[ -x /usr/local/bin/brew ]]; then
eval "$(/usr/local/bin/brew shellenv)"
fi
;;
esac
export CACHE_DIR=${CACHE_DIR:-/tmp}
export WAF_JOBS=${WAF_JOBS:-1}
[[ $JOB_NAME == *"code-coverage" ]] && export DISABLE_ASAN=yes
nanos() {
# Cannot use date(1) because macOS does not support %N format specifier
python3 -c 'import time; print(int(time.time() * 1e9))'
}
if [[ $JOB_NAME == *"code-coverage" ]]; then
export DISABLE_ASAN=yes
export DISABLE_HEADERS_CHECK=yes
fi
# https://reproducible-builds.org/docs/source-date-epoch/
export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)
for file in .jenkins.d/*; do
[[ -f $file && -x $file ]] || continue
if [[ -n $TRAVIS ]]; then
if [[ -n $GITHUB_ACTIONS ]]; then
label=$(basename "$file" | sed -E 's/[[:digit:]]+-(.*)\..*/\1/')
echo -ne "travis_fold:start:${label}\r"
echo -ne "travis_time:start:${label}\r"
start=$(nanos)
echo "::group::${label}"
fi
echo "\$ $file"
"$file"
if [[ -n $TRAVIS ]]; then
finish=$(nanos)
echo -ne "travis_time:end:${label}:start=${start},finish=${finish},duration=$((finish-start)),event=${label}\r"
echo -ne "travis_fold:end:${label}\r"
if [[ -n $GITHUB_ACTIONS ]]; then
echo "::endgroup::"
fi
done
+33 -34
View File
@@ -1,41 +1,40 @@
#!/usr/bin/env bash
set -ex
set -eo pipefail
if has OSX $NODE_LABELS; then
FORMULAE=(boost openssl pkg-config)
if has OSX-10.13 $NODE_LABELS || has OSX-10.14 $NODE_LABELS; then
FORMULAE+=(python)
APT_PKGS=(build-essential pkg-config python3-minimal
libboost-all-dev libssl-dev libsqlite3-dev
libpcap-dev libsystemd-dev)
FORMULAE=(boost openssl pkg-config)
PIP_PKGS=()
case $JOB_NAME in
*code-coverage)
APT_PKGS+=(lcov python3-pip)
PIP_PKGS+=('gcovr~=5.2')
;;
*Docs)
APT_PKGS+=(doxygen graphviz python3-pip)
FORMULAE+=(doxygen graphviz)
PIP_PKGS+=(sphinx sphinxcontrib-doxylink)
;;
esac
set -x
if [[ $ID == macos ]]; then
if [[ -n $GITHUB_ACTIONS ]]; then
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
fi
if [[ -n $TRAVIS ]]; then
# Travis images come with a large number of pre-installed
# brew packages, don't waste time upgrading all of them
brew list --versions "${FORMULAE[@]}" || brew update
for FORMULA in "${FORMULAE[@]}"; do
brew list --versions "$FORMULA" || brew install "$FORMULA"
done
# Ensure /usr/local/opt/openssl exists
brew reinstall openssl
else
brew update
brew upgrade
brew install "${FORMULAE[@]}"
brew cleanup
fi
elif has Ubuntu $NODE_LABELS; then
brew update
brew install --formula "${FORMULAE[@]}"
elif [[ $ID_LIKE == *debian* ]]; then
sudo apt-get -qq update
sudo apt-get -qy install build-essential pkg-config python3-minimal \
libboost-all-dev libssl-dev libsqlite3-dev \
libpcap-dev libsystemd-dev
if [[ $JOB_NAME == *"code-coverage" ]]; then
sudo apt-get -qy install gcovr lcov
fi
elif has CentOS-8 $NODE_LABELS; then
sudo dnf config-manager --enable PowerTools
sudo dnf -y install gcc-c++ libasan pkgconf-pkg-config python3 \
sudo apt-get -qy install "${APT_PKGS[@]}"
elif [[ $ID_LIKE == *fedora* ]]; then
sudo dnf -y install gcc-c++ libasan lld pkgconf-pkg-config python3 \
boost-devel openssl-devel sqlite-devel \
libpcap-devel systemd-devel
fi
if (( ${#PIP_PKGS[@]} )); then
pip3 install --user --upgrade --upgrade-strategy=eager "${PIP_PKGS[@]}"
fi
+8 -13
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env bash
set -ex
set -exo pipefail
pushd "$CACHE_DIR" >/dev/null
INSTALLED_VERSION=
if has OSX $NODE_LABELS; then
BOOST=$(brew ls --versions boost)
if [[ $ID == macos ]]; then
BOOST=$(brew list --formula --versions boost)
OLD_BOOST=$(cat boost.txt || :)
if [[ $OLD_BOOST != $BOOST ]]; then
echo "$BOOST" > boost.txt
@@ -35,21 +35,16 @@ sudo rm -f /usr/local/lib{,64}/pkgconfig/libndn-cxx.pc
pushd ndn-cxx >/dev/null
if has CentOS-8 $NODE_LABELS; then
# https://bugzilla.redhat.com/show_bug.cgi?id=1721553
PCH="--without-pch"
fi
./waf --color=yes configure --disable-static --enable-shared --without-osx-keychain $PCH
./waf --color=yes build -j$WAF_JOBS
sudo_preserve_env PATH -- ./waf --color=yes install
./waf --color=yes configure --without-osx-keychain
./waf --color=yes build
sudo ./waf --color=yes install
popd >/dev/null
popd >/dev/null
if has CentOS-8 $NODE_LABELS; then
if [[ $ID_LIKE == *fedora* ]]; then
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
fi
if has Linux $NODE_LABELS; then
if [[ $ID_LIKE == *linux* ]]; then
sudo ldconfig
fi
+8 -10
View File
@@ -1,8 +1,5 @@
#!/usr/bin/env bash
set -ex
git submodule sync
git submodule update --init
set -eo pipefail
if [[ -z $DISABLE_ASAN ]]; then
ASAN="--with-sanitizer=address"
@@ -10,22 +7,23 @@ fi
if [[ $JOB_NAME == *"code-coverage" ]]; then
COVERAGE="--with-coverage"
fi
if has CentOS-8 $NODE_LABELS; then
# https://bugzilla.redhat.com/show_bug.cgi?id=1721553
if [[ -n $DISABLE_PCH ]]; then
PCH="--without-pch"
fi
set -x
if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
# Build in release mode with tests and without precompiled headers
./waf --color=yes configure --with-tests --without-pch
./waf --color=yes build -j$WAF_JOBS
./waf --color=yes build
# Cleanup
./waf --color=yes distclean
# Build in release mode without tests, but with "other tests"
./waf --color=yes configure --with-other-tests $PCH
./waf --color=yes build -j$WAF_JOBS
./waf --color=yes build
# Cleanup
./waf --color=yes distclean
@@ -33,9 +31,9 @@ fi
# Build in debug mode with tests
./waf --color=yes configure --debug --with-tests $ASAN $COVERAGE $PCH
./waf --color=yes build -j$WAF_JOBS
./waf --color=yes build
# (tests will be run against the debug version)
# Install
sudo_preserve_env PATH -- ./waf --color=yes install
sudo ./waf --color=yes install
+10 -13
View File
@@ -1,14 +1,5 @@
#!/usr/bin/env bash
set -ex
# Prepare environment
rm -rf ~/.ndn
if has OSX $NODE_LABELS; then
security unlock-keychain -p named-data
fi
ndnsec-keygen "/tmp/jenkins/$NODE_NAME" | ndnsec-install-cert -
set -eo pipefail
# https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
ASAN_OPTIONS="color=always"
@@ -22,6 +13,7 @@ ASAN_OPTIONS+=":detect_leaks=0"
ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
export ASAN_OPTIONS
# https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/runtime_config/summary.html
export BOOST_TEST_BUILD_INFO=1
export BOOST_TEST_COLOR_OUTPUT=1
export BOOST_TEST_DETECT_MEMORY_LEAK=0
@@ -30,6 +22,11 @@ ut_log_args() {
echo --logger=HRF,test_suite,stdout:XML,all,build/xunit-log${1:+-$1}.xml
}
set -x
# Prepare environment
rm -rf ~/.ndn
# First run all tests as unprivileged user
./build/unit-tests-core $(ut_log_args core)
./build/unit-tests-daemon $(ut_log_args daemon)
@@ -37,9 +34,9 @@ ut_log_args() {
./build/unit-tests-tools $(ut_log_args tools)
# Then use sudo to run those tests that need superuser powers
sudo_preserve_env ASAN_OPTIONS BOOST_TEST_COLOR_OUTPUT -- \
sudo --preserve-env=ASAN_OPTIONS,BOOST_TEST_COLOR_OUTPUT \
./build/unit-tests-daemon -t TestPrivilegeHelper $(ut_log_args daemon-privilege-helper)
sudo_preserve_env ASAN_OPTIONS BOOST_TEST_COLOR_OUTPUT -- \
sudo --preserve-env=ASAN_OPTIONS,BOOST_TEST_COLOR_OUTPUT \
./build/unit-tests-daemon -t Face/*Ethernet* $(ut_log_args daemon-ethernet)
sudo_preserve_env ASAN_OPTIONS BOOST_TEST_COLOR_OUTPUT -- \
sudo --preserve-env=ASAN_OPTIONS,BOOST_TEST_COLOR_OUTPUT \
./build/unit-tests-daemon -t Face/TestUdpFactory $(ut_log_args daemon-udp)
+15 -18
View File
@@ -1,35 +1,32 @@
#!/usr/bin/env bash
set -ex
set -exo pipefail
if [[ $JOB_NAME == *"code-coverage" ]]; then
gcovr --object-directory=build \
--output=build/coverage.xml \
--exclude="$PWD/(tests|websocketpp)" \
--root=. \
--xml
# Generate an XML report (Cobertura format) and a detailed HTML report using gcovr
# Note: trailing slashes are important in the paths below. Do not remove them!
gcovr --object-directory build \
--exclude tests/ \
--exclude websocketpp/ \
--exclude-throw-branches \
--exclude-unreachable-branches \
--cobertura build/coverage.xml \
--html-details build/gcovr/ \
--print-summary
# Generate also a detailed HTML output, but using lcov (better results)
# Generate a detailed HTML report using lcov
lcov --quiet \
--capture \
--directory . \
--exclude "$PWD/tests/*" \
--exclude "$PWD/websocketpp/*" \
--no-external \
--rc lcov_branch_coverage=1 \
--output-file build/coverage-with-tests-and-websocketpp.info
lcov --quiet \
--remove build/coverage-with-tests-and-websocketpp.info "$PWD/websocketpp/*" \
--rc lcov_branch_coverage=1 \
--output-file build/coverage-with-tests.info
lcov --quiet \
--remove build/coverage-with-tests.info "$PWD/tests/*" \
--rc lcov_branch_coverage=1 \
--output-file build/coverage.info
genhtml --branch-coverage \
--demangle-cpp \
--legend \
--output-directory build/coverage \
--output-directory build/lcov \
--title "NFD unit tests" \
build/coverage.info
fi
+24 -16
View File
@@ -1,28 +1,36 @@
# CONTINUOUS INTEGRATION SCRIPTS
# Continuous Integration Scripts
## Environment Variables Used in Build Scripts
## Environment Variables
- `NODE_LABELS`: space-separated list of platform properties. The included values are used by
the build scripts to select the proper behavior for different operating systems and versions.
- `ID`: lower-case string that identifies the operating system, for example: `ID=ubuntu`,
`ID=centos`. See [os-release(5)] for more information. On macOS, where `os-release` is
not available, we emulate it by setting `ID=macos`.
The list should normally contain `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
- `ID_LIKE`: space-separated list of operating system identifiers that are closely related
to the running OS. See [os-release(5)] for more information. The listed values are used
by the CI scripts to select the proper behavior for different platforms and OS flavors.
Example values:
Examples:
- `[OS_TYPE]`: `Linux`, `OSX`
- `[DISTRO_TYPE]`: `Ubuntu`, `CentOS`
- `[DISTRO_VERSION]`: `Ubuntu-16.04`, `Ubuntu-18.04`, `CentOS-8`, `OSX-10.14`, `OSX-10.15`
- On CentOS, `ID_LIKE="centos rhel fedora linux"`
- On Ubuntu, `ID_LIKE="ubuntu debian linux"`
- `JOB_NAME`: optional variable that defines the type of build job. Depending on the job type,
the build scripts can perform different tasks.
- `VERSION_ID`: identifies the operating system version, excluding any release code names.
See [os-release(5)] for more information. Examples: `VERSION_ID=42`, `VERSION_ID=22.04`.
Possible values:
- `JOB_NAME`: defines the type of the current CI job. Depending on the job type, the CI
scripts can perform different tasks.
Supported values:
- empty: default build task
- `code-coverage`: debug build with tests and code coverage analysis (Ubuntu Linux is assumed)
- `code-coverage`: debug build with tests and code coverage analysis
- `limited-build`: only a single debug build with tests
- `CACHE_DIR`: directory containing cached files from previous builds, e.g., a compiled version
of ndn-cxx. If not set, `/tmp` is used.
- `CACHE_DIR`: directory containing cached files from previous builds, e.g., a compiled
version of ndn-cxx. If not set, `/tmp` is used.
- `WAF_JOBS`: number of parallel build threads used by waf, defaults to 1.
- `DISABLE_ASAN`: disable building with AddressSanitizer. This is automatically set for
the `code-coverage` job type.
[os-release(5)]: https://www.freedesktop.org/software/systemd/man/os-release.html
-39
View File
@@ -1,39 +0,0 @@
has() {
local saved_xtrace
[[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
set +x
local p=$1
shift
local i ret=1
for i in "$@"; do
if [[ "${i}" == "${p}" ]]; then
ret=0
break
fi
done
set ${saved_xtrace}
return ${ret}
}
export -f has
sudo_preserve_env() {
local saved_xtrace
[[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
set +x
local vars=()
while [[ $# -gt 0 ]]; do
local arg=$1
shift
case ${arg} in
--) break ;;
*) vars+=("${arg}=${!arg}") ;;
esac
done
set ${saved_xtrace}
sudo env "${vars[@]}" "$@"
}
export -f sudo_preserve_env
+9 -7
View File
@@ -1,14 +1,16 @@
<aa@cs.fiu.edu> <alexander.afanasyev@ucla.edu>
Alexander Lane <awlane@memphis.edu>
<chghasemi@cs.arizona.edu> <chavoosh.ghasemi@gmail.com>
<davidepesa@gmail.com> <davide.pesavento@lip6.fr>
<enewberry@email.arizona.edu> <enewberry@cs.arizona.edu>
Vince Lehman <vslehman@memphis.edu> <vlehman1@gmail.com>
<lybmath2009@gmail.com> <lybmath@ucla.edu>
Hila Ben Abraham <hilata@gmail.com>
<tuyukai1994@gmail.com> <tyk@bupt.edu.cn>
Haowei Yuan <hyuan@wustl.edu>
Hila Ben Abraham <hilata@gmail.com>
<lybmath2009@gmail.com> <lybmath@ucla.edu>
Md Ashiqur Rahman <marahman@email.arizona.edu>
Minsheng Zhang <jimmyzms5@gmail.com>
Spyridon Mastorakis <spiros.mastorakis@gmail.com>
Md Ashiqur Rahman <marahman@email.arizona.edu>
Yumin Xia <me@yumin-xia.com>
<chghasemi@cs.arizona.edu> <chavoosh.ghasemi@gmail.com>
Susmit Shannigrahi <susmit@cs.colostate.edu>
Tai-Lin Chu <tailinchu@gmail.com>
<tuyukai1994@gmail.com> <tyk@bupt.edu.cn>
Vince Lehman <vslehman@memphis.edu> <vlehman1@gmail.com>
Yumin Xia <me@yumin-xia.com>
-115
View File
@@ -1,115 +0,0 @@
version: ~> 1.0
language: cpp
os: linux
dist: bionic
arch:
- amd64
#- arm64 # Too slow, exceeds time limit
#- ppc64le # Fails transport tests
#- s390x # Fails transport tests
env:
- COMPILER=g++-7
- COMPILER=g++-9
- COMPILER=clang++-6.0
- COMPILER=clang++-9
jobs:
include:
# Linux
- env: COMPILER=g++-5
- env: COMPILER=g++-6
- env: COMPILER=g++-8
- env: COMPILER=clang++-4.0
- env: COMPILER=clang++-5.0
- env: COMPILER=clang++-7
- env: COMPILER=clang++-8
- env: COMPILER=clang++-10
- env: COMPILER=clang++-11
- env: COMPILER=clang++-12
# macOS
- os: osx
osx_image: xcode9.4
env: # default compiler
- os: osx
osx_image: xcode10.1
env: # default compiler
- os: osx
osx_image: xcode10.3
env: # default compiler
- os: osx
osx_image: xcode11.3
env: # default compiler
- os: osx
osx_image: xcode11.6
env: # default compiler
- os: osx
osx_image: xcode12
env: # default compiler
allow_failures:
- env: COMPILER=g++-5
- env: COMPILER=g++-6
- env: COMPILER=clang++-4.0
- env: COMPILER=clang++-12
fast_finish: true
before_install:
- |
: Adding apt repositories
case ${COMPILER} in
g++-9)
# https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages
travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
travis_retry sudo apt-get -qq update
;;
clang++-1?)
# https://apt.llvm.org/
LLVM_REPO=${COMPILER/clang++/llvm-toolchain-${TRAVIS_DIST}}
travis_retry wget -nv -O - "https://apt.llvm.org/llvm-snapshot.gpg.key" | sudo apt-key add -
travis_retry sudo add-apt-repository -y "deb http://apt.llvm.org/${TRAVIS_DIST}/ ${LLVM_REPO%-12} main"
travis_retry sudo apt-get -qq update
;;
esac
install:
- |
: Installing C++ compiler
if [[ -n ${COMPILER} ]]; then
travis_retry sudo apt-get -qy install ${COMPILER/clang++/clang}
fi
before_script:
- |
: Setting environment variables
if [[ -n ${COMPILER} ]]; then
export CXX=${COMPILER}
fi
case ${TRAVIS_OS_NAME} in
linux) export NODE_LABELS="Linux Ubuntu Ubuntu-18.04" ;;
osx) export NODE_LABELS="OSX OSX-$(sw_vers -productVersion | cut -d . -f -2)" ;;
esac
export JOB_NAME=limited-build
export WAF_JOBS=2
- |
: Enabling workarounds
case "${TRAVIS_CPU_ARCH},${COMPILER}" in
ppc64le,g++-7)
# AddressSanitizer does not seem to be working
export DISABLE_ASAN=yes
;;
*,clang++-8)
# https://bugs.llvm.org/show_bug.cgi?id=40808
export DISABLE_ASAN=yes
;;
esac
if [[ ${TRAVIS_OS_NAME} == linux ]]; then
sudo sysctl -e -w net.ipv6.conf.all.disable_ipv6=0
fi
- ${CXX:-c++} --version
script:
- ./.jenkins
+2 -2
View File
@@ -54,8 +54,8 @@ 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']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/homebrew/lib', '/opt/local/lib', '/sw/lib', '/lib']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/homebrew/include', '/opt/local/include', '/sw/include']
BOOST_VERSION_FILE = 'boost/version.hpp'
BOOST_VERSION_CODE = '''
+91 -78
View File
@@ -3,10 +3,12 @@
import platform
from waflib import Configure, Logs, Utils
def options(opt):
opt.add_option('--debug', '--with-debug', action='store_true', default=False,
help='Compile in debugging mode with minimal optimizations (-Og)')
def configure(conf):
conf.start_msg('Checking C++ compiler version')
@@ -16,23 +18,27 @@ def configure(conf):
errmsg = ''
warnmsg = ''
if cxx == 'gcc':
if ccver < (5, 3, 0):
if ccver < (7, 4, 0):
errmsg = ('The version of gcc you are using is too old.\n'
'The minimum supported gcc version is 7.4.0.')
elif ccver < (7, 4, 0):
warnmsg = ('Using a version of gcc older than 7.4.0 is not '
'The minimum supported gcc version is 9.3.')
elif ccver < (9, 3, 0):
warnmsg = ('Using a version of gcc older than 9.3 is not '
'officially supported and may result in build failures.')
conf.flags = GccFlags()
elif cxx == 'clang':
if Utils.unversioned_sys_platform() == 'darwin' and ccver < (9, 0, 0):
errmsg = ('The version of Xcode you are using is too old.\n'
'The minimum supported Xcode version is 9.0.')
elif ccver < (4, 0, 0):
if Utils.unversioned_sys_platform() == 'darwin':
if ccver < (10, 0, 0):
errmsg = ('The version of Xcode you are using is too old.\n'
'The minimum supported Xcode version is 12.4.')
elif ccver < (12, 0, 0):
warnmsg = ('Using a version of Xcode older than 12.4 is not '
'officially supported and may result in build failures.')
elif ccver < (7, 0, 0):
errmsg = ('The version of clang you are using is too old.\n'
'The minimum supported clang version is 4.0.')
'The minimum supported clang version is 7.0.')
conf.flags = ClangFlags()
else:
warnmsg = '%s compiler is unsupported' % cxx
warnmsg = f'{cxx} compiler is unsupported'
conf.flags = CompilerFlags()
if errmsg:
@@ -44,7 +50,7 @@ def configure(conf):
else:
conf.end_msg(ccverstr)
conf.areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
conf.areCustomCxxflagsPresent = len(conf.env.CXXFLAGS) > 0
# General flags are always applied (e.g., selecting C++ language standard)
generalFlags = conf.flags.getGeneralFlags(conf)
@@ -52,6 +58,7 @@ def configure(conf):
conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
conf.env.DEFINES += generalFlags['DEFINES']
@Configure.conf
def check_compiler_flags(conf):
# Debug or optimized CXXFLAGS and LINKFLAGS are applied only if the
@@ -74,10 +81,11 @@ def check_compiler_flags(conf):
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
Check which cxxflags are supported by the active compiler and add them to env.CXXFLAGS variable.
"""
if len(cxxflags) == 0:
return
@@ -93,10 +101,11 @@ def add_supported_cxxflags(self, cxxflags):
self.end_msg(' '.join(supportedFlags))
self.env.prepend_value('CXXFLAGS', supportedFlags)
@Configure.conf
def add_supported_linkflags(self, linkflags):
"""
Check which linkflags are supported by compiler and add them to env.LINKFLAGS variable
Check which linkflags are supported by the active compiler and add them to env.LINKFLAGS variable.
"""
if len(linkflags) == 0:
return
@@ -113,13 +122,17 @@ def add_supported_linkflags(self, linkflags):
self.env.prepend_value('LINKFLAGS', supportedFlags)
class CompilerFlags(object):
class CompilerFlags:
def getCompilerVersion(self, conf):
return tuple(int(i) for i in conf.env.CC_VERSION)
def getGeneralFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
return {
'CXXFLAGS': [],
'LINKFLAGS': [],
'DEFINES': ['BOOST_FILESYSTEM_NO_DEPRECATED'],
}
def getDebugFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
@@ -129,99 +142,99 @@ class CompilerFlags(object):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in optimized mode"""
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['NDEBUG']}
class GccBasicFlags(CompilerFlags):
class GccClangCommonFlags(CompilerFlags):
"""
This class defines basic flags that work for both gcc and clang compilers
This class defines common flags that work for both gcc and clang compilers.
"""
def getGeneralFlags(self, conf):
flags = super(GccBasicFlags, self).getGeneralFlags(conf)
flags['CXXFLAGS'] += ['-std=c++14']
if Utils.unversioned_sys_platform() == 'linux':
flags['LINKFLAGS'] += ['-fuse-ld=gold']
elif Utils.unversioned_sys_platform() == 'freebsd':
flags = super().getGeneralFlags(conf)
flags['CXXFLAGS'] += ['-std=c++17']
if Utils.unversioned_sys_platform() != 'darwin':
flags['LINKFLAGS'] += ['-fuse-ld=lld']
return flags
__cxxFlags = [
'-fdiagnostics-color',
'-Wall',
'-Wextra',
'-Wpedantic',
'-Wenum-conversion',
'-Wextra-semi',
'-Wno-unused-parameter',
]
__linkFlags = ['-Wl,-O1']
def getDebugFlags(self, conf):
flags = super(GccBasicFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-Og',
'-g3',
'-pedantic',
'-Wall',
'-Wextra',
'-Werror',
'-Wcatch-value=2',
'-Wextra-semi',
'-Wnon-virtual-dtor',
'-Wno-error=deprecated-declarations', # Bug #3795
'-Wno-error=maybe-uninitialized', # Bug #1615
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-Wl,-O1']
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += ['-Og', '-g'] + self.__cxxFlags + [
'-Werror',
'-Wno-error=deprecated-declarations', # Bug #3795
'-Wno-error=maybe-uninitialized', # Bug #1615
]
flags['LINKFLAGS'] += self.__linkFlags
return flags
def getOptimizedFlags(self, conf):
flags = super(GccBasicFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-O2',
'-g',
'-pedantic',
'-Wall',
'-Wextra',
'-Wcatch-value=2',
'-Wextra-semi',
'-Wnon-virtual-dtor',
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-Wl,-O1']
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-O2', '-g1'] + self.__cxxFlags
flags['LINKFLAGS'] += self.__linkFlags
return flags
class GccFlags(GccBasicFlags):
class GccFlags(GccClangCommonFlags):
__cxxFlags = [
'-Wcatch-value=2',
'-Wcomma-subscript', # enabled by default in C++20
'-Wduplicated-branches',
'-Wduplicated-cond',
'-Wlogical-op',
'-Wredundant-tags',
'-Wvolatile', # enabled by default in C++20
]
def getDebugFlags(self, conf):
flags = super(GccFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-fdiagnostics-color',
'-Wredundant-tags',
]
if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
if platform.machine() == 'armv7l':
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
return flags
def getOptimizedFlags(self, conf):
flags = super(GccFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fdiagnostics-color',
'-Wredundant-tags',
]
if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
if platform.machine() == 'armv7l':
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
return flags
class ClangFlags(GccBasicFlags):
class ClangFlags(GccClangCommonFlags):
def getGeneralFlags(self, conf):
flags = super(ClangFlags, self).getGeneralFlags(conf)
flags = super().getGeneralFlags(conf)
if Utils.unversioned_sys_platform() == 'darwin':
# Bug #4296
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
['-isystem', '/opt/local/include']] # for MacPorts
brewdir = '/opt/homebrew' if platform.machine() == 'arm64' else '/usr/local'
flags['CXXFLAGS'] += [
['-isystem', f'{brewdir}/include'], # for Homebrew
['-isystem', '/opt/local/include'], # for MacPorts
]
elif Utils.unversioned_sys_platform() == 'freebsd':
# Bug #4790
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']]
return flags
__cxxFlags = [
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
def getDebugFlags(self, conf):
flags = super(ClangFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
if self.getCompilerVersion(conf) < (6, 0, 0):
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
return flags
def getOptimizedFlags(self, conf):
flags = super(ClangFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
if self.getCompilerVersion(conf) < (6, 0, 0):
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
return flags
+1 -1
View File
@@ -53,10 +53,10 @@ def checkWebsocket(self, **kw):
self.end_msg('.'.join(self.env.WEBSOCKET_VERSION))
self.env.append_unique('DEFINES', ['_WEBSOCKETPP_CPP11_STL_'])
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:
+6 -5
View File
@@ -1,12 +1,12 @@
# NFD Authors
The following lists maintainers, primary developers, and all much-appreciated contributors to NFD in alphabetic order.
The following lists maintainers, primary developers, and all much-appreciated contributors to NFD in alphabetical order.
The specific contributions of individual authors can be obtained from the git history of the [official NFD repository](https://github.com/named-data/NFD).
If you would like to become a contributor to the official repository, please follow the recommendations in https://github.com/named-data/.github/blob/master/CONTRIBUTING.md.
If you would like to become a contributor to the official repository, please follow the recommendations in <https://github.com/named-data/.github/blob/main/CONTRIBUTING.md>.
* Jerald Paul Abraham <https://cs.arizona.edu/~jeraldabraham>
* ***(Maintainer)*** Alexander Afanasyev <https://users.cs.fiu.edu/~afanasyev>
* Syed Obai Amin <http://obaidamin.weebly.com>
* Syed Obaid Amin <http://obaidamin.weebly.com>
* Hila Ben Abraham <https://sites.wustl.edu/hbabraham>
* Muktadir R Chowdhury <https://github.com/alvyC>
* Tai-Lin Chu <https://www.linkedin.com/pub/tai-lin-chu/55/5b2/669>
@@ -19,6 +19,7 @@ If you would like to become a contributor to the official repository, please fol
* Nick Gordon <https://github.com/gorgonical>
* Giulio Grassi <https://www.lip6.fr/actualite/personnes-fiche.php?ident=D1461>
* Yi Huang <https://www.linkedin.com/in/yihuang1991>
* Alexander Lane <https://github.com/awlane>
* Jongseok Lee <https://github.com/imwhiz>
* Spencer Lee <https://www.linkedin.com/in/spenlee>
* Vince Lehman <http://vslehman.com>
@@ -31,7 +32,7 @@ If you would like to become a contributor to the official repository, please fol
* Eric Newberry <https://ericnewberry.com>
* Ju Pan <https://cs-jupan.com>
* João Pereira <http://website.jpereira.co.uk>
* Davide Pesavento <https://github.com/Pesa>
* ***(Maintainer)*** Davide Pesavento <https://github.com/Pesa>
* Felix Rabe <https://twitter.com/felixrabe>
* Md Ashiqur Rahman <https://ashiqrahman.com>
* Matteo Sammarco <https://www.linkedin.com/in/matteo-sammarco-9b544530>
@@ -55,7 +56,7 @@ If you would like to become a contributor to the official repository, please fol
* Patrick Crowley <https://www.arl.wustl.edu/~pcrowley>
* Christos Papadopoulos <https://www.cs.colostate.edu/~christos>
* Giovanni Pau <http://www.cs.ucla.edu/~gpau/Giovanni_Paus_Home_Page/Home.html>
* Giovanni Pau <https://www.unibo.it/sitoweb/giovanni.pau/en>
* Tian Song <http://www.bit-netlab.org/songtian>
* Lan Wang <http://www.cs.memphis.edu/~lanwang>
* Beichuan Zhang <https://cs.arizona.edu/~bzhang>
+17
View File
@@ -0,0 +1,17 @@
cff-version: 1.2.0
message: If you use NFD in your research, please cite it as below.
license: GPL-3.0-or-later
repository-code: "https://github.com/named-data/NFD"
title: Named Data Networking Forwarding Daemon
url: "https://docs.named-data.net/NFD/"
preferred-citation:
authors:
- name: Named Data Networking Project Team
date-published: "2021-07-30"
journal: NDN Technical Report NDN-0021
month: 7
title: NFD Developer's Guide
type: generic
url: "https://named-data.net/publications/techreports/ndn-0021-11-nfd-guide/"
version: 11
year: 2021
-81
View File
@@ -1,81 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our
project and our community a harassment-free experience for everyone,
regardless of age, body size, disability, ethnicity, gender identity
and expression, level of experience, nationality, personal appearance,
race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive
environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual
attention or advances
* Trolling, insulting/derogatory comments, and personal or political
attacks
* Public or private harassment
* Publishing others' private information, such as a physical or
electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in
a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of
acceptable behavior and are expected to take appropriate and fair
corrective action in response to any instances of unacceptable
behavior.
Project maintainers have the right and responsibility to remove, edit,
or reject comments, commits, code, wiki edits, issues, and other
contributions that are not aligned to this Code of Conduct, or to ban
temporarily or permanently any contributor for other behaviors that
they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public
spaces when an individual is representing the project or its
community. Examples of representing a project or community include
using an official project e-mail address, posting via an official
social media account, or acting as an appointed representative at an
online or offline event. Representation of a project may be further
defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior
may be reported by contacting the project leaders Lixia Zhang,
Beichuan Zhang, or Alex Afanasyev
at
[lixia@cs.ucla.edu](mailto:lixia@cs.ucla.edu),
[bzhang@cs.arizona.edu](mailto:bzhang@cs.arizona.edu),
and [aa@cs.ucla.edu](mailto:aa@cs.ucla.edu). All complaints will be
reviewed and investigated and will result in a response that is deemed
necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of
an incident. Further details of specific enforcement policies may be
posted separately.
Project maintainers who do not follow or enforce the Code of Conduct
in good faith may face temporary or permanent repercussions as
determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from
the [Contributor Covenant](http://contributor-covenant.org), version 1.4, available
at [http://contributor-covenant.org/version/1/4](http://contributor-covenant.org/version/1/4/)
-489
View File
@@ -1,489 +0,0 @@
# Contributing to the NDN Codebase
## Getting Started
The NDN team is very glad you are interested in contributing! The NDN
(Named Data Networking) codebase is composed of many projects, with
multiple universities across the world contributing. This
documentation will help you understand how we work and what we expect
from contributors.
### Code of Conduct
NDN codebase development adheres to the Contributor Covenant, located
in `CODE_OF_CONDUCT.md`. By contributing, you are expected to also
adhere to this code. If you feel someone has breached this code of
conduct,
please
[email us](mailto:lixia@cs.ucla.edu,bzhang@cs.arizona.edu,aa@cs.ucla.edu).
### What can I do?
The NDN codebase continually needs help with, among other
things:
1. Implementing new features
2. Writing fixes for bugs
3. Writing documentation for features that have recently changed or
that change quickly. Sometimes people forget to update
documentation!
4. Code review
## Finding Documentation
The NDN team maintains a community
([Redmine site](https://redmine.named-data.net/projects/nfd)) for
issue tracking and documentation hosting. Redmine is the hub for
design activity. In particular, all design discussion and decisions
will either occur or be copied there.
**Why did they do it *this* way?** When writing code, if you ever have
questions about why some design decision was made, the best approach
is to use `git blame` on a file to inspect the last commit for some
line of code. In this view there will be a commit hash in hex
(e.g. `0ab12e3a`) in the first column. Using our example, `git show
0ab12e3a` would show the commit made for that line. In the commit view
there should be a reference number (e.g. `refs: #1234`). Using this
number, you can find a pertaining issue on the Redmine
(e.g., `https://redmine.named-data.net/issues/1234`).
Additionally, in some cases there are published papers you can read in
order to gain a better understanding of the project. Searching for
these papers is not difficult; in many cases you can find a pertaining
paper or technical report listed on
[the main NDN website](https://named-data.net/publications).
Usually the title of a project will be a good keyword.
If you cannot find an answer to your question, the best place to go is
the
[mailing lists](https://named-data.net/codebase/platform/support/mailing-lists/).
There are multiple different lists for different interests, so be sure you
are mailing the right list for a quick response.
## Tracking work on Redmine ##
As mentioned above, Redmine is the organizational hub of the NDN
projects. As such, extensive use of it is made, and learning how it
works will help you. In particular, there is a workflow associated
with Redmine. Generally it is:
1. An issue is reported by someone. At this point they should
describe the issue, including relationships to other
issues. Unless they know what they're doing, they should leave
particulars blank. Such particulars are priority, target version,
assignees, and categories.
2. Design discussion about the issue occurs, and the issue is either
accepted or rejected.
3. Someone either is assigned to, or assigns themselves to work on the
issue, setting the status to "In progress."
**Note:** You must be a "Developer" of the project before you are
able to toggle the Status field. A user should contact a project
manager to be granted Developer privilege. Project managers can be
found on "Overview" page of the project.
4. After every useful chunk of progress, notes are made on the issue
and the progress percentage is updated to reflect this. Remember
that notes are actually Markdown, so it is advised to use the
'preview' button to ensure your note looks right.
5. The changes are uploaded to Gerrit for review. Once all changes
pertaining to an issue are on Gerrit, an issues status should
change to "Code review."
6. Once all changes are cleared for merging, they either can be
merged, or held for feedback, at which point the issue status
should become "Feedback."
7. After all changes have been merged, the issue should be set to
"Closed."
Redmine provides other facilities for managing your work on NDN
projects, too, such as time logging and time estimation.
## Contributing Guidelines
### Repositories ###
All NDN projects are hosted on GitHub, at various organizations, using git
for version control:
- [Main NDN codebase](https://github.com/named-data)
- [NDN codebase for mobile platforms](https://github.com/named-data-mobile)
- [NDN codebase for IoT](https://github.com/named-data-iot)
- [ndnSIM codebase](https://github.com/named-data-ndnSIM)
- [Other NDN codebase (REMAP)](https://github.com/remap)
If you are unfamiliar with git, some kind
of [tutorial on git](https://git-scm.com/book/en/v1/Getting-Started)
should be your first step.
There is also a [Git game](http://learngitbranching.js.org/index.html)
you can play. Finally, there is a
[wiki page](https://redmine.named-data.net/projects/nfd/wiki#Development-process)
on NFD's Redmine that has more useful links.
There are a lot of different projects, so take some time to look
through them for ones that pertain to your interests. NDN projects
use [Gerrit](https://gerrit.named-data.net/) for code review purposes.
Occasionally there will be other repositories used privately to test
changes, but this is uncommon. In general, you will not need to refer
to these repositories.
### Style ###
Most NDN projects are written in C++, and there is a
[style guide](https://named-data.net/doc/ndn-cxx/current/code-style.html).
In general the NDN style is similar to the GNU style, but there are
some significant changes. This style guide is not exhaustive, and in
all cases not covered by the guide you should emulate the current
style of the project.
There is a
[partial styleguide](https://redmine.named-data.net/projects/nfd/wiki/CodeStyle)
for Python. It applies many of the provisions from the C++ guide, in
addition to some other Python-specific things.
Some NDN projects are written in JavaScript, and there is a [style guide](https://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/) for that language, too.
#### Commit Messages ####
Commit messages are very important, as they are usually the first
thing (besides the changelog file) a developer looks at when trying to
understand the timeline of a project. Commit messages should:
- Have a short, descriptive first line, starting with the module
they change. A good rule of thumb is a maximum length of 65
characters.
- If including a body, leave a blank line between the first line and
the rest, and ensure that each line is no longer than 72 characters.
- Include Redmine issue numbers. The exact syntax is given below.
- Be written in an imperative mood. E.g. `"Make foo a bar"` and not
`"Foo is now a bar"`
- Use the present tense. E.g. `"Make foo a bar"` and not `"Made foo a
bar"`
To explain, the anatomy of a typical commit message is like this:
docs: write contributing guide and code of conduct
This commit adds a guide that may be useful for new-comers to NDN in
becoming productive contributors. This commit also adds a code of
conduct.
refs: #3898
Change-Id: Ife89360305027dba9020f0b298793c1121ae1fd6c
Explaining this:
- `docs` is the module that the commit affects. We want this because
it lets someone know at a glance what part of the project it
changes. For some projects, there will be only one module or only
very small other modules. This practice should be observed in
those cases, too.
- `#3898` is the Redmine issue number. Gerrit transforms these into
clickable links, and it is useful to reviewers to gain background
understanding of the issue. You can have multiple by separating
them with commas.
- `Change-Id` should be filled automatically. It is used by Gerrit
to track changes.
### Unit Tests ###
With a few exceptions, every patch needs to have unit tests that
accompany them. For C++, we use
the [Boost unit test framework](http://www.boost.org/libs/test) to
help us out. Note that this link points to the newest version of the
Boost Test library documentation, and you may need to refer to older
documentation if you are using an older version of Boost. More
information on this is available in
the
[NFD Dev Guide](https://named-data.net/publications/techreports/ndn-0021-7-nfd-developer-guide/)
When designing and writing tests, a few things need to be kept in mind:
1. Unit tests are **design** tools, *not* debug tools. Just because
your code passes some unit tests does not mean it is
bug-free. Unit tests are tools to convince you that your code does
what you think it does.
2. It can be difficult to know when you should test something. If
you find that you are having a hard time designing a test for
something, ask yourself whether it is because it doesn't make
sense to test what you've just written, or if it's because the way
you designed it makes it difficult to test. Consider a second look
at your design if you think it's the second one.
3. The method that gave the world unit tests says that unit tests
should be written *before* the code they test. This is
a contentious issue, so writing them either before or after is
acceptable. If writing them later, keep the tests in mind when
writing the code, and it will help design good interfaces.
4. At the very least, write the test for a completed module/unit of
code before moving on. Doing this will ensure that the test gets
written, and will help you think about the interface that you need
to examine. If you don't, you may forget exactly what each piece
is responsible for when you're looking at the whole system
afterward.
5. Separate your I/O, as it is very hard to test, so I/O should be
isolated if possible. Consider something like separating a
function that invokes I/O into two functions: one that does the
I/O and calls the other one, which takes that I/O result. This
will make it easier to test that second function than if they were
combined.
Writing unit tests using the Boost framework is quite simple, and you
can refer to existing unit tests for examples.
([This is a good example.](https://github.com/named-data/NFD/blob/master/tests/rib/rib.t.cpp))
#### Building and running unit tests ####
This is mentioned in greater depth in
the [developer's readme](README-dev.md), but the basic procedure is:
1. In the base directory of the project, run `./waf distclean`. This
removes all prior build files.
2. Run `./waf configure --with-tests`. This configures the next build
to also build the tests.
3. Run `./waf`. This will build the tests.
4. Then, the unit tests will be in the `build` directory, and will be
named `unit-tests-<module name`, e.g. `unit-tests-nlsr` or
`unit-tests-rib`. To run just one test suite, run
`./unit-tests-exampleModule -t ExampleTestSuite`. To run a
specific test in a suite, use `./unit-tests-exampleModule -t
ExampleTestSuite/ExampleTestCase`.
## Gerrit: Uploading Patches and Code Review ##
As mentioned above, NDN projects
use [Gerrit](https://gerrit.named-data.net/) for code review. This is
a web-hosted, open code review platform that allows for interactive
code review, rebasing, and cross-linking with the Redmine, and a
developer interacts with it using the familiar git. For issues that
require a tracker reference, a particularly useful feature is that
the `refs: #...` becomes a clickable link to the issue for design
discussion.
### First-time Setup ###
The first-time Gerrit setup goes like this:
1. Log in to Gerrit. You can authenticate using many different
methods, including GitHub OAuth. You need to ensure that you have a Gerrit username:
1. Log in.
2. Click on your name in the top right corner and click "Settings" in the pop-up box.
3. In the `Username` box, check for a name. If there's already one there, great.
4. If not, type one in, and this will be used in later steps.
2. Set up your Gerrit credentials. This will depend on how you
configured your Gerrit remote in step 1. Among other things, you
need to set up identities so that the email on your Gerrit profile
matches whatever email you will be committing with on your git
repo.
**Note:** We only support using
[SSH access to Gerrit](https://gerrit.named-data.net/Documentation/user-upload.html#ssh).
This shows what the identities panel looks like. If you do
not see the email here that you have configured git to use, you
cannot upload to Gerrit.
![Web page showing what the "identities" panel looks like](./docs/images/gerrit-credentials-blurred.png)
In that case, add it under contact information panel.
![Web page showing what the "contact information" panel looks like](./docs/images/gerrit-email.png).
Gerrit itself has
[extensive documentation](https://gerrit.named-data.net/Documentation/error-messages.html)
regarding error messages, and this identity-based one is by far the most
common. This is the
[documentation for an identity error.](https://gerrit.named-data.net/Documentation/error-invalid-author.html)
3. Clone the source for a project from Gerrit.
1. While logged in to Gerrit, there will be a link in the top-left
area, `Projects`.
2. From this project view, click on the `Clone with commit-msg
hook` tab.
3. Click on the `ssh` tab to select cloning over SSH. **Note:**
This will require setting up SSH access to Gerrit first.
4. Copy-and-paste the `git clone ...` command into your terminal
to fetch the project source.
After this, your remotes will be set up correctly, and pushing to
Gerrit will only require `git push origin HEAD:refs/for/master` after
committing work. This section has some
[git tips and tricks to type less][type-less].
### Uploading patches ###
Most patches should have a corresponding Redmine issue that they can
reference. If you search the Redmine and notice there is no relevant
issue for a patch you are writing, please create an issue first. You
will need a Redmine account, which can be created there.
After writing some changes, commit them locally as normal. After
saving and exiting your editor, the commit hook will insert a unique
`Change-Id` to the message.
Once you have a commit message you are happy with, simply run `git
push HEAD:refs/for/master`.
**Note:** Gerrit separates commits into patch sets by the unique
`Change-Id`s. As a result, you must either:
* Squash your various commits into one with `git rebase -i
<initial commit>`, ensuring that the ultimate `Change-Id` in the
commit is the one on the patch set on Gerrit. This workflow is
generally preferred.
* Amend your commit with any new changes using `git commit --amend`.
If you do not do this, what will happen is that each commit will be
interpreted by Gerrit as a separate patch set. This is probably not
what you want.
### Code Review ###
#### Dealing with Code Review ####
It is important to remember that code review is about improving
the quality of code contributed, and nothing else. Further, code
review is highly important, as every line of code that's
committed comes with a burden of maintenance. Code review helps
minimize the burden of that maintenance. Consider that when you
are receiving comments, those comments are influenced by two
things:
- How the reviewer personally feels about the change ("Would I
be happy to see this code in a year?" or "Would I be happy if
I wrote this?") and
- How the reviewer feels the change abides by style and usage
requirements ("I may not personally mind, but we have to do it
this way.")
Remembering these things when reading comments helps to separate
what can feel like needless negativity.
#### Doing Code Review and Writing Comments ####
**Code review is *extremely* important!** We need every bit of code
review you can give. In many cases this is the bottleneck for
new contributors who do not fully understand how certain
language constructs should be used, what best practices are,
etc. In these cases it is important to give constructive
feedback.
Writing comments is somewhat counter-intuitive on Gerrit. If you are
signed in through a modern browser, you can leave a comment in a file
either by clicking on the line number, by selecting some text you want
to comment and pressing 'c', or by clicking on someone else's
comment. After typing, click the `Save` button there. After navigating
through the patch set with the arrows at the top-right of the Gerrit
UI, you then must click the up-arrow to get back to the Change
screen. **At this point your comments have *not* been made yet!** You
must then click the `Reply...` button, and assign a score. If you
correctly saved your comments, they will be shown at the bottom of
that box. Once you click post, the comments will be made public to
others.
Minimally, a review *must* include:
- A score (usually -1, 0, or +1)
- An "itemized" commentary on each objection you have, or a
justification for a whole-change objection.
Optimally, a review should include:
- A useful explanation of *why* you object to some item. This is
more important than it first appears. Consider that although
you may have been writing code since before you could count,
not everyone has. Some things may not be obvious to others,
and sharing your knowledge is key to making an open-source
project work.
- Comments about good design decisions. These help motivate
developers when otherwise a review is entirely negative
comments.
#### Expediting the Code Review Process ####
If you observe that code review takes a long time, there are a
few things that you can do to to expedite the process:
1. **Think about language best practices.**
2. **Ask yourself how you would feel about this code, if you saw it "in the wild."**
3. **When making code decisions, ask yourself "why *shouldn't* I do it this way?"**
#### Responding to Code Review ####
There are a few things to remember when responding to code review, including:
- **Don't** click "Done" on a comment if you agree with a comment and
are updating the code accordingly. These comments are essentially
useless and only clutter the discussion. Gerrit has a convenient
mechanism to check the differences between two patch sets, so
reviewers are expected to check that their comments have been
addressed.
- **Don't** blindly follow what is suggested. Review is just that: a
review. Sometimes what is suggested is functionally equivalent to
what you have implemented. Other times, the reviewer has not
considered something when writing their review, and their
suggestion will not work. Lastly, if you disagree with a suggestion
for some other reason, feel free to object, but you may be asked to
provide an explanation.
- **How** to reply. To reply to a comment, click on the comment in
the Gerrit interface, type your reply, and then press save. After
replying, you **must remember** to go to the main patch set change
screen, and press `Reply...`. Your comments will be shown as
drafts, and you must click `Post` to make them visible to others.
### Jenkins ###
As a supplement to the code review process, every patch set is automatically
compiled and tested on multiple platforms
using [our instance of Jenkins](http://jenkins.named-data.net/), the
continuous integration system. Interacting with Jenkins is not usually
necessary, as Jenkins automatically picks up new patch sets and posts
the results. Typically the only interaction needed with Jenkins is
when some kind of glitch occurs and a build needs to be retriggered.
It is expected that code is checked locally. Reviewers may wait until
Jenkins checks the code before doing a more functional review of the
code. Since Jenkins checks can take a while, you can save some time by
checking yourself first.
### Gerrit Change-Id Commit Hook ###
If you encounter an error like this when trying to push work:
remote: ERROR: [4311462] missing Change-Id in commit message footer
remote:
remote: Hint: To automatically insert Change-Id, install the hook:
remote: gitdir=$(git rev-parse --git-dir); scp -p -P 29418 someuser@gerrit.named-data.net:hooks/commit-msg ${gitdir}/hooks/
remote: And then amend the commit:
remote: git commit --amend
Then your commit hook has not been set up correctly, somehow. Follow
the instructions in the terminal to resolve this.
### Code Style Robot ###
As part of CI, there is a script that checks every patch uploaded to
Gerrit for code style consistency. Checking these kinds of things is
notoriously difficult, and while the robot is very good in general, it
will occasionally report false positives and miss things. So all
issues it raises should be inspected manually to ensure they really
are style problems. Further, since this automated check is not
perfect, you should take steps (e.g., configure your editor or run a
linter before you commit) to ensure you adhere to code style rules.
### <a name="type-less"></a> Typing Less to Upload Patches to Gerrit ###
If typing `HEAD:refs/for/master` feels
repetitive, you have a few options:
* You can configure git to do the work for you, as described
in [this blog post](https://yoursunny.com/t/2017/NFD-devbox/#Uploading-to-Gerrit)
* Git has an alias system that you can use to specify certain
commands. For example, you can use `git config --global alias.pg
"push origin HEAD:refs/for/master"` to make `git pg` push to
Gerrit. [Learn about git aliases here.](https://githowto.com/aliases)
* If using Linux or macOS, it is relatively simple to create a shell
alias: `alias gs="git status"` for example, or `alias gitpush="git
push origin HEAD:refs/for/master`. The alias itself must be one
word, but it can represent multiple words. To persist your
aliases, they need to go in your environment file, which is
generally at `~/.bashrc` or `~/.zshrc` or `~/.profile`. The exact
syntax of aliases and the environment variables file will vary by
shell. You should be careful not to overuse aliases, however.
[type-less]: #type-less
+4 -5
View File
@@ -9,10 +9,10 @@ NFD relies on third-party software, licensed under the following licenses:
- The Boost libraries are licensed under the
[Boost Software License 1.0](https://www.boost.org/users/license.html)
- CityHash is licensed under a
- CityHash is licensed under the
[MIT license](https://github.com/google/cityhash/blob/master/COPYING)
- Libpcap is licensed under a
- Libpcap is licensed under the
[3-clause BSD license](https://github.com/the-tcpdump-group/libpcap/blob/master/LICENSE)
- The WebSocket++ library is licensed under the terms of the
@@ -21,11 +21,10 @@ NFD relies on third-party software, licensed under the following licenses:
- The waf build system is licensed under the terms of the
[BSD license](https://github.com/named-data/NFD/blob/master/waf)
The GPL license is provided below in this file. For more information about
these licenses, see https://www.gnu.org/licenses/
these licenses, see <https://www.gnu.org/licenses/>
----------------------------------------------------------------------------------
--------------------------------------------------------------------------------
### GNU GENERAL PUBLIC LICENSE
+45
View File
@@ -0,0 +1,45 @@
FROM ghcr.io/named-data/ndn-cxx:latest as builder
RUN apt-get update \
&& apt-get install -y --no-install-recommends libpcap-dev \
&& rm -rf /var/lib/apt/lists/*
COPY . /NFD
RUN cd /NFD \
&& ./waf configure --without-pch --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
&& ./waf \
&& ./waf install \
# get list of dependencies
&& mkdir -p /shlibdeps/debian && cd /shlibdeps && touch debian/control \
&& dpkg-shlibdeps --ignore-missing-info /usr/lib/libndn-cxx.so* /usr/bin/nfdc /usr/bin/nfd \
&& sed -n '/^shlibs:Depends=/ s|shlibs:Depends=||p' debian/substvars | sed -e 's|,||g' -e 's| ([^)]*)||g' > /deps.txt
# use same base distro version as named-data/ndn-cxx
FROM debian:bookworm
COPY --from=builder /deps.txt /
RUN apt-get update \
&& apt-get install -y --no-install-recommends $(cat /deps.txt) \
&& rm -rf /var/lib/apt/lists/* /deps.txt
COPY --from=builder /usr/lib/libndn-cxx.so* /usr/lib/
COPY --from=builder /usr/bin/nfd /usr/bin/
COPY --from=builder /usr/bin/nfdc /usr/bin/
COPY --from=builder /usr/bin/nfd-status-http-server /usr/bin/
COPY --from=builder /usr/share/ndn/ /usr/share/ndn/
COPY --from=builder /etc/ndn/nfd.conf.sample /config/nfd.conf
ENV HOME=/config
VOLUME /config
VOLUME /run/nfd
EXPOSE 6363/tcp
EXPOSE 6363/udp
EXPOSE 9696/tcp
ENTRYPOINT ["/usr/bin/nfd"]
CMD ["--config", "/config/nfd.conf"]
+7 -9
View File
@@ -1,7 +1,7 @@
# Notes for NFD developers
If you are new to the NDN software community, please read the
[Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md).
If you are new to the NDN software community, please read our
[Contributor's Guide](https://github.com/named-data/.github/blob/main/CONTRIBUTING.md).
## Code style
@@ -9,11 +9,9 @@ NFD code is subject to [NFD code style](https://redmine.named-data.net/projects/
## Licensing
Contributions to NFD must be licensed under the 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:
Contributions to NFD must be licensed under the GPL v3 or a compatible license.
If you choose the GPL v3, please use the following license boilerplate in all `.hpp`
and `.cpp` files:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
@@ -61,7 +59,7 @@ The simplest way to run the tests is to launch the compiled binary without any p
# Run NFD RIB management tests
./build/unit-tests-rib
The [Boost.Test framework](https://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/index.html)
The [Boost.Test framework](https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/index.html)
is very flexible and allows a number of run-time customization of what tests should be run.
For example, it is possible to choose to run only a specific test suite, only a specific
test case within a suite, or specific test cases within specific test suites:
@@ -94,4 +92,4 @@ or `-p` to show a progress bar:
There are many more command line options available, information about which can be obtained
either from the command line using the `--help` switch, or online on the
[Boost.Test website](https://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/index.html).
[Boost.Test website](https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/boost_test/runtime_config.html).
+23 -17
View File
@@ -1,13 +1,20 @@
# NFD - Named Data Networking Forwarding Daemon
<div align="center">
![Language](https://img.shields.io/badge/C%2B%2B-14-blue.svg)
[![Build Status](https://travis-ci.org/named-data/NFD.svg?branch=master)](https://travis-ci.org/named-data/NFD)
![Latest Version](https://img.shields.io/github/tag/named-data/NFD.svg?color=darkkhaki&label=latest%20version)
[<img alt height="65" src="docs/named_data_theme/static/ndn-logo.svg"/>](https://named-data.net/)
# NFD: Named Data Networking Forwarding Daemon
</div>
[![CI](https://github.com/named-data/NFD/actions/workflows/ci.yml/badge.svg)](https://github.com/named-data/NFD/actions/workflows/ci.yml)
[![Docs](https://github.com/named-data/NFD/actions/workflows/docs.yml/badge.svg)](https://github.com/named-data/NFD/actions/workflows/docs.yml)
![Language](https://img.shields.io/badge/C%2B%2B-17-blue)
![Latest version](https://img.shields.io/github/v/tag/named-data/NFD?label=Latest%20version)
## Overview
NFD is a network forwarder that implements and evolves together with the Named Data
Networking (NDN) [protocol](https://named-data.net/doc/NDN-packet-spec/current/).
NFD is a network forwarder that implements and evolves together with the Named
Data Networking (NDN) [protocol](https://docs.named-data.net/NDN-packet-spec/).
Since the initial public release in 2014, NFD has been a core component of the
[NDN Platform](https://named-data.net/codebase/platform/).
@@ -27,13 +34,12 @@ various features, some of which may eventually work into the protocol spec.
See [`docs/INSTALL.rst`](docs/INSTALL.rst) for compilation and installation instructions.
Extensive documentation is available on NFD's [homepage](https://named-data.net/doc/NFD/).
Extensive documentation is available on NFD's [homepage](https://docs.named-data.net/NFD/).
## Reporting bugs
Bug reports and feedback are highly appreciated and can be submitted through the
[NFD issue tracker](https://redmine.named-data.net/projects/nfd/issues) or the
[ndn-interest mailing list](http://www.lists.cs.ucla.edu/mailman/listinfo/ndn-interest).
Please submit any bug reports or feature requests to the
[NFD issue tracker](https://redmine.named-data.net/projects/nfd/issues).
## Contributing
@@ -43,13 +49,13 @@ it already contains significant contributions from people outside the project te
[`AUTHORS.md`](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.
If you are new to the NDN software community, please read [`README-dev.md`](README-dev.md)
and the [Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md)
to get started.
Contributions to NFD are greatly appreciated and can be made through our
[Gerrit code review site](https://gerrit.named-data.net/).
If you are new to the NDN software community, please read our
[Contributor's Guide](https://github.com/named-data/.github/blob/main/CONTRIBUTING.md)
and [`README-dev.md`](README-dev.md) to get started.
## License
NFD is a free and open-source software package licensed under the GPL version 3 and
is the centerpiece of our committement to making NDN's core technology free and open
to all Internet users and developers. For more information about licensing, refer to
[`COPYING.md`](COPYING.md).
NFD is free software distributed under the GNU General Public License version 3.
See [`COPYING.md`](COPYING.md) for details.
-1
View File
@@ -1 +0,0 @@
docs/release-notes-latest.rst
-58
View File
@@ -1,58 +0,0 @@
/* -*- 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
+24 -32
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,20 +28,20 @@
#include "core/config.hpp"
#ifdef WITH_TESTS
#define VIRTUAL_WITH_TESTS virtual
#define PUBLIC_WITH_TESTS_ELSE_PROTECTED public
#define PUBLIC_WITH_TESTS_ELSE_PRIVATE public
#define PROTECTED_WITH_TESTS_ELSE_PRIVATE protected
#define OVERRIDE_WITH_TESTS_ELSE_FINAL override
#define FINAL_UNLESS_WITH_TESTS
#ifdef NFD_WITH_TESTS
#define NFD_VIRTUAL_WITH_TESTS virtual
#define NFD_PUBLIC_WITH_TESTS_ELSE_PROTECTED public
#define NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE public
#define NFD_PROTECTED_WITH_TESTS_ELSE_PRIVATE protected
#define NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL override
#define NFD_FINAL_UNLESS_WITH_TESTS
#else
#define VIRTUAL_WITH_TESTS
#define PUBLIC_WITH_TESTS_ELSE_PROTECTED protected
#define PUBLIC_WITH_TESTS_ELSE_PRIVATE private
#define PROTECTED_WITH_TESTS_ELSE_PRIVATE private
#define OVERRIDE_WITH_TESTS_ELSE_FINAL final
#define FINAL_UNLESS_WITH_TESTS final
#define NFD_VIRTUAL_WITH_TESTS
#define NFD_PUBLIC_WITH_TESTS_ELSE_PROTECTED protected
#define NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE private
#define NFD_PROTECTED_WITH_TESTS_ELSE_PRIVATE private
#define NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL final
#define NFD_FINAL_UNLESS_WITH_TESTS final
#endif
#include <cstddef>
@@ -50,17 +50,15 @@
#include <limits>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <string_view>
#include <utility>
#include <vector>
#include <ndn-cxx/data.hpp>
#include <ndn-cxx/delegation.hpp>
#include <ndn-cxx/delegation-list.hpp>
#include <ndn-cxx/interest.hpp>
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/encoding/block.hpp>
@@ -70,20 +68,16 @@
#include <ndn-cxx/util/exception.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <ndn-cxx/util/signal.hpp>
#include <ndn-cxx/util/span.hpp>
#include <ndn-cxx/util/time.hpp>
#include <boost/asio.hpp>
#include <boost/assert.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/property_tree/ptree.hpp>
namespace nfd {
using std::size_t;
using boost::noncopyable;
using std::shared_ptr;
using std::unique_ptr;
using std::weak_ptr;
@@ -94,18 +88,15 @@ using std::static_pointer_cast;
using std::dynamic_pointer_cast;
using std::const_pointer_cast;
using std::bind;
using std::to_string;
using namespace std::string_literals;
using namespace std::string_view_literals;
using ndn::optional;
using ndn::nullopt;
using ndn::to_string;
using boost::noncopyable;
using ndn::span;
using ndn::Block;
using ndn::Data;
using ndn::Delegation;
using ndn::DelegationList;
using ndn::FaceUri;
using ndn::Interest;
using ndn::Name;
@@ -121,10 +112,11 @@ using namespace ndn::tlv;
namespace lp = ndn::lp;
namespace name = ndn::name;
namespace scheduler = ndn::scheduler;
namespace signal = ndn::util::signal;
namespace signal = ndn::signal;
namespace time = ndn::time;
using namespace ndn::block_literals;
using namespace ndn::time_literals;
using ndn::operator""_block;
} // namespace nfd
+13 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2018, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -25,9 +25,13 @@
#include "network.hpp"
#include <boost/lexical_cast.hpp>
#include <boost/utility/value_init.hpp>
#include <algorithm>
#include <cctype>
#include <istream>
#include <ostream>
namespace nfd {
@@ -44,7 +48,7 @@ const Network&
Network::getMaxRangeV4()
{
using boost::asio::ip::address_v4;
static Network range{address_v4{}, address_v4{0xffffffff}};
static const Network range{address_v4{}, address_v4{0xffffffff}};
return range;
}
@@ -52,14 +56,14 @@ 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{address_v6{}, address_v6{maxV6}};
static const address_v6::bytes_type maxV6 = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
static const Network range{address_v6{}, address_v6{maxV6}};
return range;
}
bool
Network::isValidCidr(const std::string& cidr)
Network::isValidCidr(std::string_view cidr) noexcept
{
auto pos = cidr.find('/');
if (pos == std::string::npos) {
@@ -92,8 +96,8 @@ operator>>(std::istream& is, Network& network)
size_t position = networkStr.find('/');
if (position == std::string::npos) {
try {
network.m_minAddress = ip::address::from_string(networkStr);
network.m_maxAddress = ip::address::from_string(networkStr);
network.m_minAddress = ip::make_address(networkStr);
network.m_maxAddress = ip::make_address(networkStr);
}
catch (const boost::system::system_error&) {
is.setstate(std::ios::failbit);
@@ -102,7 +106,7 @@ operator>>(std::istream& is, Network& network)
}
else {
boost::system::error_code ec;
auto address = ip::address::from_string(networkStr.substr(0, position), ec);
auto address = ip::make_address(networkStr.substr(0, position), ec);
if (ec) {
is.setstate(std::ios::failbit);
return is;
+18 -19
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2016, Regents of the University of California,
/*
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,11 +26,14 @@
#ifndef NFD_CORE_NETWORK_HPP
#define NFD_CORE_NETWORK_HPP
#include "common.hpp"
#include <boost/asio/ip/address.hpp>
#include <boost/operators.hpp>
#include <string_view>
namespace nfd {
class Network
class Network : private boost::equality_comparable<Network>
{
public:
Network();
@@ -39,7 +42,7 @@ public:
const boost::asio::ip::address& maxAddress);
bool
doesContain(const boost::asio::ip::address& address) const
doesContain(const boost::asio::ip::address& address) const noexcept
{
return m_minAddress <= address && address <= m_maxAddress;
}
@@ -51,29 +54,25 @@ public:
getMaxRangeV6();
static bool
isValidCidr(const std::string& cidr);
isValidCidr(std::string_view cidr) noexcept;
bool
operator==(const Network& rhs) const
private: // non-member operators
friend bool
operator==(const Network& lhs, const Network& rhs) noexcept
{
return m_minAddress == rhs.m_minAddress && m_maxAddress == rhs.m_maxAddress;
return lhs.m_minAddress == rhs.m_minAddress &&
lhs.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::ostream&
operator<<(std::ostream& os, const Network& network);
friend std::istream&
operator>>(std::istream& is, Network& network);
private:
boost::asio::ip::address m_minAddress;
boost::asio::ip::address m_maxAddress;
};
std::ostream&
+16 -12
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,14 +26,16 @@
#ifndef NFD_CORE_VERSION_HPP
#define NFD_CORE_VERSION_HPP
// NFD version follows Semantic Versioning 2.0.0
// https://semver.org/spec/v2.0.0.html
// The NFD version follows the approach of Calendar Versioning (https://calver.org/)
// based on the year and month of the release, followed by an optional "patch" number,
// i.e., `YY.0M[.MICRO]` using CalVer notation.
//
// To change version number, modify VERSION variable in top-level wscript.
// To change version number, modify the VERSION variable in the top-level wscript.
/** \brief NFD version represented as an integer.
/**
* \brief NFD version represented as an integer.
*
* Equivalent to: `#NFD_VERSION_MAJOR*1000000 + #NFD_VERSION_MINOR*1000 + #NFD_VERSION_PATCH`
* Equivalent to: #NFD_VERSION_MAJOR*1000000 + #NFD_VERSION_MINOR*1000 + #NFD_VERSION_PATCH
*/
#define NFD_VERSION @VERSION@
@@ -44,7 +46,8 @@
/// The patch version of NFD
#define NFD_VERSION_PATCH @VERSION_PATCH@
/** \brief NFD version represented as a string.
/**
* \brief NFD version represented as a string.
*
* Format:
* @code
@@ -53,20 +56,21 @@
*/
extern const char NFD_VERSION_STRING[];
/** \brief NFD version string, including git commit information, if NFD is build from
* specific git commit.
/**
* \brief NFD version string, including git commit information if NFD is build from a
* specific git commit.
*
* #NFD_VERSION_BUILD_STRING is obtained using the following command (`NFD-` prefix is
* afterwards removed): `git describe --match 'NFD-*'`
* afterwards removed): ``git describe --match 'NFD-*'``
*
* When NFD is not built from git, #NFD_VERSION_BUILD_STRING equals #NFD_VERSION_STRING.
*
* Format:
* @code
* MAJOR.MINOR.PATCH(-release-candidate-tag)(-(number-of-commits-since-tag)-COMMIT-HASH)
* MAJOR.MINOR(.PATCH)(-release-candidate-tag)(-(number-of-commits-since-tag)-COMMIT-HASH)
* @endcode
*
* Example: 0.1.0-rc1-1-g5c86570
* Example: 2022.02-1-g5c86570
*/
extern const char NFD_VERSION_BUILD_STRING[];
+4 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -32,8 +32,8 @@
namespace nfd {
ConfigFile::ConfigFile(UnknownConfigSectionHandler unknownSectionCallback)
: m_unknownSectionCallback(unknownSectionCallback)
ConfigFile::ConfigFile(UnknownConfigSectionHandler callback)
: m_unknownSectionCallback(std::move(callback))
{
}
@@ -77,7 +77,7 @@ void
ConfigFile::addSectionHandler(const std::string& sectionName,
ConfigSectionHandler subscriber)
{
m_subscriptions[sectionName] = subscriber;
m_subscriptions[sectionName] = std::move(subscriber);
}
void
+35 -13
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -32,27 +32,32 @@
namespace nfd {
/** \brief a config file section
/**
* \brief A configuration file section.
*/
using ConfigSection = boost::property_tree::ptree;
/** \brief an optional config file section
/**
* \brief An optional configuration file section.
*/
using OptionalConfigSection = boost::optional<const ConfigSection&>;
/** \brief callback to process a config file section
/**
* \brief Callback to process a configuration file section.
*/
using ConfigSectionHandler = std::function<void(const ConfigSection& section, bool isDryRun,
const std::string& filename)>;
/** \brief callback to process a config file section without a \p ConfigSectionHandler
/**
* \brief Callback to process a configuration file section without a #ConfigSectionHandler.
*/
using UnknownConfigSectionHandler = std::function<void(const std::string& filename,
const std::string& sectionName,
const ConfigSection& section,
bool isDryRun)>;
/** \brief configuration file parsing utility
/**
* \brief Configuration file parsing utility.
*/
class ConfigFile : noncopyable
{
@@ -80,7 +85,7 @@ public: // unknown section handlers
bool isDryRun);
public: // parse helpers
/** \brief parse a config option that can be either "yes" or "no"
/** \brief Parse a config option that can be either "yes" or "no".
* \retval true "yes"
* \retval false "no"
* \throw Error the value is neither "yes" nor "no"
@@ -95,7 +100,7 @@ public: // parse helpers
}
/**
* \brief parse a numeric (integral or floating point) config option
* \brief Parse a numeric (integral or floating point) config option.
* \tparam T an arithmetic type
*
* \return the numeric value of the parsed option
@@ -105,27 +110,44 @@ public: // parse helpers
static T
parseNumber(const ConfigSection& node, const std::string& key, const std::string& sectionName)
{
static_assert(std::is_arithmetic<T>::value, "T must be an arithmetic type");
static_assert(std::is_arithmetic_v<T>);
boost::optional<T> value = node.get_value_optional<T>();
auto value = node.get_value_optional<T>();
// Unsigned logic is workaround for https://redmine.named-data.net/issues/4489
if (value &&
(std::is_signed<T>() || node.get_value<std::string>().find("-") == std::string::npos)) {
(std::is_signed_v<T> || node.get_value<std::string>().find("-") == std::string::npos)) {
return *value;
}
NDN_THROW(Error("Invalid value '" + node.get_value<std::string>() +
"' for option '" + key + "' in section '" + sectionName + "'"));
}
template <typename T>
template<typename T>
static T
parseNumber(const ConfigSection::value_type& option, const std::string& sectionName)
{
return parseNumber<T>(option.second, option.first, sectionName);
}
/**
* \brief Check that a value is within the inclusive range [min, max].
* \throw Error the value is out of the acceptable range
*/
template<typename T>
static void
checkRange(T value, T min, T max, const std::string& key, const std::string& sectionName)
{
static_assert(std::is_integral_v<T>);
if (value < min || value > max) {
NDN_THROW(Error("Invalid value '" + to_string(value) + "' for option '" + key +
"' in section '" + sectionName + "': out of acceptable range [" +
to_string(min) + ", " + to_string(max) + "]"));
}
}
public: // setup and parsing
/// \brief setup notification of configuration file sections
/// \brief Setup notification of configuration file sections.
void
addSectionHandler(const std::string& sectionName,
ConfigSectionHandler subscriber);
+29 -21
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -30,24 +30,27 @@
namespace nfd {
/** \brief represents a counter that encloses an integer value
/**
* \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
* 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 : noncopyable
{
public:
typedef uint64_t rep;
using rep = uint64_t;
/** \brief observe the counter
/**
* \brief Return the counter's value.
*/
operator rep() const noexcept
{
return m_value;
}
/** \brief replace the counter value
/**
* \brief Replace the counter's value.
*/
void
set(rep value) noexcept
@@ -59,14 +62,16 @@ protected:
rep m_value = 0;
};
/** \brief represents a counter of number of packets
/**
* \brief Represents a counter of number of packets.
*
* \warning The counter value may wrap after exceeding the range of underlying integer type.
* \warning The counter value may wrap after exceeding the range of the underlying integer type.
*/
class PacketCounter : public SimpleCounter
{
public:
/** \brief increment the counter by one
/**
* \brief Increment the counter by one.
*/
PacketCounter&
operator++() noexcept
@@ -74,17 +79,18 @@ public:
++m_value;
return *this;
}
// postfix ++ operator is not provided because it's not needed
};
/** \brief represents a counter of number of bytes
/**
* \brief Represents a counter of number of bytes.
*
* \warning The counter value may wrap after exceeding the range of underlying integer type.
* \warning The counter value may wrap after exceeding the range of the underlying integer type.
*/
class ByteCounter : public SimpleCounter
{
public:
/** \brief increase the counter
/**
* \brief Increase the counter.
*/
ByteCounter&
operator+=(rep n) noexcept
@@ -94,16 +100,17 @@ public:
}
};
/** \brief provides a counter that observes the size of a table
* \tparam T a type that provides a size() const member function
/**
* \brief Provides a counter that observes the size of a table.
* \tparam T a type that provides a `size()` const member function
*
* if table not specified in constructor, it can be added later by invoking observe()
* If the table is not specified in the constructor, it can be added later by calling observe().
*/
template<typename T>
class SizeCounter : noncopyable
{
public:
typedef size_t Rep;
using rep = size_t;
explicit constexpr
SizeCounter(const T* table = nullptr) noexcept
@@ -117,16 +124,17 @@ public:
m_table = table;
}
/** \brief observe the counter
/**
* \brief Return the counter's value, i.e., the current size of the table being observed.
*/
operator Rep() const
operator rep() const
{
BOOST_ASSERT(m_table != nullptr);
return m_table->size();
}
private:
const T* m_table;
const T* m_table = nullptr;
};
} // namespace nfd
+20 -32
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,18 +27,18 @@
namespace nfd {
static thread_local unique_ptr<boost::asio::io_service> g_ioService;
static thread_local unique_ptr<boost::asio::io_context> g_ioCtx;
static thread_local unique_ptr<Scheduler> g_scheduler;
static boost::asio::io_service* g_mainIoService = nullptr;
static boost::asio::io_service* g_ribIoService = nullptr;
static boost::asio::io_context* g_mainIoCtx = nullptr;
static boost::asio::io_context* g_ribIoCtx = nullptr;
boost::asio::io_service&
boost::asio::io_context&
getGlobalIoService()
{
if (g_ioService == nullptr) {
g_ioService = make_unique<boost::asio::io_service>();
if (g_ioCtx == nullptr) {
g_ioCtx = make_unique<boost::asio::io_context>();
}
return *g_ioService;
return *g_ioCtx;
}
Scheduler&
@@ -50,51 +50,39 @@ getScheduler()
return *g_scheduler;
}
#ifdef WITH_TESTS
#ifdef NFD_WITH_TESTS
void
resetGlobalIoService()
{
g_scheduler.reset();
g_ioService.reset();
g_ioCtx.reset();
}
#endif
boost::asio::io_service&
boost::asio::io_context&
getMainIoService()
{
BOOST_ASSERT(g_mainIoService != nullptr);
return *g_mainIoService;
BOOST_ASSERT(g_mainIoCtx != nullptr);
return *g_mainIoCtx;
}
boost::asio::io_service&
boost::asio::io_context&
getRibIoService()
{
BOOST_ASSERT(g_ribIoService != nullptr);
return *g_ribIoService;
BOOST_ASSERT(g_ribIoCtx != nullptr);
return *g_ribIoCtx;
}
void
setMainIoService(boost::asio::io_service* mainIo)
setMainIoService(boost::asio::io_context* mainIo)
{
g_mainIoService = mainIo;
g_mainIoCtx = mainIo;
}
void
setRibIoService(boost::asio::io_service* ribIo)
setRibIoService(boost::asio::io_context* ribIo)
{
g_ribIoService = ribIo;
}
void
runOnMainIoService(const std::function<void()>& f)
{
getMainIoService().post(f);
}
void
runOnRibIoService(const std::function<void()>& f)
{
getRibIoService().post(f);
g_ribIoCtx = ribIo;
}
} // namespace nfd
+16 -21
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019 Regents of the University of California,
* Copyright (c) 2014-2023 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,44 +27,39 @@
#include "core/common.hpp"
#include <boost/asio/io_context.hpp>
namespace nfd {
/** \brief Returns the global io_service instance for the calling thread.
/**
* \brief Returns the global io_context instance for the calling thread.
*/
boost::asio::io_service&
boost::asio::io_context&
getGlobalIoService();
/** \brief Returns the global Scheduler instance for the calling thread.
/**
* \brief Returns the global Scheduler instance for the calling thread.
*/
Scheduler&
getScheduler();
boost::asio::io_service&
boost::asio::io_context&
getMainIoService();
boost::asio::io_service&
boost::asio::io_context&
getRibIoService();
void
setMainIoService(boost::asio::io_service* mainIo);
setMainIoService(boost::asio::io_context* mainIo);
void
setRibIoService(boost::asio::io_service* ribIo);
setRibIoService(boost::asio::io_context* ribIo);
/** \brief Run a function on the main io_service instance.
*/
void
runOnMainIoService(const std::function<void()>& f);
/** \brief Run a function on the RIB io_service instance.
*/
void
runOnRibIoService(const std::function<void()>& f);
#ifdef WITH_TESTS
/** \brief Destroy the global io_service instance.
#ifdef NFD_WITH_TESTS
/**
* \brief Destroy the global io_context instance.
*
* It will be recreated at the next invocation of getGlobalIoService().
* It will be recreated at the next invocation of getGlobalIoService().
*/
void
resetGlobalIoService();
+9 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2021, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -33,18 +33,18 @@ namespace nfd {
NFD_LOG_INIT(PrivilegeHelper);
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
#ifdef NFD_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
#endif // NFD_HAVE_PRIVILEGE_DROP_AND_ELEVATE
void
PrivilegeHelper::initialize(const std::string& userName, const std::string& groupName)
{
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
#ifdef NFD_HAVE_PRIVILEGE_DROP_AND_ELEVATE
static const size_t MAX_GROUP_BUFFER_SIZE = 16384; // 16 KiB
static const size_t MAX_PASSWD_BUFFER_SIZE = 16384;
@@ -111,13 +111,13 @@ PrivilegeHelper::initialize(const std::string& userName, const std::string& grou
if (!userName.empty() || !groupName.empty()) {
throw Error("Dropping and raising privileges is not supported on this platform");
}
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
#endif // NFD_HAVE_PRIVILEGE_DROP_AND_ELEVATE
}
void
PrivilegeHelper::drop()
{
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
#ifdef NFD_HAVE_PRIVILEGE_DROP_AND_ELEVATE
if (::geteuid() == s_normalUid && ::getegid() == s_normalGid)
return;
@@ -132,13 +132,13 @@ PrivilegeHelper::drop()
NFD_LOG_INFO("dropped to effective uid=" << ::geteuid() << " gid=" << ::getegid());
#else
NFD_LOG_WARN("Dropping privileges is not supported on this platform");
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
#endif // NFD_HAVE_PRIVILEGE_DROP_AND_ELEVATE
}
void
PrivilegeHelper::raise()
{
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
#ifdef NFD_HAVE_PRIVILEGE_DROP_AND_ELEVATE
if (::geteuid() == s_privilegedUid && ::getegid() == s_privilegedGid)
return;
@@ -153,7 +153,7 @@ PrivilegeHelper::raise()
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
#endif // NFD_HAVE_PRIVILEGE_DROP_AND_ELEVATE
}
} // namespace nfd
+11 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -35,10 +35,12 @@ namespace nfd {
class PrivilegeHelper
{
public:
/** \brief represents a serious seteuid/gid failure
/**
* \brief Indicates a serious seteuid/setegid failure.
*
* This should only be caught by main as part of a graceful program termination.
* \note This is not an std::exception and NDN_THROW should not be used.
* This should only be caught by main as part of a graceful program termination.
*
* \note This is not an std::exception and NDN_THROW should not be used.
*/
class Error
{
@@ -71,7 +73,7 @@ public:
{
raise();
try {
f();
std::invoke(std::forward<F>(f));
}
catch (...) {
drop();
@@ -80,18 +82,18 @@ public:
drop();
}
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
static void
raise();
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
#ifdef NFD_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
#endif // NFD_HAVE_PRIVILEGE_DROP_AND_ELEVATE
};
} // namespace nfd
+1 -21
View File
@@ -1,7 +1,7 @@
#include "TokenBucket.hpp"
#include "common/global.hpp"
#include "common/logger.hpp"
#include <iostream>
#include <functional>
namespace nfd {
namespace face {
@@ -28,26 +28,6 @@ namespace nfd {
}
getScheduler().schedule(time::milliseconds(4), std::bind(&TokenBucket::generateToken, this));
}
void TokenBucket::generateTokenByCurrentTime(long currentTime) {
if (this->lastGenerateTokenTime == -1) {
this->lastGenerateTokenTime = currentTime;
return;
}
if (currentTime - this->lastGenerateTokenTime < 1) {
return;
}
long currentStep = (currentTime - this->lastGenerateTokenTime) * this->rateLimit / 1000.0;
// std::cout << "currentStep: " << currentStep << "currentTime: " << currentTime << "lastGenerateTokenTime: " << this->lastGenerateTokenTime << std::endl;
// NFD_LOG_DEBUG(this->name << "=> do generateToken => " << this->currentTokenSize);
this->lastGenerateTokenTime = currentTime;
if (this->currentTokenSize + currentStep > this->bucketSize) {
this->currentTokenSize = this->bucketSize;
} else {
this->currentTokenSize += currentStep;
}
}
bool TokenBucket::use(uint64_t tokenNum) {
if(this->currentTokenSize > tokenNum) {
this->currentTokenSize -= tokenNum;
-7
View File
@@ -15,12 +15,6 @@ namespace nfd {
* 周期性增加token
**/
void generateToken();
/**
* 根据当前时间生成token
*/
void generateTokenByCurrentTime(long currentTime);
/**
* 尝试消费n个token
* @param tokenNum
@@ -34,7 +28,6 @@ namespace nfd {
uint64_t bucketSize; // 令牌桶容量
std::string name;
bool isStart; // 标识是否启动
long lastGenerateTokenTime = -1;
};
}
}
+10 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,17 +26,22 @@
#include "channel.hpp"
#include "face.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
Channel::~Channel() = default;
void
Channel::setUri(const FaceUri& uri)
Channel::setUri(const FaceUri& uri) noexcept
{
m_uri = uri;
}
void
Channel::setDefaultMtu(size_t mtu) noexcept
{
m_defaultMtu = mtu;
}
void
connectFaceClosedSignal(Face& face, std::function<void()> f)
{
@@ -47,5 +52,4 @@ connectFaceClosedSignal(Face& face, std::function<void()> f)
});
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+22 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,8 +29,7 @@
#include "channel-log.hpp"
#include "face-common.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief Represents a channel that listens on a local endpoint.
* \sa FaceSystem
@@ -45,27 +44,42 @@ public:
~Channel();
const FaceUri&
getUri() const
getUri() const noexcept
{
return m_uri;
}
/** \brief Returns whether the channel is listening
/**
* \brief Returns the default MTU for all faces created by this channel.
*/
size_t
getDefaultMtu() const noexcept
{
return m_defaultMtu;
}
/**
* \brief Returns whether the channel is listening.
*/
virtual bool
isListening() const = 0;
/** \brief Returns the number of faces in the channel
/**
* \brief Returns the number of faces in the channel.
*/
virtual size_t
size() const = 0;
protected:
void
setUri(const FaceUri& uri);
setUri(const FaceUri& uri) noexcept;
void
setDefaultMtu(size_t mtu) noexcept;
private:
FaceUri m_uri;
size_t m_defaultMtu = ndn::MAX_NDN_PACKET_SIZE;
};
/** \brief Prototype for the callback that is invoked when a face is created
@@ -87,7 +101,6 @@ using FaceCreationFailedCallback = std::function<void(uint32_t status, const std
void
connectFaceClosedSignal(Face& face, std::function<void()> f);
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_CHANNEL_HPP
+28 -33
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -32,25 +32,30 @@
#include <array>
namespace nfd {
namespace face {
#include <boost/asio/defer.hpp>
namespace nfd::face {
struct Unicast {};
struct Multicast {};
/** \brief Implements Transport for datagram-based protocols.
/**
* \brief Implements a Transport for datagram-based protocols.
*
* \tparam Protocol a datagram-based protocol in Boost.Asio
* \tparam Protocol A datagram-based protocol in Boost.Asio
* \tparam Addressing The addressing mode, either Unicast or Multicast
*/
template<class Protocol, class Addressing = Unicast>
template<class Protocol, class Addressing>
class DatagramTransport : public Transport
{
public:
typedef Protocol protocol;
using protocol = Protocol;
using addressing = Addressing;
/** \brief Construct datagram transport.
/**
* \brief Construct datagram transport.
*
* \param socket Protocol-specific socket for the created transport
* \param socket Protocol-specific socket for the created transport
*/
explicit
DatagramTransport(typename protocol::socket&& socket);
@@ -58,11 +63,11 @@ public:
ssize_t
getSendQueueLength() override;
/** \brief Receive datagram, translate buffer into packet, deliver to parent class.
/**
* \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);
receiveDatagram(span<const uint8_t> buffer, const boost::system::error_code& error);
protected:
void
@@ -86,9 +91,6 @@ protected:
void
resetRecentlyReceived();
static EndpointId
makeEndpointId(const typename protocol::endpoint& ep);
protected:
typename protocol::socket m_socket;
typename protocol::endpoint m_sender;
@@ -150,7 +152,7 @@ DatagramTransport<T, U>::doClose()
// Ensure that the Transport stays alive at least until
// all pending handlers are dispatched
getGlobalIoService().post([this] {
boost::asio::defer(getGlobalIoService(), [this] {
this->setState(TransportState::CLOSED);
});
}
@@ -170,37 +172,38 @@ DatagramTransport<T, U>::doSend(const Block& packet)
template<class T, class U>
void
DatagramTransport<T, U>::receiveDatagram(const uint8_t* buffer, size_t nBytesReceived,
DatagramTransport<T, U>::receiveDatagram(span<const uint8_t> buffer,
const boost::system::error_code& error)
{
if (error)
return processErrorCode(error);
NFD_LOG_FACE_TRACE("Received: " << nBytesReceived << " bytes from " << m_sender);
NFD_LOG_FACE_TRACE("Received: " << buffer.size() << " bytes from " << m_sender);
bool isOk = false;
Block element;
std::tie(isOk, element) = Block::fromBuffer(buffer, nBytesReceived);
auto [isOk, element] = Block::fromBuffer(buffer);
if (!isOk) {
NFD_LOG_FACE_WARN("Failed to parse incoming packet from " << m_sender);
// This packet won't extend the face lifetime
return;
}
if (element.size() != nBytesReceived) {
if (element.size() != buffer.size()) {
NFD_LOG_FACE_WARN("Received datagram size and decoded element size don't match");
// This packet won't extend the face lifetime
return;
}
m_hasRecentlyReceived = true;
this->receive(element, makeEndpointId(m_sender));
if constexpr (std::is_same_v<addressing, Multicast>)
this->receive(element, m_sender);
else
this->receive(element);
}
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);
receiveDatagram(ndn::make_span(m_receiveBuffer).first(nBytesReceived), error);
if (m_socket.is_open())
m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
@@ -257,14 +260,6 @@ DatagramTransport<T, U>::resetRecentlyReceived()
m_hasRecentlyReceived = false;
}
template<class T, class U>
EndpointId
DatagramTransport<T, U>::makeEndpointId(const typename protocol::endpoint&)
{
return 0;
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_DATAGRAM_TRANSPORT_HPP
+17 -27
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -33,8 +33,7 @@
#include <boost/range/adaptor/map.hpp>
#include <pcap/pcap.h>
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_INIT(EthernetChannel);
@@ -102,8 +101,9 @@ void
EthernetChannel::asyncRead(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onReceiveFailed)
{
m_socket.async_read_some(boost::asio::null_buffers(),
[=] (const auto& e, auto) { this->handleRead(e, onFaceCreated, onReceiveFailed); });
m_socket.async_wait(boost::asio::posix::stream_descriptor::wait_read, [=] (const auto& e) {
handleRead(e, onFaceCreated, onReceiveFailed);
});
}
void
@@ -120,26 +120,20 @@ EthernetChannel::handleRead(const boost::system::error_code& error,
return;
}
const uint8_t* pkt;
size_t len;
std::string err;
std::tie(pkt, len, err) = m_pcap.readNextPacket();
if (pkt == nullptr) {
NFD_LOG_CHAN_WARN("Read error: " << err);
auto [pkt, readErr] = m_pcap.readNextPacket();
if (pkt.empty()) {
NFD_LOG_CHAN_WARN("Read error: " << readErr);
}
else {
const ether_header* eh;
std::tie(eh, err) = ethernet::checkFrameHeader(pkt, len, m_localEndpoint->getEthernetAddress(),
m_localEndpoint->getEthernetAddress());
auto [eh, frameErr] = ethernet::checkFrameHeader(pkt, m_localEndpoint->getEthernetAddress(),
m_localEndpoint->getEthernetAddress());
if (eh == nullptr) {
NFD_LOG_CHAN_DEBUG(err);
NFD_LOG_CHAN_DEBUG(frameErr);
}
else {
ethernet::Address sender(eh->ether_shost);
pkt += ethernet::HDR_LEN;
len -= ethernet::HDR_LEN;
processIncomingPacket(pkt, len, sender, onFaceCreated, onReceiveFailed);
pkt = pkt.subspan(ethernet::HDR_LEN);
processIncomingPacket(pkt, sender, onFaceCreated, onReceiveFailed);
}
}
@@ -154,7 +148,7 @@ EthernetChannel::handleRead(const boost::system::error_code& error,
}
void
EthernetChannel::processIncomingPacket(const uint8_t* packet, size_t length,
EthernetChannel::processIncomingPacket(span<const uint8_t> packet,
const ethernet::Address& sender,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onReceiveFailed)
@@ -182,7 +176,7 @@ EthernetChannel::processIncomingPacket(const uint8_t* packet, size_t length,
// dispatch the packet to the face for processing
auto* transport = static_cast<UnicastEthernetTransport*>(face->getTransport());
transport->receivePayload(packet, length, sender);
transport->receivePayload(packet, sender);
}
std::pair<bool, shared_ptr<Face>>
@@ -204,15 +198,12 @@ EthernetChannel::createFace(const ethernet::Address& remoteEndpoint,
if (params.mtu) {
options.overrideMtu = *params.mtu;
}
if (params.bandwidth) {
options.C = *params.bandwidth;
}
auto linkService = make_unique<GenericLinkService>(options);
auto transport = make_unique<UnicastEthernetTransport>(*m_localEndpoint, remoteEndpoint,
params.persistency, m_idleFaceTimeout);
auto face = make_shared<Face>(std::move(linkService), std::move(transport));
face->setChannel(shared_from_this()); // use weak_from_this() in C++17
face->setChannel(weak_from_this());
m_channelFaces[remoteEndpoint] = face;
connectFaceClosedSignal(*face, [this, remoteEndpoint] {
@@ -243,5 +234,4 @@ EthernetChannel::updateFilter()
m_pcap.setPacketFilter(filter.data());
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+17 -21
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2018, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,53 +29,50 @@
#include "channel.hpp"
#include "ethernet-protocol.hpp"
#include "pcap-helper.hpp"
#include <boost/asio/posix/stream_descriptor.hpp>
#include <ndn-cxx/net/network-interface.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
/**
* \brief Class implementing Ethernet-based channel to create faces
* \brief Class implementing an Ethernet-based channel to create faces.
*/
class EthernetChannel : public Channel
class EthernetChannel final : public Channel
{
public:
/**
* \brief EthernetChannel-related error
* \brief EthernetChannel-related error.
*/
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
using std::runtime_error::runtime_error;
};
/**
* \brief Create an Ethernet channel on the given \p localEndpoint (network interface)
* \brief Create an Ethernet channel on the given \p localEndpoint (network interface).
*
* To enable creation of faces upon incoming connections,
* one needs to explicitly call EthernetChannel::listen method.
* To enable the creation of faces upon incoming connections, one needs to
* explicitly call listen().
*/
EthernetChannel(shared_ptr<const ndn::net::NetworkInterface> localEndpoint,
time::nanoseconds idleTimeout);
bool
isListening() const override
isListening() const final
{
return m_isListening;
}
size_t
size() const override
size() const final
{
return m_channelFaces.size();
}
/**
* \brief Create a unicast Ethernet face toward \p remoteEndpoint
* \brief Create a unicast Ethernet face toward \p remoteEndpoint.
*/
void
connect(const ethernet::Address& remoteEndpoint,
@@ -84,7 +81,7 @@ public:
const FaceCreationFailedCallback& onConnectFailed);
/**
* \brief Start listening
* \brief Start listening.
*
* Enable listening on the local endpoint, waiting for incoming frames,
* and creating a face when a frame is received from a new remote host.
@@ -110,7 +107,7 @@ private:
const FaceCreationFailedCallback& onReceiveFailed);
void
processIncomingPacket(const uint8_t* packet, size_t length,
processIncomingPacket(span<const uint8_t> packet,
const ethernet::Address& sender,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onReceiveFailed);
@@ -136,7 +133,6 @@ private:
#endif
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_ETHERNET_CHANNEL_HPP
+36 -35
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -30,8 +30,7 @@
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm/copy.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_INIT(EthernetFactory);
NFD_REGISTER_PROTOCOL_FACTORY(EthernetFactory);
@@ -47,8 +46,8 @@ EthernetFactory::EthernetFactory(const CtorParams& params)
: ProtocolFactory(params)
{
m_netifAddConn = netmon->onInterfaceAdded.connect([this] (const auto& netif) {
this->applyUnicastConfigToNetif(netif);
this->applyMcastConfigToNetif(*netif);
applyUnicastConfigToNetif(netif);
applyMcastConfigToNetif(*netif);
});
}
@@ -157,11 +156,11 @@ EthernetFactory::doProcessConfig(OptionalConfigSection configSection,
}
}
// Even if there's no configuration change, we still need to re-apply configuration because
// netifs may have changed.
m_unicastConfig = unicastConfig;
m_mcastConfig = mcastConfig;
this->applyConfig(context);
// Even if there are no configuration changes, we still need to re-apply
// the configuration because netifs may have changed.
m_unicastConfig = std::move(unicastConfig);
m_mcastConfig = std::move(mcastConfig);
applyConfig(context);
}
void
@@ -170,13 +169,13 @@ EthernetFactory::doCreateFace(const CreateFaceRequest& req,
const FaceCreationFailedCallback& onFailure)
{
if (!req.localUri || req.localUri->getScheme() != "dev") {
NFD_LOG_TRACE("Cannot create unicast Ethernet face without dev:// LocalUri");
NFD_LOG_TRACE("createFace: dev:// LocalUri required");
onFailure(406, "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme");
return;
}
if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
NFD_LOG_TRACE("createFace: unsupported FacePersistency");
onFailure(406, "Outgoing Ethernet faces do not support on-demand persistency");
return;
}
@@ -185,14 +184,14 @@ EthernetFactory::doCreateFace(const CreateFaceRequest& req,
std::string localEndpoint(req.localUri->getHost());
if (remoteEndpoint.isMulticast()) {
NFD_LOG_TRACE("createFace does not support multicast faces");
NFD_LOG_TRACE("createFace: unsupported multicast endpoint");
onFailure(406, "Cannot create multicast Ethernet faces");
return;
}
if (req.params.wantLocalFields) {
// Ethernet faces are never local
NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
NFD_LOG_TRACE("createFace: cannot create non-local face with local fields enabled");
onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
@@ -240,7 +239,7 @@ EthernetFactory::createMulticastFace(const ndn::net::NetworkInterface& netif,
{
BOOST_ASSERT(address.isMulticast());
auto key = std::make_pair(netif.getName(), address);
std::pair key(netif.getName(), address);
auto found = m_mcastFaces.find(key);
if (found != m_mcastFaces.end()) {
return found->second;
@@ -258,7 +257,9 @@ EthernetFactory::createMulticastFace(const ndn::net::NetworkInterface& netif,
connectFaceClosedSignal(*face, [this, key] { m_mcastFaces.erase(key); });
auto channelIt = m_channels.find(netif.getName());
face->setChannel(channelIt != m_channels.end() ? channelIt->second : nullptr);
if (channelIt != m_channels.end()) {
face->setChannel(channelIt->second);
}
return face;
}
@@ -270,13 +271,13 @@ EthernetFactory::applyUnicastConfigToNetif(const shared_ptr<const ndn::net::Netw
return nullptr;
}
if (netif->getType() != ndn::net::InterfaceType::ETHERNET) {
NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": incompatible netif type");
if (!netif->isUp()) {
NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": netif is down");
return nullptr;
}
if (!netif->isUp()) {
NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": netif is down");
if (netif->getType() != ndn::net::InterfaceType::ETHERNET) {
NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": incompatible netif type");
return nullptr;
}
@@ -304,18 +305,13 @@ EthernetFactory::applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif
return nullptr;
}
if (netif.getType() != ndn::net::InterfaceType::ETHERNET) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": incompatible netif type");
return nullptr;
}
if (!netif.isUp()) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": netif is down");
return nullptr;
}
if (!netif.canMulticast()) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": netif cannot multicast");
if (netif.getType() != ndn::net::InterfaceType::ETHERNET) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": incompatible netif type");
return nullptr;
}
@@ -324,6 +320,11 @@ EthernetFactory::applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif
return nullptr;
}
if (!netif.canMulticast()) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": netif cannot multicast");
return nullptr;
}
if (!m_mcastConfig.netifPredicate(netif)) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": rejected by whitelist/blacklist");
return nullptr;
@@ -332,17 +333,18 @@ EthernetFactory::applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif
NFD_LOG_DEBUG("Creating multicast face on " << netif.getName());
shared_ptr<Face> face;
try {
face = this->createMulticastFace(netif, m_mcastConfig.group);
face = createMulticastFace(netif, m_mcastConfig.group);
}
catch (const EthernetTransport::Error& e) {
catch (const std::runtime_error& e) {
NFD_LOG_WARN("Cannot create multicast face on " << netif.getName() << ": " << e.what());
return nullptr;
return nullptr; // not a fatal error
}
if (face->getId() == face::INVALID_FACEID) {
if (face->getId() == INVALID_FACEID) {
// new face: register with forwarding
this->addFace(face);
}
return face;
}
@@ -362,9 +364,9 @@ EthernetFactory::applyConfig(const FaceSystem::ConfigContext&)
// create channels and multicast faces if requested by config
for (const auto& netif : netmon->listNetworkInterfaces()) {
this->applyUnicastConfigToNetif(netif);
applyUnicastConfigToNetif(netif);
auto face = this->applyMcastConfigToNetif(*netif);
auto face = applyMcastConfigToNetif(*netif);
if (face != nullptr) {
// don't destroy face
oldFaces.erase(face);
@@ -377,5 +379,4 @@ EthernetFactory::applyConfig(const FaceSystem::ConfigContext&)
}
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+23 -22
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2018, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,13 +28,14 @@
#include "protocol-factory.hpp"
#include "ethernet-channel.hpp"
#include "network-predicate.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief Protocol factory for Ethernet
/**
* \brief Protocol factory for Ethernet.
*/
class EthernetFactory : public ProtocolFactory
class EthernetFactory final : public ProtocolFactory
{
public:
static const std::string&
@@ -44,12 +45,12 @@ public:
EthernetFactory(const CtorParams& params);
/**
* \brief Create Ethernet-based channel on the specified network interface
* \brief Create Ethernet-based channel on the specified network interface.
*
* If this method is called twice with the same endpoint, only one channel
* will be created. The second call will just return the existing channel.
*
* \return always a valid pointer to a EthernetChannel object, an exception
* \return Always a valid pointer to a EthernetChannel object, an exception
* is thrown if it cannot be created.
* \throw PcapHelper::Error channel creation failed
*/
@@ -58,7 +59,7 @@ public:
time::nanoseconds idleTimeout);
/**
* \brief Create a face to communicate on the given Ethernet multicast group
* \brief Create a face to communicate on the given Ethernet multicast group.
*
* If this method is called twice with the same arguments, only one face
* will be created. The second call will just return the existing face.
@@ -66,35 +67,35 @@ public:
* \param localEndpoint local network interface
* \param group multicast group address
*
* \throw EthernetTransport::Error transport creation fails
* \throw std::runtime_error %Face creation failed
*/
shared_ptr<Face>
createMulticastFace(const ndn::net::NetworkInterface& localEndpoint,
const ethernet::Address& group);
private:
/** \brief process face_system.ether config section
*/
void
doProcessConfig(OptionalConfigSection configSection,
FaceSystem::ConfigContext& context) override;
FaceSystem::ConfigContext& context) final;
void
doCreateFace(const CreateFaceRequest& req,
const FaceCreatedCallback& onCreated,
const FaceCreationFailedCallback& onFailure) override;
const FaceCreationFailedCallback& onFailure) final;
std::vector<shared_ptr<const Channel>>
doGetChannels() const override;
doGetChannels() const final;
/** \brief Create EthernetChannel on \p netif if requested by \p m_unicastConfig.
* \return new or existing channel, or nullptr if no channel should be created
/**
* \brief Create EthernetChannel on \p netif if requested by \p m_unicastConfig.
* \return New or existing channel, or nullptr if no channel should be created.
*/
shared_ptr<EthernetChannel>
applyUnicastConfigToNetif(const shared_ptr<const ndn::net::NetworkInterface>& netif);
/** \brief Create Ethernet multicast face on \p netif if requested by \p m_mcastConfig.
* \return new or existing face, or nullptr if no face should be created
/**
* \brief Create Ethernet multicast face on \p netif if requested by \p m_mcastConfig.
* \return New or existing face, or nullptr if no face should be created.
*/
shared_ptr<Face>
applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif);
@@ -103,7 +104,8 @@ private:
applyConfig(const FaceSystem::ConfigContext& context);
private:
std::map<std::string, shared_ptr<EthernetChannel>> m_channels; ///< ifname => channel
// ifname => channel
std::map<std::string, shared_ptr<EthernetChannel>> m_channels;
struct UnicastConfig
{
@@ -122,13 +124,12 @@ private:
};
MulticastConfig m_mcastConfig;
/// (ifname, group) => face
// [ifname, group] => face
std::map<std::pair<std::string, ethernet::Address>, shared_ptr<Face>> m_mcastFaces;
signal::ScopedConnection m_netifAddConn;
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_ETHERNET_FACTORY_HPP
+8 -11
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2018, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,17 +27,15 @@
#include <boost/endian/conversion.hpp>
namespace nfd {
namespace ethernet {
namespace nfd::ethernet {
std::pair<const ether_header*, std::string>
checkFrameHeader(const uint8_t* packet, size_t length,
const Address& localAddr, const Address& destAddr)
std::tuple<const ether_header*, std::string>
checkFrameHeader(span<const uint8_t> packet, const Address& localAddr, const Address& destAddr)
{
if (length < HDR_LEN + MIN_DATA_LEN)
return {nullptr, "Received frame too short: " + to_string(length) + " bytes"};
if (packet.size() < HDR_LEN + MIN_DATA_LEN)
return {nullptr, "Received frame too short: " + to_string(packet.size()) + " bytes"};
const ether_header* eh = reinterpret_cast<const ether_header*>(packet);
const ether_header* eh = reinterpret_cast<const ether_header*>(packet.data());
// in some cases VLAN-tagged frames may survive the BPF filter,
// make sure we do not process those frames (see #3348)
@@ -58,5 +56,4 @@ checkFrameHeader(const uint8_t* packet, size_t length,
return {eh, ""};
}
} // namespace ethernet
} // namespace nfd
} // namespace nfd::ethernet
+6 -8
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,19 +27,17 @@
#define NFD_DAEMON_FACE_ETHERNET_PROTOCOL_HPP
#include "core/common.hpp"
#include <ndn-cxx/net/ethernet.hpp>
#include <net/ethernet.h>
namespace nfd {
namespace ethernet {
namespace nfd::ethernet {
using namespace ndn::ethernet;
std::pair<const ether_header*, std::string>
checkFrameHeader(const uint8_t* packet, size_t length,
const Address& localAddr, const Address& destAddr);
std::tuple<const ether_header*, std::string>
checkFrameHeader(span<const uint8_t> packet, const Address& localAddr, const Address& destAddr);
} // namespace ethernet
} // namespace nfd
} // namespace nfd::ethernet
#endif // NFD_DAEMON_FACE_ETHERNET_PROTOCOL_HPP
+24 -42
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,12 +29,10 @@
#include <pcap/pcap.h>
#include <cstring> // for memcpy()
#include <boost/asio/defer.hpp>
#include <boost/endian/conversion.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_INIT(EthernetTransport);
@@ -90,7 +88,7 @@ EthernetTransport::doClose()
// Ensure that the Transport stays alive at least
// until all pending handlers are dispatched
getGlobalIoService().post([this] {
boost::asio::defer(getGlobalIoService(), [this] {
this->setState(TransportState::CLOSED);
});
}
@@ -125,17 +123,17 @@ EthernetTransport::sendPacket(const ndn::Block& 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());
buffer.appendBytes(ndn::make_span(padding).subspan(block.size()));
}
// construct and prepend the ethernet header
uint16_t ethertype = boost::endian::native_to_big(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());
buffer.prependBytes({reinterpret_cast<const uint8_t*>(&ethertype), ethernet::TYPE_LEN});
buffer.prependBytes(m_srcAddress);
buffer.prependBytes(m_destAddress);
// send the frame
int sent = pcap_inject(m_pcap, buffer.buf(), buffer.size());
int sent = pcap_inject(m_pcap, buffer.data(), buffer.size());
if (sent < 0)
handleError("Send operation failed: " + m_pcap.getLastError());
else if (static_cast<size_t>(sent) < buffer.size())
@@ -149,8 +147,8 @@ EthernetTransport::sendPacket(const ndn::Block& block)
void
EthernetTransport::asyncRead()
{
m_socket.async_read_some(boost::asio::null_buffers(),
[this] (const auto& e, auto) { this->handleRead(e); });
m_socket.async_wait(boost::asio::posix::stream_descriptor::wait_read,
[this] (const auto& e) { this->handleRead(e); });
}
void
@@ -168,26 +166,20 @@ EthernetTransport::handleRead(const boost::system::error_code& error)
return;
}
const uint8_t* pkt;
size_t len;
std::string err;
std::tie(pkt, len, err) = m_pcap.readNextPacket();
if (pkt == nullptr) {
NFD_LOG_FACE_WARN("Read error: " << err);
auto [pkt, readErr] = m_pcap.readNextPacket();
if (pkt.empty()) {
NFD_LOG_FACE_DEBUG("Read error: " << readErr);
}
else {
const ether_header* eh;
std::tie(eh, err) = ethernet::checkFrameHeader(pkt, len, m_srcAddress,
m_destAddress.isMulticast() ? m_destAddress : m_srcAddress);
auto [eh, frameErr] = ethernet::checkFrameHeader(pkt, m_srcAddress,
m_destAddress.isMulticast() ? m_destAddress : m_srcAddress);
if (eh == nullptr) {
NFD_LOG_FACE_WARN(err);
NFD_LOG_FACE_WARN(frameErr);
}
else {
ethernet::Address sender(eh->ether_shost);
pkt += ethernet::HDR_LEN;
len -= ethernet::HDR_LEN;
receivePayload(pkt, len, sender);
pkt = pkt.subspan(ethernet::HDR_LEN);
receivePayload(pkt, sender);
}
}
@@ -202,14 +194,11 @@ EthernetTransport::handleRead(const boost::system::error_code& error)
}
void
EthernetTransport::receivePayload(const uint8_t* payload, size_t length,
const ethernet::Address& sender)
EthernetTransport::receivePayload(span<const uint8_t> payload, const ethernet::Address& sender)
{
NFD_LOG_FACE_TRACE("Received: " << length << " bytes from " << sender);
NFD_LOG_FACE_TRACE("Received: " << payload.size() << " bytes from " << sender);
bool isOk = false;
Block element;
std::tie(isOk, element) = Block::fromBuffer(payload, length);
auto [isOk, element] = Block::fromBuffer(payload);
if (!isOk) {
NFD_LOG_FACE_WARN("Failed to parse incoming packet from " << sender);
// This packet won't extend the face lifetime
@@ -217,13 +206,7 @@ EthernetTransport::receivePayload(const uint8_t* payload, size_t length,
}
m_hasRecentlyReceived = true;
static_assert(sizeof(EndpointId) >= ethernet::ADDR_LEN, "EndpointId is too small");
EndpointId endpoint = 0;
if (m_destAddress.isMulticast()) {
std::memcpy(&endpoint, sender.data(), sender.size());
}
this->receive(element, endpoint);
this->receive(element, m_destAddress.isMulticast() ? sender : EndpointId{});
}
void
@@ -239,5 +222,4 @@ EthernetTransport::handleError(const std::string& errorMessage)
doClose();
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+9 -12
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -30,13 +30,13 @@
#include "pcap-helper.hpp"
#include "transport.hpp"
#include <boost/asio/posix/stream_descriptor.hpp>
#include <ndn-cxx/net/network-interface.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
/**
* @brief Base class for Ethernet-based Transports
* @brief Base class for Ethernet-based Transports.
*/
class EthernetTransport : public Transport
{
@@ -48,14 +48,12 @@ public:
};
/**
* @brief Processes the payload of an incoming frame
* @param payload Pointer to the first byte of data after the Ethernet header
* @param length Payload length
* @brief Processes the payload of an incoming frame.
* @param payload Payload bytes, starting from the first byte after the Ethernet header
* @param sender Sender address
*/
void
receivePayload(const uint8_t* payload, size_t length,
const ethernet::Address& sender);
receivePayload(span<const uint8_t> payload, const ethernet::Address& sender);
protected:
EthernetTransport(const ndn::net::NetworkInterface& localEndpoint,
@@ -84,7 +82,7 @@ private:
doSend(const Block& packet) final;
/**
* @brief Sends the specified TLV block on the network wrapped in an Ethernet frame
* @brief Sends the specified TLV block on the network wrapped in an Ethernet frame.
*/
void
sendPacket(const ndn::Block& block);
@@ -115,7 +113,6 @@ private:
#endif
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_ETHERNET_TRANSPORT_HPP
+32 -29
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,12 +26,14 @@
#ifndef NFD_DAEMON_FACE_FACE_COMMON_HPP
#define NFD_DAEMON_FACE_FACE_COMMON_HPP
#include "core/common.hpp"
#include "ethernet-protocol.hpp"
#include "udp-protocol.hpp"
#include "common/logger.hpp"
#include <ndn-cxx/encoding/nfd-constants.hpp>
#include <boost/logic/tribool.hpp>
#include <variant>
namespace nfd {
namespace face {
@@ -39,36 +41,40 @@ namespace face {
class Face;
class LinkService;
/** \brief Identifies a face.
/**
* \brief Identifies a face.
*/
using FaceId = uint64_t;
/// indicates an invalid FaceId
const FaceId INVALID_FACEID = ndn::nfd::INVALID_FACE_ID;
/// 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;
/// Indicates an invalid FaceId
inline constexpr FaceId INVALID_FACEID = ndn::nfd::INVALID_FACE_ID;
/// Identifies the InternalFace used in management
inline constexpr FaceId FACEID_INTERNAL_FACE = 1;
/// Identifies a packet comes from the ContentStore
inline constexpr FaceId FACEID_CONTENT_STORE = 254;
/// Identifies the NullFace that drops every packet
inline constexpr FaceId FACEID_NULL = 255;
/// Upper bound of reserved FaceIds
inline constexpr FaceId FACEID_RESERVED_MAX = 255;
/** \brief Minimum MTU that may be set
/**
* \brief Minimum MTU that may be set.
*
* This is done to ensure the NDNLPv2 fragmentation feature functions properly.
* This is done to ensure the NDNLPv2 fragmentation feature functions properly.
*/
const ssize_t MIN_MTU = 64;
inline constexpr ssize_t MIN_MTU = 64;
/** \brief Identifies a remote endpoint on the link.
/**
* \brief Identifies a remote endpoint on the link.
*
* This ID is only meaningful in the context of the same Transport.
* Incoming packets from the same remote endpoint have the same EndpointId,
* and incoming packets from different remote endpoints have different EndpointIds.
* This ID is only meaningful in the context of the same Transport.
* Incoming packets from the same remote endpoint have the same EndpointId,
* and incoming packets from different remote endpoints have different EndpointIds.
*
* Typically, a point-to-point Transport has only one meaningful EndpointId (usually 0).
* Typically, a point-to-point Transport has only one meaningful EndpointId,
* represented by `std::monostate`.
*/
using EndpointId = uint64_t;
using EndpointId = std::variant<std::monostate, ethernet::Address, udp::Endpoint>;
/** \brief Parameters used to set Transport properties or LinkService options on a newly created face.
*
@@ -78,10 +84,9 @@ using EndpointId = uint64_t;
struct FaceParams
{
ndn::nfd::FacePersistency persistency = ndn::nfd::FACE_PERSISTENCY_PERSISTENT;
optional<time::nanoseconds> baseCongestionMarkingInterval;
optional<uint64_t> defaultCongestionThreshold;
optional<ssize_t> mtu;
optional<uint64_t> bandwidth;
std::optional<time::nanoseconds> baseCongestionMarkingInterval;
std::optional<uint64_t> defaultCongestionThreshold;
std::optional<ssize_t> mtu;
bool wantLocalFields = false;
bool wantLpReliability = false;
boost::logic::tribool wantCongestionMarking = boost::logic::indeterminate;
@@ -129,9 +134,7 @@ using face::FaceId;
// implementation detail
#define NFD_LOG_FACE(level, msg) NFD_LOG_##level( \
::nfd::face::FaceLogHelper< \
typename std::remove_cv< \
typename std::remove_reference<decltype(*this)>::type \
>::type \
std::remove_cv_t<std::remove_reference_t<decltype(*this)>> \
>(*this) \
<< msg)
/** \endcond */
+3 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -25,8 +25,7 @@
#include "face-counters.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
FaceCounters::FaceCounters(const LinkService::Counters& linkServiceCounters,
const Transport::Counters& transportCounters)
@@ -46,5 +45,4 @@ FaceCounters::FaceCounters(const LinkService::Counters& linkServiceCounters,
{
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+8 -10
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,10 +29,9 @@
#include "link-service.hpp"
#include "transport.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief gives access to counters provided by Face
/** \brief Gives access to counters provided by Face.
*
* This type is a facade that exposes common counters of a Face.
*
@@ -50,7 +49,7 @@ public:
* \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
std::enable_if_t<std::is_base_of_v<LinkService::Counters, T>, const T&>
get() const
{
return dynamic_cast<const T&>(m_linkServiceCounters);
@@ -61,7 +60,7 @@ public:
* \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
std::enable_if_t<std::is_base_of_v<Transport::Counters, T>, const T&>
get() const
{
return dynamic_cast<const T&>(m_transportCounters);
@@ -81,11 +80,11 @@ public:
const ByteCounter& nInBytes;
const ByteCounter& nOutBytes;
/** \brief count of incoming Interests dropped due to HopLimit == 0
/** \brief Count of incoming Interests dropped due to HopLimit == 0.
*/
PacketCounter nInHopLimitZero;
/** \brief count of outgoing Interests dropped due to HopLimit == 0 on non-local faces
/** \brief Count of outgoing Interests dropped due to HopLimit == 0 on non-local faces.
*/
PacketCounter nOutHopLimitZero;
@@ -94,7 +93,6 @@ private:
const Transport::Counters& m_transportCounters;
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_FACE_COUNTERS_HPP
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2018, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -23,27 +23,31 @@
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "available-commands.hpp"
#include "cs-module.hpp"
#include "face-module.hpp"
#include "rib-module.hpp"
#include "status.hpp"
#include "strategy-choice-module.hpp"
#include "face-endpoint.hpp"
#include <boost/hana/functional/overload.hpp>
namespace nfd {
namespace tools {
namespace nfdc {
void
registerCommands(CommandParser& parser)
FaceEndpoint::FaceEndpoint(Face& face, const EndpointId& endpoint)
: face(face)
, endpoint(endpoint)
{
registerStatusCommands(parser);
FaceModule::registerCommands(parser);
RibModule::registerCommands(parser);
CsModule::registerCommands(parser);
StrategyChoiceModule::registerCommands(parser);
}
} // namespace nfdc
} // namespace tools
void
FaceEndpoint::print(std::ostream& os) const
{
std::visit(boost::hana::overload(
[&] (std::monostate) {
os << face.getId();
},
[&] (const ethernet::Address& ep) {
os << '(' << face.getId() << ", " << ep << ')';
},
[&] (const udp::Endpoint& ep) {
os << '(' << face.getId() << ", " << ep << ')';
}), endpoint);
}
} // namespace nfd
+15 -12
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -30,16 +30,25 @@
namespace nfd {
/** \brief Represents a face-endpoint pair in the forwarder.
* \sa face::Face, face::EndpointId
/**
* \brief Represents a face-endpoint pair in the forwarder.
* \sa face::Face, face::EndpointId
*/
class FaceEndpoint
{
public:
FaceEndpoint(const Face& face, EndpointId endpoint)
: face(const_cast<Face&>(face))
, endpoint(endpoint)
explicit
FaceEndpoint(Face& face, const EndpointId& endpoint = {});
private:
void
print(std::ostream& os) const;
friend std::ostream&
operator<<(std::ostream& os, const FaceEndpoint& fe)
{
fe.print(os);
return os;
}
public:
@@ -47,12 +56,6 @@ public:
const EndpointId endpoint;
};
inline std::ostream&
operator<<(std::ostream& os, const FaceEndpoint& fe)
{
return os << '(' << fe.face.getId() << ',' << fe.endpoint << ')';
}
} // namespace nfd
#endif // NFD_DAEMON_FACE_FACE_ENDPOINT_HPP
+13 -17
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,13 +24,11 @@
*/
#include "face-system.hpp"
#include "protocol-factory.hpp"
#include "netdev-bound.hpp"
#include "common/global.hpp"
#include "protocol-factory.hpp"
#include "fw/face-table.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_INIT(FaceSystem);
@@ -72,14 +70,14 @@ FaceSystem::listProtocolFactories() const
}
ProtocolFactory*
FaceSystem::getFactoryById(const std::string& id)
FaceSystem::getFactoryById(const std::string& id) const
{
auto found = m_factories.find(id);
return found == m_factories.end() ? nullptr : found->second.get();
}
ProtocolFactory*
FaceSystem::getFactoryByScheme(const std::string& scheme)
FaceSystem::getFactoryByScheme(const std::string& scheme) const
{
auto found = m_factoryByScheme.find(scheme);
return found == m_factoryByScheme.end() ? nullptr : found->second;
@@ -94,7 +92,9 @@ FaceSystem::hasFactoryForScheme(const std::string& scheme) const
void
FaceSystem::setConfigFile(ConfigFile& configFile)
{
configFile.addSectionHandler(CFGSEC_FACESYSTEM, bind(&FaceSystem::processConfig, this, _1, _2, _3));
configFile.addSectionHandler(CFGSEC_FACESYSTEM, [this] (auto&&... args) {
processConfig(std::forward<decltype(args)>(args)...);
});
}
void
@@ -118,22 +118,19 @@ FaceSystem::processConfig(const ConfigSection& configSection, bool isDryRun, con
}
// process in protocol factories
for (const auto& pair : m_factories) {
const std::string& sectionName = pair.first;
ProtocolFactory* factory = pair.second.get();
for (const auto& [sectionName, factory] : m_factories) {
std::set<std::string> oldProvidedSchemes = factory->getProvidedSchemes();
factory->processConfig(configSection.get_child_optional(sectionName), context);
if (!isDryRun) {
for (const std::string& scheme : factory->getProvidedSchemes()) {
m_factoryByScheme[scheme] = factory;
for (const auto& scheme : factory->getProvidedSchemes()) {
m_factoryByScheme[scheme] = factory.get();
if (oldProvidedSchemes.erase(scheme) == 0) {
NFD_LOG_TRACE("factory " << sectionName <<
" provides " << scheme << " FaceUri scheme");
}
}
for (const std::string& scheme : oldProvidedSchemes) {
for (const auto& scheme : oldProvidedSchemes) {
m_factoryByScheme.erase(scheme);
NFD_LOG_TRACE("factory " << sectionName <<
" no longer provides " << scheme << " FaceUri scheme");
@@ -164,5 +161,4 @@ FaceSystem::processConfig(const ConfigSection& configSection, bool isDryRun, con
}
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+21 -18
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,7 +26,6 @@
#ifndef NFD_DAEMON_FACE_FACE_SYSTEM_HPP
#define NFD_DAEMON_FACE_FACE_SYSTEM_HPP
#include "network-predicate.hpp"
#include "common/config-file.hpp"
#include <ndn-cxx/net/network-address.hpp>
@@ -43,10 +42,11 @@ class NetdevBound;
class ProtocolFactory;
struct ProtocolFactoryCtorParams;
/** \brief entry point of the face system
/**
* \brief Entry point of NFD's face system.
*
* NFD's face system is organized as a FaceSystem-ProtocolFactory-Channel-Face hierarchy.
* FaceSystem class is the entry point of NFD's face system and owns ProtocolFactory objects.
* NFD's face system is organized as a FaceSystem-ProtocolFactory-Channel-Face hierarchy.
* The FaceSystem class is the entry point of the face system and owns all ProtocolFactory objects.
*/
class FaceSystem : noncopyable
{
@@ -55,20 +55,23 @@ public:
~FaceSystem();
/** \return ProtocolFactory objects owned by the FaceSystem
/**
* \brief Returns all ProtocolFactory objects owned by the face system.
*/
std::set<const ProtocolFactory*>
[[nodiscard]] std::set<const ProtocolFactory*>
listProtocolFactories() const;
/** \return ProtocolFactory for the specified registered factory id or nullptr if not found
/**
* \return ProtocolFactory for the specified registered factory id or nullptr if not found.
*/
ProtocolFactory*
getFactoryById(const std::string& id);
getFactoryById(const std::string& id) const;
/** \return ProtocolFactory for the specified FaceUri scheme or nullptr if not found
/**
* \return ProtocolFactory for the specified FaceUri scheme or nullptr if not found.
*/
ProtocolFactory*
getFactoryByScheme(const std::string& scheme);
getFactoryByScheme(const std::string& scheme) const;
bool
hasFactoryForScheme(const std::string& scheme) const;
@@ -79,19 +82,19 @@ public:
return m_faceTable;
}
/** \brief register handler for face_system section of NFD configuration file
/** \brief Register handler for the `face_system` section of NFD's configuration file.
*/
void
setConfigFile(ConfigFile& configFile);
/** \brief configuration options from "general" section
/** \brief Configuration options from `general` section.
*/
struct GeneralConfig
{
bool wantCongestionMarking = true;
};
/** \brief context for processing a config section in ProtocolFactory
/** \brief Context for processing a config section in ProtocolFactory.
*/
class ConfigContext : noncopyable
{
@@ -100,7 +103,7 @@ public:
bool isDryRun;
};
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
ProtocolFactoryCtorParams
makePFCtorParams();
@@ -109,14 +112,14 @@ private:
processConfig(const ConfigSection& configSection, bool isDryRun,
const std::string& filename);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/** \brief config section name => protocol factory
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/** \brief Config section name => protocol factory.
*/
std::map<std::string, unique_ptr<ProtocolFactory>> m_factories;
unique_ptr<NetdevBound> m_netdevBound;
private:
/** \brief scheme => protocol factory
/** \brief Scheme => protocol factory.
*
* The same protocol factory may be available under multiple schemes.
*/
+3 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -25,8 +25,7 @@
#include "face.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
Face::Face(unique_ptr<LinkService> service, unique_ptr<Transport> transport)
: afterReceiveInterest(service->afterReceiveInterest)
@@ -34,7 +33,6 @@ Face::Face(unique_ptr<LinkService> service, unique_ptr<Transport> transport)
, afterReceiveNack(service->afterReceiveNack)
, onDroppedInterest(service->onDroppedInterest)
, 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())
@@ -52,5 +50,4 @@ operator<<(std::ostream& os, const FaceLogHelper<Face>& flh)
return os;
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+72 -68
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -36,11 +36,12 @@ namespace face {
class Channel;
/** \brief indicates the state of a face
/**
* \brief Indicates the state of a face.
*/
typedef TransportState FaceState;
using FaceState = TransportState;
/** \brief generalization of a network interface
/** \brief Generalization of a network interface.
*
* A face generalizes a network interface.
* It provides best-effort network-layer packet delivery services
@@ -51,18 +52,24 @@ typedef TransportState FaceState;
* 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 FINAL_UNLESS_WITH_TESTS : public std::enable_shared_from_this<Face>, noncopyable
class Face NFD_FINAL_UNLESS_WITH_TESTS : public std::enable_shared_from_this<Face>, noncopyable
{
public:
Face(unique_ptr<LinkService> service, unique_ptr<Transport> transport);
LinkService*
getLinkService() const;
getLinkService() const noexcept
{
return m_service.get();
}
Transport*
getTransport() const;
getTransport() const noexcept
{
return m_transport.get();
}
/** \brief Request that the face be closed
/** \brief Request that the face be closed.
*
* This operation is effective only if face is in the UP or DOWN state; otherwise, it has no effect.
* The face will change state to CLOSING, and then perform a cleanup procedure.
@@ -75,106 +82,133 @@ public:
close();
public: // upper interface connected to forwarding
/** \brief send Interest
/** \brief Send Interest.
*/
void
sendInterest(const Interest& interest);
/** \brief send Data
/** \brief Send Data.
*/
void
sendData(const Data& data);
/** \brief send Nack
/** \brief Send Nack.
*/
void
sendNack(const lp::Nack& nack);
/** \brief signals on Interest received
/** \brief Signals on Interest received.
*/
signal::Signal<LinkService, Interest, EndpointId>& afterReceiveInterest;
/** \brief signals on Data received
/** \brief Signals on Data received.
*/
signal::Signal<LinkService, Data, EndpointId>& afterReceiveData;
/** \brief signals on Nack received
/** \brief Signals on Nack received.
*/
signal::Signal<LinkService, lp::Nack, EndpointId>& afterReceiveNack;
/** \brief signals on Interest dropped by reliability system for exceeding allowed number of retx
/** \brief Signals on Interest dropped by reliability system for exceeding allowed number of retx.
*/
signal::Signal<LinkService, Interest>& onDroppedInterest;
public: // properties
/** \return face ID
/**
* \brief Returns the face ID.
*/
FaceId
getId() const;
getId() const noexcept
{
return m_id;
}
/** \brief sets face ID
* \note Normally, this should only be invoked by FaceTable.
/**
* \brief Sets the face ID.
* \note Normally, this should only be invoked by FaceTable.
*/
void
setId(FaceId id);
setId(FaceId id) noexcept
{
m_id = id;
}
/** \return a FaceUri representing local endpoint
/**
* \brief Returns a FaceUri representing the local endpoint.
*/
FaceUri
getLocalUri() const;
/** \return a FaceUri representing remote endpoint
/**
* \brief Returns a FaceUri representing the remote endpoint.
*/
FaceUri
getRemoteUri() const;
/** \return whether face is local or non-local for scope control purpose
/**
* \brief Returns whether the face is local or non-local for scope control purposes.
*/
ndn::nfd::FaceScope
getScope() const;
/** \return face persistency setting
/**
* \brief Returns the current persistency setting of the face.
*/
ndn::nfd::FacePersistency
getPersistency() const;
/** \brief changes face persistency setting
/**
* \brief Changes the face persistency setting.
*/
void
setPersistency(ndn::nfd::FacePersistency persistency);
/** \return whether face is point-to-point or multi-access
/**
* \brief Returns the link type of the face (point-to-point, multi-access, ...).
*/
ndn::nfd::LinkType
getLinkType() const;
/** \brief Returns face effective MTU
/**
* \brief Returns the effective MTU of the face.
*
* This function is a wrapper. The effective MTU of a face is determined by the link service.
* This function is a wrapper. The effective MTU of a face is determined by the link service.
*/
ssize_t
getMtu() const;
/** \return face state
/**
* \brief Returns the face state.
*/
FaceState
getState() const;
/** \brief signals after face state changed
/**
* \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
/**
* \brief Returns the expiration time of the face.
* \retval time::steady_clock::time_point::max() The face has an indefinite lifetime.
*/
time::steady_clock::TimePoint
time::steady_clock::time_point
getExpirationTime() const;
const FaceCounters&
getCounters() const;
getCounters() const noexcept
{
return m_counters;
}
FaceCounters&
getCounters() noexcept
{
return m_counters;
}
/**
* \brief Get channel on which face was created (unicast) or the associated channel (multicast)
* \brief Get channel on which face was created (unicast) or the associated channel (multicast).
*/
weak_ptr<Channel>
getChannel() const
@@ -183,7 +217,7 @@ public: // properties
}
/**
* \brief Set channel on which face was created (unicast) or the associated channel (multicast)
* \brief Set channel on which face was created (unicast) or the associated channel (multicast).
*/
void
setChannel(weak_ptr<Channel> channel)
@@ -192,25 +226,13 @@ public: // properties
}
private:
FaceId m_id;
FaceId m_id = INVALID_FACEID;
unique_ptr<LinkService> m_service;
unique_ptr<Transport> m_transport;
FaceCounters m_counters;
weak_ptr<Channel> m_channel;
};
inline LinkService*
Face::getLinkService() const
{
return m_service.get();
}
inline Transport*
Face::getTransport() const
{
return m_transport.get();
}
inline void
Face::close()
{
@@ -235,18 +257,6 @@ 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
{
@@ -295,18 +305,12 @@ Face::getState() const
return m_transport->getState();
}
inline time::steady_clock::TimePoint
inline time::steady_clock::time_point
Face::getExpirationTime() const
{
return m_transport->getExpirationTime();
}
inline const FaceCounters&
Face::getCounters() const
{
return m_counters;
}
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<Face>& flh);
+34 -46
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -25,13 +25,13 @@
#include "generic-link-service.hpp"
#include <iostream>
#include <ndn-cxx/lp/fields.hpp>
#include <ndn-cxx/lp/pit-token.hpp>
#include <ndn-cxx/lp/tags.hpp>
#include <cmath>
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_INIT(GenericLinkService);
@@ -45,16 +45,15 @@ GenericLinkService::GenericLinkService(const GenericLinkService::Options& option
, m_reassembler(m_options.reassemblerOptions, this)
, m_reliability(m_options.reliabilityOptions, this)
, m_lastSeqNo(-2)
, m_nextMarkTime(time::steady_clock::TimePoint::max())
, m_nextMarkTime(time::steady_clock::time_point::max())
, m_nMarkedSinceInMarkingState(0)
, globalSp(options.C * 0.99, options.vqSize)
{
std::cout << "C: " << options.C << std::endl;
m_reassembler.beforeTimeout.connect([this] (auto...) { ++this->nReassemblyTimeouts; });
m_reliability.onDroppedInterest.connect([this] (const auto& i) { this->notifyDroppedInterest(i); });
m_reassembler.beforeTimeout.connect([this] (auto&&...) { ++nReassemblyTimeouts; });
m_reliability.onDroppedInterest.connect([this] (const auto& i) { notifyDroppedInterest(i); });
nReassembling.observe(&m_reassembler);
this->sendPacketCallback = [this](std::shared_ptr<VirtualQueueItem> taskPtr) {
this->globalSp.triggerCalObjectRate();
if (taskPtr != nullptr) {
const Block &block = taskPtr->item->wireEncode();
// std::cout << "interest wireEncode size: " << block.size() << std::endl;
@@ -71,16 +70,14 @@ GenericLinkService::GenericLinkService(const GenericLinkService::Options& option
auto newTaskPtr = this->globalSp.scheduleNext();
if (newTaskPtr == nullptr) {
//NFD_LOG_ERROR("FUCK");
// std::cout << "FUCK" << std::endl;
// 如果没有可调度的包,则 1 ms 之后再调度
this->canScheduler = true;
// getScheduler().schedule(time::milliseconds(1), std::bind(this->sendPacketCallback, nullptr));
} else {
// 等待足够的 token 再发送
this->canScheduler = false;
// std::cout << "Route waitTime: " << newTaskPtr->waitNsTime << std::endl;
// NFD_LOG_DEBUG("Route waitTime: " << newTaskPtr->waitNsTime);
getScheduler().schedule(time::nanoseconds((uint32_t)(0)),
getScheduler().schedule(time::nanoseconds((uint32_t)(newTaskPtr->waitNsTime)),
std::bind(this->sendPacketCallback, newTaskPtr));
}
};
@@ -139,7 +136,7 @@ GenericLinkService::sendLpPacket(lp::Packet&& pkt)
auto block = pkt.wireEncode();
if (mtu != MTU_UNLIMITED && block.size() > static_cast<size_t>(mtu)) {
++this->nOutOverMtu;
++nOutOverMtu;
NFD_LOG_FACE_WARN("attempted to send packet over MTU limit");
return;
}
@@ -173,6 +170,7 @@ GenericLinkService::doSendInterest(const Interest& interest)
// this->receiveNack(nack, endpointId);
//}
}
// lp::Packet lpPacket(interest.wireEncode());
// encodeLpFields(interest, lpPacket);
@@ -182,9 +180,12 @@ GenericLinkService::doSendInterest(const Interest& interest)
void
GenericLinkService::doSendData(const Data& data)
{
// const Block& block = data.wireEncode();
// std::cout << "Data wireEncode size: " << block.size() << std::endl;
lp::Packet lpPacket(data.wireEncode());
// std::cout << "Data before encode LpFields size: " << lpPacket.wireEncode().size() << std::endl;
encodeLpFields(data, lpPacket);
// std::cout << "Data After encode LpFields size: " << lpPacket.wireEncode().size() << std::endl;
this->sendNetPacket(std::move(lpPacket), false);
}
@@ -264,7 +265,7 @@ GenericLinkService::sendNetPacket(lp::Packet&& pkt, bool isInterest)
std::tie(isOk, frags) = m_fragmenter.fragmentPacket(pkt, mtu);
if (!isOk) {
// fragmentation failed (warning is logged by LpFragmenter)
++this->nFragmentationErrors;
++nFragmentationErrors;
return;
}
}
@@ -318,7 +319,7 @@ GenericLinkService::checkCongestionLevel(lp::Packet& pkt)
if (static_cast<size_t>(sendQueueLength) > m_options.defaultCongestionThreshold) {
const auto now = time::steady_clock::now();
if (m_nextMarkTime == time::steady_clock::TimePoint::max()) {
if (m_nextMarkTime == time::steady_clock::time_point::max()) {
m_nextMarkTime = now + m_options.baseCongestionMarkingInterval;
}
// Mark packet if sendQueue stays above target for one interval
@@ -336,10 +337,10 @@ GenericLinkService::checkCongestionLevel(lp::Packet& pkt)
m_nextMarkTime += interval;
}
}
else if (m_nextMarkTime != time::steady_clock::TimePoint::max()) {
else if (m_nextMarkTime != time::steady_clock::time_point::max()) {
// Congestion incident has ended, so reset
NFD_LOG_FACE_DEBUG("Send queue length dropped below congestion threshold");
m_nextMarkTime = time::steady_clock::TimePoint::max();
m_nextMarkTime = time::steady_clock::time_point::max();
m_nMarkedSinceInMarkingState = 0;
}
}
@@ -353,7 +354,7 @@ GenericLinkService::doReceivePacket(const Block& packet, const EndpointId& endpo
if (m_options.reliabilityOptions.isEnabled) {
if (!m_reliability.processIncomingPacket(pkt)) {
NFD_LOG_FACE_TRACE("received duplicate fragment: DROP");
++this->nDuplicateSequence;
++nDuplicateSequence;
return;
}
}
@@ -369,16 +370,13 @@ GenericLinkService::doReceivePacket(const Block& packet, const EndpointId& endpo
return;
}
bool isReassembled = false;
Block netPkt;
lp::Packet firstPkt;
std::tie(isReassembled, netPkt, firstPkt) = m_reassembler.receiveFragment(endpoint, pkt);
auto [isReassembled, netPkt, firstPkt] = m_reassembler.receiveFragment(endpoint, pkt);
if (isReassembled) {
this->decodeNetPacket(netPkt, firstPkt, endpoint);
}
}
catch (const tlv::Error& e) {
++this->nInLpInvalid;
++nInLpInvalid;
NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
}
}
@@ -401,14 +399,14 @@ GenericLinkService::decodeNetPacket(const Block& netPkt, const lp::Packet& first
this->decodeData(netPkt, firstPkt, endpointId);
break;
default:
++this->nInNetInvalid;
++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" << netPkt.type());
++nInNetInvalid;
NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
}
}
@@ -433,7 +431,7 @@ GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstP
}
if (firstPkt.has<lp::CachePolicyField>()) {
++this->nInNetInvalid;
++nInNetInvalid;
NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
return;
}
@@ -456,7 +454,7 @@ GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstP
}
if (firstPkt.has<lp::PrefixAnnouncementField>()) {
++this->nInNetInvalid;
++nInNetInvalid;
NFD_LOG_FACE_WARN("received PrefixAnnouncement with Interest: DROP");
return;
}
@@ -465,8 +463,6 @@ GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstP
interest->setTag(make_shared<lp::PitToken>(firstPkt.get<lp::PitTokenField>()));
}
this->globalSp.receiveInterest(*interest);
this->globalSp.triggerCalObjectRate();
this->receiveInterest(*interest, endpointId);
}
@@ -480,13 +476,13 @@ GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt,
auto data = make_shared<Data>(netPkt);
if (firstPkt.has<lp::NackField>()) {
++this->nInNetInvalid;
++nInNetInvalid;
NFD_LOG_FACE_WARN("received Nack with Data: DROP");
return;
}
if (firstPkt.has<lp::NextHopFaceIdField>()) {
++this->nInNetInvalid;
++nInNetInvalid;
NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
return;
}
@@ -507,7 +503,7 @@ GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt,
}
if (firstPkt.has<lp::NonDiscoveryField>()) {
++this->nInNetInvalid;
++nInNetInvalid;
NFD_LOG_FACE_WARN("received NonDiscovery with Data: DROP");
return;
}
@@ -521,13 +517,6 @@ GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt,
}
}
// 不处理本地命令通信
if (data->getName().getPrefix(1).toUri() != "/localhost") {
// TR = min(TR, OR)
this->globalSp.assignObjectRate(*data);
}
this->globalSp.triggerCalObjectRate();
this->receiveData(*data, endpointId);
}
@@ -542,13 +531,13 @@ GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt,
nack.setHeader(firstPkt.get<lp::NackField>());
if (firstPkt.has<lp::NextHopFaceIdField>()) {
++this->nInNetInvalid;
++nInNetInvalid;
NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
return;
}
if (firstPkt.has<lp::CachePolicyField>()) {
++this->nInNetInvalid;
++nInNetInvalid;
NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
return;
}
@@ -562,13 +551,13 @@ GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt,
}
if (firstPkt.has<lp::NonDiscoveryField>()) {
++this->nInNetInvalid;
++nInNetInvalid;
NFD_LOG_FACE_WARN("received NonDiscovery with Nack: DROP");
return;
}
if (firstPkt.has<lp::PrefixAnnouncementField>()) {
++this->nInNetInvalid;
++nInNetInvalid;
NFD_LOG_FACE_WARN("received PrefixAnnouncement with Nack: DROP");
return;
}
@@ -576,5 +565,4 @@ GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt,
this->receiveNack(nack, endpointId);
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+73 -79
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -32,73 +32,73 @@
#include "lp-reliability.hpp"
#include "queues.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief counters provided by GenericLinkService
* \note The type name 'GenericLinkServiceCounters' is implementation detail.
* Use 'GenericLinkService::Counters' in public API.
/** \brief Counters provided by GenericLinkService.
* \note The type name GenericLinkServiceCounters is an implementation detail.
* Use GenericLinkService::Counters in public API.
*/
class GenericLinkServiceCounters : public virtual LinkService::Counters
{
public:
/** \brief count of failed fragmentations
/** \brief Count of failed fragmentations.
*/
PacketCounter nFragmentationErrors;
/** \brief count of outgoing LpPackets dropped due to exceeding MTU limit
/** \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
/** \brief Count of invalid LpPackets dropped before reassembly.
*/
PacketCounter nInLpInvalid;
/** \brief count of network-layer packets currently being reassembled
/** \brief Count of network-layer packets currently being reassembled.
*/
SizeCounter<LpReassembler> nReassembling;
/** \brief count of dropped partial network-layer packets due to reassembly timeout
/** \brief Count of dropped partial network-layer packets due to reassembly timeout.
*/
PacketCounter nReassemblyTimeouts;
/** \brief count of invalid reassembled network-layer packets dropped
/** \brief Count of invalid reassembled network-layer packets dropped.
*/
PacketCounter nInNetInvalid;
/** \brief count of network-layer packets that did not require retransmission of a fragment
/** \brief Count of network-layer packets that did not require retransmission of a fragment.
*/
PacketCounter nAcknowledged;
/** \brief count of network-layer packets that had at least one fragment retransmitted, but were
* eventually received in full
/** \brief Count of network-layer packets that had at least one fragment retransmitted, but were
* eventually received in full.
*/
PacketCounter nRetransmitted;
/** \brief count of network-layer packets dropped because a fragment reached the maximum number
* of retransmissions
/** \brief Count of network-layer packets dropped because a fragment reached the maximum number
* of retransmissions.
*/
PacketCounter nRetxExhausted;
/** \brief count of LpPackets dropped due to duplicate Sequence numbers
/** \brief Count of LpPackets dropped due to duplicate Sequence numbers.
*/
PacketCounter nDuplicateSequence;
/** \brief count of outgoing LpPackets that were marked with congestion marks
/** \brief Count of outgoing LpPackets that were marked with congestion marks.
*/
PacketCounter nCongestionMarked;
};
/** \brief GenericLinkService is a LinkService that implements the NDNLPv2 protocol
* \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
/**
* \brief GenericLinkService is a LinkService that implements the NDNLPv2 protocol.
* \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
*/
class GenericLinkService FINAL_UNLESS_WITH_TESTS : public LinkService
, protected virtual GenericLinkServiceCounters
class GenericLinkService NFD_FINAL_UNLESS_WITH_TESTS : public LinkService
, protected virtual GenericLinkServiceCounters
{
public:
/** \brief Options that control the behavior of GenericLinkService
/** \brief %Options that control the behavior of GenericLinkService.
*/
class Options
{
@@ -108,35 +108,35 @@ public:
}
public:
/** \brief enables encoding of IncomingFaceId, and decoding of NextHopFaceId and CachePolicy
/** \brief Enables encoding of IncomingFaceId, and decoding of NextHopFaceId and CachePolicy.
*/
bool allowLocalFields = false;
/** \brief enables fragmentation
/** \brief Enables fragmentation.
*/
bool allowFragmentation = false;
/** \brief options for fragmentation
/** \brief Options for fragmentation.
*/
LpFragmenter::Options fragmenterOptions;
/** \brief enables reassembly
/** \brief Enables reassembly.
*/
bool allowReassembly = false;
/** \brief options for reassembly
/** \brief Options for reassembly.
*/
LpReassembler::Options reassemblerOptions;
/** \brief options for reliability
/** \brief Options for reliability.
*/
LpReliability::Options reliabilityOptions;
/** \brief enables send queue congestion detection and marking
/** \brief Enables send queue congestion detection and marking.
*/
bool allowCongestionMarking = false;
/** \brief starting value for congestion marking interval
/** \brief Starting value for congestion marking interval.
*
* Packets are marked if the queue size stays above THRESHOLD for at least one INTERVAL.
*
@@ -144,7 +144,7 @@ public:
*/
time::nanoseconds baseCongestionMarkingInterval = 100_ms;
/** \brief default congestion threshold in bytes
/** \brief Default congestion threshold in bytes.
*
* Packets are marked if the queue size stays above THRESHOLD for at least one INTERVAL.
*
@@ -152,96 +152,102 @@ public:
*/
size_t defaultCongestionThreshold = 65536;
/** \brief enables self-learning forwarding support
/** \brief Enables self-learning forwarding support.
*/
bool allowSelfLearning = true;
/** \brief overrides MTU provided by Transport
/** \brief Overrides the MTU provided by Transport.
*
* This MTU value will be used instead of the MTU provided by the transport if it is less than
* the transport MTU. However, it will not be utilized when the transport MTU is unlimited.
*
* Acceptable values for the override MTU are values >= MIN_MTU, which can be validated before
* Acceptable values for this option are values >= #MIN_MTU, which can be validated before
* being set with canOverrideMtuTo().
*/
ssize_t overrideMtu = std::numeric_limits<ssize_t>::max();
uint64_t C = 100000000; // 100Mbps
uint64_t C = 10000000;
size_t vqSize = 20;
};
/** \brief counters provided by GenericLinkService
/** \brief %Counters provided by GenericLinkService.
*/
using Counters = GenericLinkServiceCounters;
explicit
GenericLinkService(const Options& options = {});
/** \brief get Options used by GenericLinkService
/** \brief Get the options used by GenericLinkService.
*/
const Options&
getOptions() const;
getOptions() const
{
return m_options;
}
/** \brief sets Options used by GenericLinkService
/** \brief Sets the options used by GenericLinkService.
*/
void
setOptions(const Options& options);
const Counters&
getCounters() const OVERRIDE_WITH_TESTS_ELSE_FINAL;
getCounters() const NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL
{
return *this;
}
ssize_t
getEffectiveMtu() const OVERRIDE_WITH_TESTS_ELSE_FINAL;
getEffectiveMtu() const NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL;
/** \brief Whether MTU can be overridden to the specified value
/** \brief Whether MTU can be overridden to the specified value.
*
* If the transport MTU is unlimited, then this will always return false.
*/
bool
canOverrideMtuTo(ssize_t mtu) const;
PROTECTED_WITH_TESTS_ELSE_PRIVATE: // send path
/** \brief request an IDLE packet to transmit pending service fields
NFD_PROTECTED_WITH_TESTS_ELSE_PRIVATE: // send path
/** \brief Request an IDLE packet to transmit pending service fields.
*/
void
requestIdlePacket();
/** \brief send an LpPacket
/** \brief Send an LpPacket.
*/
void
sendLpPacket(lp::Packet&& pkt);
void
doSendInterest(const Interest& interest) OVERRIDE_WITH_TESTS_ELSE_FINAL;
doSendInterest(const Interest& interest) NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL;
void
doSendData(const Data& data) OVERRIDE_WITH_TESTS_ELSE_FINAL;
doSendData(const Data& data) NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL;
void
doSendNack(const ndn::lp::Nack& nack) OVERRIDE_WITH_TESTS_ELSE_FINAL;
doSendNack(const ndn::lp::Nack& nack) NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL;
/** \brief assign consecutive sequence numbers to LpPackets
/** \brief Assign consecutive sequence numbers to LpPackets.
*/
void
assignSequences(std::vector<lp::Packet>& pkts);
private: // send path
/** \brief encode link protocol fields from tags onto an outgoing LpPacket
/** \brief Encode link protocol fields from tags onto an outgoing LpPacket.
* \param netPkt network-layer packet to extract tags from
* \param lpPacket LpPacket to add link protocol fields to
*/
void
encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket);
/** \brief send a complete network layer packet
/** \brief Send a complete network layer packet.
* \param pkt LpPacket containing a complete network layer packet
* \param isInterest whether the network layer packet is an Interest
*/
void
sendNetPacket(lp::Packet&& pkt, bool isInterest);
/** \brief if the send queue is found to be congested, add a congestion mark to the packet
* according to CoDel
/** \brief If the send queue is found to be congested, add a congestion mark to the packet
* according to CoDel.
* \sa https://tools.ietf.org/html/rfc8289
*/
void
@@ -249,9 +255,9 @@ private: // send path
private: // receive path
void
doReceivePacket(const Block& packet, const EndpointId& endpoint) OVERRIDE_WITH_TESTS_ELSE_FINAL;
doReceivePacket(const Block& packet, const EndpointId& endpoint) NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL;
/** \brief decode incoming network-layer packet
/** \brief Decode incoming network-layer packet.
* \param netPkt reassembled network-layer packet
* \param firstPkt LpPacket of first fragment
* \param endpointId endpoint of peer who sent the packet
@@ -262,7 +268,7 @@ private: // receive path
void
decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
/** \brief decode incoming Interest
/** \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
* \param endpointId endpoint of peer who sent the Interest
@@ -275,7 +281,7 @@ private: // receive path
void
decodeInterest(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
/** \brief decode incoming Interest
/** \brief Decode incoming Interest.
* \param netPkt reassembled network-layer packet; TLV-TYPE must be Data
* \param firstPkt LpPacket of first fragment
* \param endpointId endpoint of peer who sent the Data
@@ -288,7 +294,7 @@ private: // receive path
void
decodeData(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
/** \brief decode incoming Interest
/** \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
* \param endpointId endpoint of peer who sent the Nack
@@ -301,38 +307,26 @@ private: // receive path
void
decodeNack(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
PROTECTED_WITH_TESTS_ELSE_PRIVATE:
NFD_PROTECTED_WITH_TESTS_ELSE_PRIVATE:
Options m_options;
LpFragmenter m_fragmenter;
LpReassembler m_reassembler;
LpReliability m_reliability;
lp::Sequence m_lastSeqNo;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/// Time to mark next packet due to send queue congestion
time::steady_clock::TimePoint m_nextMarkTime;
time::steady_clock::time_point m_nextMarkTime;
/// number of marked packets in the current incident of congestion
size_t m_nMarkedSinceInMarkingState;
GlobalSP globalSp;
bool canScheduler = true;
std::function<void(std::shared_ptr<VirtualQueueItem>)> sendPacketCallback;
friend class LpReliability;
friend LpReliability;
};
inline const GenericLinkService::Options&
GenericLinkService::getOptions() const
{
return m_options;
}
inline const GenericLinkService::Counters&
GenericLinkService::getCounters() const
{
return *this;
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_GENERIC_LINK_SERVICE_HPP
+4 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,8 +28,7 @@
#include "internal-transport.hpp"
#include "common/global.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
std::tuple<shared_ptr<Face>, shared_ptr<ndn::Face>>
makeInternalFace(ndn::KeyChain& clientKeyChain)
@@ -46,8 +45,7 @@ makeInternalFace(ndn::KeyChain& clientKeyChain)
auto clientFace = make_shared<ndn::Face>(clientTransport, getGlobalIoService(), clientKeyChain);
return std::make_tuple(face, clientFace);
return {face, clientFace};
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+8 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,16 +27,16 @@
#define NFD_DAEMON_FACE_INTERNAL_FACE_HPP
#include "face.hpp"
#include <ndn-cxx/face.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief make a pair of forwarder-side face and client-side face
* that are connected with each other
/** \brief Make a pair of forwarder-side face and client-side face
* that are connected to each other.
*
* Network-layer packets sent by one face will be received by the other face
* after io.poll().
* after `io.poll()`.
*
* \param clientKeyChain A KeyChain used by client-side face to sign
* prefix registration commands.
@@ -45,7 +45,6 @@ namespace face {
std::tuple<shared_ptr<Face>, shared_ptr<ndn::Face>>
makeInternalFace(ndn::KeyChain& clientKeyChain);
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_INTERNAL_FACE_HPP
+7 -17
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,8 +26,9 @@
#include "internal-transport.hpp"
#include "common/global.hpp"
namespace nfd {
namespace face {
#include <boost/asio/post.hpp>
namespace nfd::face {
NFD_LOG_MEMBER_INIT(InternalForwarderTransport, InternalForwarderTransport);
NFD_LOG_MEMBER_INIT(InternalClientTransport, InternalClientTransport);
@@ -48,7 +49,7 @@ InternalForwarderTransport::InternalForwarderTransport(const FaceUri& localUri,
void
InternalForwarderTransport::receivePacket(const Block& packet)
{
getGlobalIoService().post([this, packet] {
boost::asio::post(getGlobalIoService(), [this, packet] {
NFD_LOG_FACE_TRACE("Received: " << packet.size() << " bytes");
receive(packet);
});
@@ -106,7 +107,7 @@ InternalClientTransport::connectToForwarder(InternalForwarderTransport* forwarde
void
InternalClientTransport::receivePacket(const Block& packet)
{
getGlobalIoService().post([this, packet] {
boost::asio::post(getGlobalIoService(), [this, packet] {
NFD_LOG_TRACE("Received: " << packet.size() << " bytes");
if (m_receiveCallback) {
m_receiveCallback(packet);
@@ -123,15 +124,4 @@ InternalClientTransport::send(const Block& wire)
m_forwarder->receivePacket(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());
send(encoder.block());
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+14 -16
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -30,22 +30,23 @@
#include <ndn-cxx/transport/transport.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief Abstracts a transport that can be paired with another.
/**
* \brief Abstracts a transport that can be paired with another.
*/
class InternalTransportBase
{
public:
virtual
~InternalTransportBase() = default;
virtual void
receivePacket(const Block& packet) = 0;
protected:
~InternalTransportBase() = default;
};
/** \brief Implements a forwarder-side transport that can be paired with another transport.
/**
* \brief Implements a forwarder-side transport that can be paired with another transport.
*/
class InternalForwarderTransport final : public Transport, public InternalTransportBase
{
@@ -57,7 +58,7 @@ public:
ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_POINT_TO_POINT);
void
setPeer(InternalTransportBase* peer)
setPeer(InternalTransportBase* peer) noexcept
{
m_peer = peer;
}
@@ -79,7 +80,8 @@ private:
InternalTransportBase* m_peer = nullptr;
};
/** \brief Implements a client-side transport that can be paired with an InternalForwarderTransport.
/**
* \brief Implements a client-side transport that can be paired with an InternalForwarderTransport.
*/
class InternalClientTransport final : public ndn::Transport, public InternalTransportBase
{
@@ -101,10 +103,7 @@ public:
receivePacket(const Block& packet) final;
void
send(const Block& wire) final;
void
send(const Block& header, const Block& payload) final;
send(const Block& block) final;
void
close() final
@@ -128,7 +127,6 @@ private:
signal::ScopedConnection m_fwTransportStateConn;
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_INTERNAL_TRANSPORT_HPP
+5 -15
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,23 +26,14 @@
#include "link-service.hpp"
#include "face.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_INIT(LinkService);
LinkService::LinkService()
: m_face(nullptr)
, m_transport(nullptr)
{
}
LinkService::~LinkService()
{
}
LinkService::~LinkService() = default;
void
LinkService::setFaceAndTransport(Face& face, Transport& transport)
LinkService::setFaceAndTransport(Face& face, Transport& transport) noexcept
{
BOOST_ASSERT(m_face == nullptr);
BOOST_ASSERT(m_transport == nullptr);
@@ -135,5 +126,4 @@ operator<<(std::ostream& os, const FaceLogHelper<LinkService>& flh)
return os;
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+67 -77
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -30,147 +30,162 @@
#include "transport.hpp"
#include "common/counter.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief counters provided by LinkService
* \note The type name 'LinkServiceCounters' is implementation detail.
* Use 'LinkService::Counters' in public API.
/** \brief Counters provided by LinkService.
* \note The type name LinkServiceCounters is an implementation detail.
* Use LinkService::Counters in public API.
*/
class LinkServiceCounters
{
public:
/** \brief count of incoming Interests
/** \brief Count of incoming Interests.
*/
PacketCounter nInInterests;
/** \brief count of outgoing Interests
/** \brief Count of outgoing Interests.
*/
PacketCounter nOutInterests;
/** \brief count of Interests dropped by reliability system for exceeding allowed number of retx
/** \brief Count of Interests dropped by reliability system for exceeding allowed number of retx.
*/
PacketCounter nInterestsExceededRetx;
/** \brief count of incoming Data packets
/** \brief Count of incoming Data packets.
*/
PacketCounter nInData;
/** \brief count of outgoing Data packets
/** \brief Count of outgoing Data packets.
*/
PacketCounter nOutData;
/** \brief count of incoming Nacks
/** \brief Count of incoming Nacks.
*/
PacketCounter nInNacks;
/** \brief count of outgoing Nacks
/** \brief Count of outgoing Nacks.
*/
PacketCounter nOutNacks;
};
/** \brief the upper part of a Face
* \sa Face
/**
* \brief The upper half of a Face.
* \sa Face, Transport
*/
class LinkService : protected virtual LinkServiceCounters, noncopyable
{
public:
/** \brief counters provided by LinkService
/**
* \brief %Counters provided by LinkService.
*/
typedef LinkServiceCounters Counters;
using Counters = LinkServiceCounters;
public:
LinkService();
virtual
~LinkService();
/** \brief set Face and Transport for LinkService
* \pre setFaceAndTransport has not been called
/**
* \brief Set Face and Transport for this LinkService.
* \pre setFaceAndTransport() has not been called.
*/
void
setFaceAndTransport(Face& face, Transport& transport);
setFaceAndTransport(Face& face, Transport& transport) noexcept;
/** \return Face to which this LinkService is attached
/**
* \brief Returns the Face to which this LinkService is attached.
*/
const Face*
getFace() const;
getFace() const noexcept
{
return m_face;
}
/** \return Transport to which this LinkService is attached
/**
* \brief Returns the Transport to which this LinkService is attached.
*/
const Transport*
getTransport() const;
getTransport() const noexcept
{
return m_transport;
}
/** \return Transport to which this LinkService is attached
/**
* \brief Returns the Transport to which this LinkService is attached.
*/
Transport*
getTransport();
getTransport() noexcept
{
return m_transport;
}
virtual const Counters&
getCounters() const;
getCounters() const
{
return *this;
}
virtual ssize_t
getEffectiveMtu() const;
public: // upper interface to be used by forwarding
/** \brief Send Interest
* \pre setTransport has been called
/** \brief Send Interest.
* \pre setFaceAndTransport() has been called.
*/
void
sendInterest(const Interest& interest);
/** \brief Send Data
* \pre setTransport has been called
/** \brief Send Data.
* \pre setFaceAndTransport() has been called.
*/
void
sendData(const Data& data);
/** \brief Send Nack
* \pre setTransport has been called
/** \brief Send Nack.
* \pre setFaceAndTransport() has been called.
*/
void
sendNack(const ndn::lp::Nack& nack);
/** \brief signals on Interest received
/** \brief Signals on Interest received.
*/
signal::Signal<LinkService, Interest, EndpointId> afterReceiveInterest;
/** \brief signals on Data received
/** \brief Signals on Data received.
*/
signal::Signal<LinkService, Data, EndpointId> afterReceiveData;
/** \brief signals on Nack received
/** \brief Signals on Nack received.
*/
signal::Signal<LinkService, lp::Nack, EndpointId> afterReceiveNack;
/** \brief signals on Interest dropped by reliability system for exceeding allowed number of retx
/** \brief Signals on Interest dropped by reliability system for exceeding allowed number of retx.
*/
signal::Signal<LinkService, Interest> onDroppedInterest;
public: // lower interface to be invoked by Transport
/** \brief performs LinkService specific operations to receive a lower-layer packet
/** \brief Performs LinkService specific operations to receive a lower-layer packet.
*/
void
receivePacket(const Block& packet, const EndpointId& endpoint);
protected: // upper interface to be invoked in subclass (receive path termination)
/** \brief delivers received Interest to forwarding
/** \brief Delivers received Interest to forwarding.
*/
void
receiveInterest(const Interest& interest, const EndpointId& endpoint);
/** \brief delivers received Data to forwarding
/** \brief Delivers received Data to forwarding.
*/
void
receiveData(const Data& data, const EndpointId& endpoint);
/** \brief delivers received Nack to forwarding
/** \brief Delivers received Nack to forwarding.
*/
void
receiveNack(const lp::Nack& nack, const EndpointId& endpoint);
protected: // lower interface to be invoked in subclass (send path termination)
/** \brief send a lower-layer packet via Transport
/** \brief Send a lower-layer packet via Transport.
*/
void
sendPacket(const Block& packet);
@@ -180,17 +195,17 @@ protected:
notifyDroppedInterest(const Interest& packet);
private: // upper interface to be overridden in subclass (send path entrypoint)
/** \brief performs LinkService specific operations to send an Interest
/** \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
/** \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
/** \brief Performs LinkService specific operations to send a Nack.
*/
virtual void
doSendNack(const lp::Nack& nack) = 0;
@@ -200,34 +215,10 @@ private: // lower interface to be overridden in subclass
doReceivePacket(const Block& packet, const EndpointId& endpoint) = 0;
private:
Face* m_face;
Transport* m_transport;
Face* m_face = nullptr;
Transport* m_transport = nullptr;
};
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 ssize_t
LinkService::getEffectiveMtu() const
{
@@ -250,14 +241,13 @@ 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
std::enable_if_t<std::is_base_of_v<LinkService, T> && !std::is_same_v<LinkService, T>,
std::ostream&>
operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
{
return os << FaceLogHelper<LinkService>(flh.obj);
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_LINK_SERVICE_HPP
+17 -20
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2018, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,10 +26,9 @@
#include "lp-fragmenter.hpp"
#include "link-service.hpp"
#include <ndn-cxx/encoding/tlv.hpp>
#include <ndn-cxx/lp/fields.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_INIT(LpFragmenter);
@@ -39,18 +38,18 @@ 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
/**
* \brief Maximum overhead on a single fragment, not counting other NDNLPv2 headers.
*/
static const size_t MAX_SINGLE_FRAG_OVERHEAD =
constexpr 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
/**
* \brief Maximum overhead of adding fragmentation to payload, not counting other NDNLPv2 headers.
*/
static const size_t MAX_FRAG_OVERHEAD =
constexpr size_t MAX_FRAG_OVERHEAD =
1 + 9 + // LpPacket TLV-TYPE and TLV-LENGTH
1 + 1 + 8 + // Sequence TLV
1 + 1 + 8 + // FragIndex TLV
@@ -86,18 +85,17 @@ LpFragmenter::fragmentPacket(const lp::Packet& packet, size_t 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});
return {true, {packet}};
}
ndn::Buffer::const_iterator netPktBegin, netPktEnd;
std::tie(netPktBegin, netPktEnd) = packet.get<lp::FragmentField>();
auto [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();
const auto& packetWire = packet.wireEncode();
if (packetWire.type() == lp::tlv::LpPacket) {
for (const Block& element : packetWire.elements()) {
for (const auto& element : packetWire.elements()) {
if (element.type() != lp::tlv::Fragment) {
firstHeaderSize += element.size();
}
@@ -107,7 +105,7 @@ LpFragmenter::fragmentPacket(const lp::Packet& packet, size_t mtu)
// 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>{});
return {false, {}};
}
size_t firstPayloadSize = std::min(netPktSize, mtu - firstHeaderSize - MAX_FRAG_OVERHEAD);
size_t payloadSize = mtu - MAX_FRAG_OVERHEAD;
@@ -117,7 +115,7 @@ LpFragmenter::fragmentPacket(const lp::Packet& packet, size_t mtu)
// compute FragCount
if (fragCount > m_options.nMaxFragments) {
NFD_LOG_FACE_WARN("fragmentation error, FragCount over limit: DROP");
return std::make_tuple(false, std::vector<lp::Packet>{});
return {false, {}};
}
// populate fragments
@@ -139,7 +137,7 @@ LpFragmenter::fragmentPacket(const lp::Packet& packet, size_t mtu)
}
BOOST_ASSERT(fragIndex == fragCount);
return std::make_tuple(true, frags);
return {true, frags};
}
std::ostream&
@@ -154,5 +152,4 @@ operator<<(std::ostream& os, const FaceLogHelper<LpFragmenter>& flh)
return os;
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+8 -10
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -30,20 +30,19 @@
#include <ndn-cxx/lp/packet.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief fragments network-layer packets into NDNLPv2 link-layer packets
/** \brief Fragments network-layer packets into NDNLPv2 link-layer packets.
* \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
*/
class LpFragmenter
{
public:
/** \brief Options that control the behavior of LpFragmenter
/** \brief %Options that control the behavior of LpFragmenter.
*/
struct Options
{
/** \brief maximum number of fragments in a packet
/** \brief Maximum number of fragments in a packet.
*/
size_t nMaxFragments = 400;
};
@@ -51,7 +50,7 @@ public:
explicit
LpFragmenter(const Options& options, const LinkService* linkService = nullptr);
/** \brief set options for fragmenter
/** \brief Set options for fragmenter.
*/
void
setOptions(const Options& options);
@@ -63,7 +62,7 @@ public:
const LinkService*
getLinkService() const;
/** \brief fragments a network-layer packet into link-layer packets
/** \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
@@ -80,7 +79,6 @@ private:
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<LpFragmenter>& flh);
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_LP_FRAGMENTER_HPP
+22 -28
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,13 +24,14 @@
*/
#include "lp-reassembler.hpp"
#include "link-service.hpp"
#include "common/global.hpp"
#include "link-service.hpp"
#include <ndn-cxx/lp/fields.hpp>
#include <numeric>
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_INIT(LpReassembler);
@@ -41,12 +42,10 @@ LpReassembler::LpReassembler(const LpReassembler::Options& options, const LinkSe
}
std::tuple<bool, Block, lp::Packet>
LpReassembler::receiveFragment(EndpointId remoteEndpoint, const lp::Packet& packet)
LpReassembler::receiveFragment(const 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;
@@ -59,29 +58,29 @@ LpReassembler::receiveFragment(EndpointId remoteEndpoint, const lp::Packet& pack
if (fragIndex >= fragCount) {
NFD_LOG_FACE_WARN("reassembly error, FragIndex>=FragCount: DROP");
return FALSE_RETURN;
return {false, {}, {}};
}
if (fragCount > m_options.nMaxFragments) {
NFD_LOG_FACE_WARN("reassembly error, FragCount over limit: DROP");
return FALSE_RETURN;
return {false, {}, {}};
}
// 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);
auto frag = packet.get<lp::FragmentField>();
Block netPkt({frag.first, frag.second});
return {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;
return {false, {}, {}};
}
lp::Sequence messageIdentifier = packet.get<lp::SequenceField>() - fragIndex;
Key key = std::make_tuple(remoteEndpoint, messageIdentifier);
Key key(remoteEndpoint, messageIdentifier);
// add to PartialPacket
PartialPacket& pp = m_partialPackets[key];
@@ -93,13 +92,13 @@ LpReassembler::receiveFragment(EndpointId remoteEndpoint, const lp::Packet& pack
else {
if (fragCount != pp.fragCount) {
NFD_LOG_FACE_WARN("reassembly error, FragCount changed: DROP");
return FALSE_RETURN;
return {false, {}, {}};
}
}
if (pp.fragments[fragIndex].has<lp::SequenceField>()) {
NFD_LOG_FACE_TRACE("fragment already received: DROP");
return FALSE_RETURN;
return {false, {}, {}};
}
pp.fragments[fragIndex] = packet;
@@ -110,13 +109,13 @@ LpReassembler::receiveFragment(EndpointId remoteEndpoint, const lp::Packet& pack
Block reassembled = doReassembly(key);
lp::Packet firstFrag(std::move(pp.fragments[0]));
m_partialPackets.erase(key);
return std::make_tuple(true, reassembled, firstFrag);
return {true, reassembled, firstFrag};
}
// set drop timer
pp.dropTimer = getScheduler().schedule(m_options.reassemblyTimeout, [=] { timeoutPartialPacket(key); });
return FALSE_RETURN;
return {false, {}, {}};
}
Block
@@ -126,21 +125,17 @@ LpReassembler::doReassembly(const Key& key)
size_t payloadSize = std::accumulate(pp.fragments.begin(), pp.fragments.end(), 0U,
[&] (size_t sum, const lp::Packet& pkt) -> size_t {
ndn::Buffer::const_iterator fragBegin, fragEnd;
std::tie(fragBegin, fragEnd) = pkt.get<lp::FragmentField>();
auto [fragBegin, fragEnd] = pkt.get<lp::FragmentField>();
return sum + std::distance(fragBegin, fragEnd);
});
ndn::Buffer fragBuffer(payloadSize);
auto it = fragBuffer.begin();
for (const lp::Packet& frag : pp.fragments) {
ndn::Buffer::const_iterator fragBegin, fragEnd;
std::tie(fragBegin, fragEnd) = frag.get<lp::FragmentField>();
auto [fragBegin, fragEnd] = frag.get<lp::FragmentField>();
it = std::copy(fragBegin, fragEnd, it);
}
return Block(&*(fragBuffer.cbegin()), std::distance(fragBuffer.cbegin(), fragBuffer.cend()));
return Block(fragBuffer);
}
void
@@ -167,5 +162,4 @@ operator<<(std::ostream& os, const FaceLogHelper<LpReassembler>& flh)
return os;
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+28 -25
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,27 +29,28 @@
#include "face-common.hpp"
#include <ndn-cxx/lp/packet.hpp>
#include <ndn-cxx/lp/sequence.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief reassembles fragmented network-layer packets
* \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
/**
* \brief Reassembles fragmented network-layer packets.
* \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
*/
class LpReassembler : noncopyable
{
public:
/** \brief Options that control the behavior of LpReassembler
/** \brief %Options that control the behavior of LpReassembler.
*/
struct Options
{
/** \brief maximum number of fragments in a packet
/** \brief Maximum number of fragments in a packet.
*
* LpPackets with FragCount over this limit are dropped.
*/
size_t nMaxFragments = 400;
/** \brief timeout before a partially reassembled packet is dropped
/** \brief Timeout before a partially reassembled packet is dropped.
*/
time::nanoseconds reassemblyTimeout = 500_ms;
};
@@ -57,7 +58,7 @@ public:
explicit
LpReassembler(const Options& options, const LinkService* linkService = nullptr);
/** \brief set options for reassembler
/** \brief Set options for reassembler.
*/
void
setOptions(const Options& options);
@@ -69,7 +70,7 @@ public:
const LinkService*
getLinkService() const;
/** \brief adds received fragment to the buffer
/** \brief Adds received fragment to the buffer.
* \param remoteEndpoint endpoint that sent the packet
* \param packet received fragment; must have Fragment field
* \return a tuple containing:
@@ -79,24 +80,26 @@ public:
* \throw tlv::Error packet is malformed
*/
std::tuple<bool, Block, lp::Packet>
receiveFragment(EndpointId remoteEndpoint, const lp::Packet& packet);
receiveFragment(const EndpointId& remoteEndpoint, const lp::Packet& packet);
/** \brief count of partial packets
/** \brief Count of partial packets.
*/
size_t
size() const;
/** \brief signals before a partial packet is dropped due to timeout
/**
* \brief Notifies 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.
* If a partial packet is incomplete and no new fragments are received within
* Options::reassemblyTimeout, the partial packet is dropped due to timeout.
* Before dropping the packet, this signal is emitted with the remote endpoint
* and the number of fragments being dropped.
*/
signal::Signal<LpReassembler, EndpointId, size_t> beforeTimeout;
private:
/** \brief holds all fragments of packet until reassembled
/**
* \brief Holds all fragments of a packet until reassembled.
*/
struct PartialPacket
{
@@ -106,12 +109,13 @@ private:
scheduler::ScopedEventId dropTimer;
};
/** \brief index key for PartialPackets
/**
* \brief Index key for PartialPackets.
*/
typedef std::tuple<
EndpointId, // remoteEndpoint
lp::Sequence // message identifier (sequence of the first fragment)
> Key;
using Key = std::tuple<
EndpointId, // remote endpoint
lp::Sequence // message identifier (sequence number of the first fragment)
>;
Block
doReassembly(const Key& key);
@@ -146,7 +150,6 @@ LpReassembler::size() const
return m_partialPackets.size();
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_LP_REASSEMBLER_HPP
+16 -24
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,12 +24,13 @@
*/
#include "lp-reliability.hpp"
#include "common/global.hpp"
#include "generic-link-service.hpp"
#include "transport.hpp"
#include "common/global.hpp"
namespace nfd {
namespace face {
#include <ndn-cxx/lp/fields.hpp>
namespace nfd::face {
NFD_LOG_INIT(LpReliability);
@@ -80,10 +81,7 @@ LpReliability::handleOutgoing(std::vector<lp::Packet>& frags, lp::Packet&& pkt,
lp::Sequence txSeq = assignTxSequence(frag);
// Store LpPacket for future retransmissions
unackedFragsIt = m_unackedFrags.emplace_hint(unackedFragsIt,
std::piecewise_construct,
std::forward_as_tuple(txSeq),
std::forward_as_tuple(frag));
unackedFragsIt = m_unackedFrags.try_emplace(unackedFragsIt, txSeq, frag);
unackedFragsIt->second.sendTime = sendTime;
auto rto = m_rttEst.getEstimatedRto();
lp::Sequence seq = frag.get<lp::SequenceField>();
@@ -174,12 +172,12 @@ LpReliability::processIncomingPacket(const lp::Packet& pkt)
// Check for recent received Sequences to remove
auto now = time::steady_clock::now();
auto rto = m_rttEst.getEstimatedRto();
while (m_recentRecvSeqsQueue.size() > 0 &&
while (!m_recentRecvSeqsQueue.empty() &&
now > m_recentRecvSeqs[m_recentRecvSeqsQueue.front()] + rto) {
m_recentRecvSeqs.erase(m_recentRecvSeqsQueue.front());
m_recentRecvSeqsQueue.pop();
}
m_recentRecvSeqs.emplace(pktSequence, now);
m_recentRecvSeqs.try_emplace(pktSequence, now);
m_recentRecvSeqsQueue.push(pktSequence);
}
@@ -226,7 +224,7 @@ LpReliability::assignTxSequence(lp::Packet& frag)
{
lp::Sequence txSeq = ++m_lastTxSeqNo;
frag.set<lp::TxSequenceField>(txSeq);
if (m_unackedFrags.size() > 0 && m_lastTxSeqNo == m_firstUnackedFrag->first) {
if (!m_unackedFrags.empty() && m_lastTxSeqNo == m_firstUnackedFrag->first) {
NDN_THROW(std::length_error("TxSequence range exceeded"));
}
return m_lastTxSeqNo;
@@ -310,10 +308,8 @@ LpReliability::onLpPacketLost(lp::Sequence txSeq, bool isTimeout)
// Notify strategy of dropped Interest (if any)
if (netPkt->isInterest) {
BOOST_ASSERT(netPkt->pkt.has<lp::FragmentField>());
ndn::Buffer::const_iterator fragBegin, fragEnd;
std::tie(fragBegin, fragEnd) = netPkt->pkt.get<lp::FragmentField>();
Block frag(&*fragBegin, std::distance(fragBegin, fragEnd));
onDroppedInterest(Interest(frag));
auto frag = netPkt->pkt.get<lp::FragmentField>();
onDroppedInterest(Interest(Block({frag.first, frag.second})));
}
// Delete this LpPacket from m_unackedFrags
@@ -326,13 +322,10 @@ LpReliability::onLpPacketLost(lp::Sequence txSeq, bool isTimeout)
netPkt->didRetx = true;
// Move fragment to new TxSequence mapping
auto newTxFragIt = m_unackedFrags.emplace_hint(
m_firstUnackedFrag != m_unackedFrags.end() && m_firstUnackedFrag->first > newTxSeq
? m_firstUnackedFrag
: m_unackedFrags.end(),
std::piecewise_construct,
std::forward_as_tuple(newTxSeq),
std::forward_as_tuple(txFrag.pkt));
auto hint = m_firstUnackedFrag != m_unackedFrags.end() && m_firstUnackedFrag->first > newTxSeq
? m_firstUnackedFrag
: m_unackedFrags.end();
auto newTxFragIt = m_unackedFrags.try_emplace(hint, newTxSeq, txFrag.pkt);
auto& newTxFrag = newTxFragIt->second;
newTxFrag.retxCount = txFrag.retxCount + 1;
newTxFrag.netPkt = netPkt;
@@ -434,5 +427,4 @@ operator<<(std::ostream& os, const FaceLogHelper<LpReliability>& flh)
return os;
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+42 -45
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -34,44 +34,49 @@
#include <queue>
namespace nfd {
namespace face {
namespace nfd::face {
class GenericLinkService;
/** \brief provides for reliable sending and receiving of link-layer packets
* \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
/**
* \brief Provides for reliable sending and receiving of link-layer packets.
* \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
*/
class LpReliability : noncopyable
{
public:
/// TxSequence TLV-TYPE (3 octets) + TLV-LENGTH (1 octet) + lp::Sequence (8 octets)
static constexpr size_t RESERVED_HEADER_SPACE = tlv::sizeOfVarNumber(lp::tlv::TxSequence) +
tlv::sizeOfVarNumber(sizeof(lp::Sequence)) +
sizeof(lp::Sequence);
struct Options
{
/** \brief enables link-layer reliability
/** \brief Enables link-layer reliability.
*/
bool isEnabled = false;
/** \brief maximum number of retransmissions for an LpPacket
/** \brief Maximum number of retransmissions for an LpPacket.
*/
size_t maxRetx = 3;
/** \brief period between sending pending Acks in an IDLE packet
/** \brief Period between sending pending Acks in an IDLE packet.
*/
time::nanoseconds idleAckTimerPeriod = 5_ms;
/** \brief a fragment is considered lost if this number of fragments with greater sequence
* numbers are acknowledged
/** \brief A fragment is considered lost if this number of fragments with greater sequence
* numbers are acknowledged.
*/
size_t seqNumLossThreshold = 3;
};
LpReliability(const Options& options, GenericLinkService* linkService);
/** \brief signals on Interest dropped by reliability system for exceeding allowed number of retx
/** \brief Signals on Interest dropped by reliability system for exceeding allowed number of retx.
*/
signal::Signal<LpReliability, Interest> onDroppedInterest;
/** \brief set options for reliability
/** \brief Set options for reliability.
*/
void
setOptions(const Options& options);
@@ -83,7 +88,7 @@ public:
const GenericLinkService*
getLinkService() const;
/** \brief observe outgoing fragment(s) of a network packet and store for potential retransmission
/** \brief Observe outgoing fragment(s) of a network packet and store for potential retransmission.
* \param frags fragments of network packet
* \param pkt encapsulated network packet
* \param isInterest whether the network packet is an Interest
@@ -91,27 +96,26 @@ public:
void
handleOutgoing(std::vector<lp::Packet>& frags, lp::Packet&& pkt, bool isInterest);
/** \brief extract and parse all Acks and add Ack for contained Fragment (if any) to AckQueue
/** \brief Extract and parse all Acks and add Ack for contained Fragment (if any) to AckQueue.
* \param pkt incoming LpPacket
* \return whether incoming LpPacket is new and not a duplicate
*/
bool
processIncomingPacket(const lp::Packet& pkt);
/** \brief called by GenericLinkService to attach Acks onto an outgoing LpPacket
/** \brief Called by GenericLinkService to attach Acks onto an outgoing LpPacket.
* \param pkt outgoing LpPacket to attach Acks to
* \param mtu MTU of the Transport
* \param mtu MTU of the transport
*/
void
piggyback(lp::Packet& pkt, ssize_t mtu);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
class UnackedFrag;
class NetPkt;
using UnackedFrags = std::map<lp::Sequence, UnackedFrag>;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/** \brief assign TxSequence number to a fragment
/** \brief Assign TxSequence number to a fragment.
* \param frag fragment to assign TxSequence to
* \return assigned TxSequence number
* \throw std::length_error assigned TxSequence is equal to the start of the existing window
@@ -119,7 +123,7 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
lp::Sequence
assignTxSequence(lp::Packet& frag);
/** \brief start the idle Ack timer
/** \brief Start the idle Ack timer.
*
* This timer requests an IDLE packet to acknowledge pending fragments not already piggybacked.
* It is called regularly on a period configured in Options::idleAckTimerPeriod. This allows Acks
@@ -128,22 +132,22 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
void
startIdleAckTimer();
/** \brief find and mark as lost fragments where a configurable number of Acks
* (\p m_options.seqNumLossThreshold) have been received for greater TxSequence numbers
/** \brief Find and mark as lost fragments where a configurable number of Acks
* (Options::seqNumLossThreshold) have been received for greater TxSequence numbers.
* \param ackIt iterator pointing to acknowledged fragment
* \return vector containing TxSequences of fragments marked lost by this mechanism
*/
std::vector<lp::Sequence>
findLostLpPackets(UnackedFrags::iterator ackIt);
/** \brief resend (or give up on) a lost fragment
/** \brief Resend (or give up on) a lost fragment.
* \return vector of the TxSequences of fragments removed due to a network packet being removed
*/
std::vector<lp::Sequence>
onLpPacketLost(lp::Sequence txSeq, bool isTimeout);
/** \brief remove the fragment with the given sequence number from the map of unacknowledged
* fragments, as well as its associated network packet (if any)
/** \brief Remove the fragment with the given sequence number from the map of unacknowledged
* fragments, as well as its associated network packet (if any).
* \param fragIt iterator to acknowledged fragment
*
* If the given TxSequence marks the beginning of the send window, the window will be incremented.
@@ -152,7 +156,7 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
void
onLpPacketAcknowledged(UnackedFrags::iterator fragIt);
/** \brief delete a fragment from UnackedFrags and advance acknowledge window if necessary
/** \brief Delete a fragment from UnackedFrags and advance acknowledge window if necessary.
* \param fragIt iterator to an UnackedFrag, must be dereferencable
* \post fragIt is not in m_unackedFrags
* \post if was equal to m_firstUnackedFrag,
@@ -162,8 +166,9 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
void
deleteUnackedFrag(UnackedFrags::iterator fragIt);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/** \brief contains a sent fragment that has not been acknowledged and associated data
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/**
* \brief Contains a sent fragment that has not been acknowledged and associated data.
*/
class UnackedFrag
{
@@ -174,13 +179,14 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
public:
lp::Packet pkt;
scheduler::ScopedEventId rtoTimer;
time::steady_clock::TimePoint sendTime;
time::steady_clock::time_point sendTime;
size_t retxCount;
size_t nGreaterSeqAcks; //!< number of Acks received for sequences greater than this fragment
shared_ptr<NetPkt> netPkt;
};
/** \brief contains a network-layer packet with unacknowledged fragments
/**
* \brief Contains a network-layer packet with unacknowledged fragments.
*/
class NetPkt
{
@@ -194,24 +200,16 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
bool didRetx;
};
public:
/// TxSequence TLV-TYPE (3 octets) + TLV-LENGTH (1 octet) + lp::Sequence (8 octets)
static constexpr size_t RESERVED_HEADER_SPACE = tlv::sizeOfVarNumber(lp::tlv::TxSequence) +
tlv::sizeOfVarNumber(sizeof(lp::Sequence)) +
sizeof(lp::Sequence);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Options m_options;
GenericLinkService* m_linkService;
UnackedFrags m_unackedFrags;
/** An iterator that points to the first unacknowledged fragment in the current window. The window
* can wrap around so that the beginning of the window is at a TxSequence greater than other
* fragments in the window. When the window is moved past the last item in the iterator, the
* first fragment in the map will become the start of the window.
*/
// An iterator that points to the first unacknowledged fragment in the current window. The window
// can wrap around so that the beginning of the window is at a TxSequence greater than other
// fragments in the window. When the window is moved past the last item in the iterator, the
// first fragment in the map will become the start of the window.
UnackedFrags::iterator m_firstUnackedFrag;
std::queue<lp::Sequence> m_ackQueue;
std::map<lp::Sequence, time::steady_clock::TimePoint> m_recentRecvSeqs;
std::map<lp::Sequence, time::steady_clock::time_point> m_recentRecvSeqs;
std::queue<lp::Sequence> m_recentRecvSeqsQueue;
lp::Sequence m_lastTxSeqNo;
scheduler::ScopedEventId m_idleAckTimer;
@@ -221,7 +219,6 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<LpReliability>& flh);
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_LP_RELIABILITY_HPP
+14 -18
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,9 +27,9 @@
#include "common/global.hpp"
#include <cerrno> // for errno
#include <cstdio> // for snprintf()
#include <cstring> // for memcpy(), strerror(), strncpy()
#include <net/if.h> // for struct ifreq
#include <stdio.h> // for snprintf()
#include <sys/ioctl.h> // for ioctl()
#if defined(__linux__)
@@ -43,8 +43,7 @@
#endif
#endif
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_INIT(MulticastEthernetTransport);
@@ -66,20 +65,19 @@ MulticastEthernetTransport::MulticastEthernetTransport(const ndn::net::NetworkIn
NFD_LOG_FACE_DEBUG("Creating transport");
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().data(),
m_srcAddress.toString().data());
// Note: "not vlan" must appear last in the filter expression, or the
// rest of the filter won't work as intended (see pcap-filter(7))
std::snprintf(filter, sizeof(filter),
"(ether proto 0x%x) && (ether dst %s) && (not ether src %s) && (not vlan)",
ethernet::ETHERTYPE_NDN,
m_destAddress.toString().data(),
m_srcAddress.toString().data());
m_pcap.setPacketFilter(filter);
BOOST_ASSERT(m_destAddress.isMulticast());
if (!m_destAddress.isBroadcast())
if (!m_destAddress.isBroadcast()) {
joinMulticastGroup();
}
}
void
@@ -105,8 +103,7 @@ MulticastEthernetTransport::joinMulticastGroup()
#if defined(__APPLE__) || defined(__FreeBSD__)
// see bug #2327
using boost::asio::ip::udp;
udp::socket sock(getGlobalIoService(), udp::v4());
boost::asio::ip::udp::socket sock(getGlobalIoService(), boost::asio::ip::udp::v4());
int fd = sock.native_handle();
// Differences between Linux and the BSDs (including macOS):
@@ -147,5 +144,4 @@ MulticastEthernetTransport::joinMulticastGroup()
NDN_THROW(Error("Failed to join multicast group"));
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+6 -8
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,17 +28,16 @@
#include "ethernet-transport.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
/**
* @brief A multicast Transport that uses raw Ethernet II frames
* @brief A multicast Transport that uses raw Ethernet II frames.
*/
class MulticastEthernetTransport final : public EthernetTransport
{
public:
/**
* @brief Creates an Ethernet-based transport for multicast communication
* @brief Creates an Ethernet-based transport for multicast communication.
*/
MulticastEthernetTransport(const ndn::net::NetworkInterface& localEndpoint,
const ethernet::Address& mcastAddress,
@@ -46,7 +45,7 @@ public:
private:
/**
* @brief Enables receiving frames addressed to our MAC multicast group
* @brief Enables receiving frames addressed to our MAC multicast group.
*/
void
joinMulticastGroup();
@@ -57,7 +56,6 @@ private:
#endif
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_MULTICAST_ETHERNET_TRANSPORT_HPP
+30 -54
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,7 +29,8 @@
#include "common/privilege-helper.hpp"
#include <boost/functional/hash.hpp>
#include <boost/asio/ip/multicast.hpp>
#include <boost/asio/ip/v6_only.hpp>
#ifdef __linux__
#include <cerrno> // for errno
@@ -37,14 +38,15 @@
#include <sys/socket.h> // for setsockopt()
#endif // __linux__
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_MEMBER_INIT_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Multicast>), MulticastUdpTransport);
namespace ip = boost::asio::ip;
MulticastUdpTransport::MulticastUdpTransport(const protocol::endpoint& multicastGroup,
protocol::socket&& recvSocket,
protocol::socket&& sendSocket,
NFD_LOG_MEMBER_INIT_SPECIALIZED((DatagramTransport<ip::udp, Multicast>), MulticastUdpTransport);
MulticastUdpTransport::MulticastUdpTransport(const ip::udp::endpoint& multicastGroup,
ip::udp::socket&& recvSocket,
ip::udp::socket&& sendSocket,
ndn::nfd::LinkType linkType)
: DatagramTransport(std::move(recvSocket))
, m_multicastGroup(multicastGroup)
@@ -57,7 +59,7 @@ MulticastUdpTransport::MulticastUdpTransport(const protocol::endpoint& multicast
this->setLinkType(linkType);
this->setMtu(udp::computeMtu(m_sendSocket.local_endpoint()));
protocol::socket::send_buffer_size sendBufferSizeOption;
boost::asio::socket_base::send_buffer_size sendBufferSizeOption;
boost::system::error_code error;
m_sendSocket.get_option(sendBufferSizeOption);
if (error) {
@@ -131,34 +133,26 @@ bindToDevice(int fd, const std::string& ifname)
}
void
MulticastUdpTransport::openRxSocket(protocol::socket& sock,
const protocol::endpoint& multicastGroup,
const boost::asio::ip::address& localAddress,
const shared_ptr<const ndn::net::NetworkInterface>& netif)
MulticastUdpTransport::openRxSocket(ip::udp::socket& sock,
const ip::udp::endpoint& multicastGroup,
const ip::address& localAddress,
const ndn::net::NetworkInterface* netif)
{
BOOST_ASSERT(!sock.is_open());
sock.open(multicastGroup.protocol());
sock.set_option(protocol::socket::reuse_address(true));
sock.set_option(boost::asio::socket_base::reuse_address(true));
if (multicastGroup.address().is_v4()) {
BOOST_ASSERT(localAddress.is_v4());
sock.bind(multicastGroup);
sock.set_option(boost::asio::ip::multicast::join_group(multicastGroup.address().to_v4(),
localAddress.to_v4()));
sock.set_option(ip::multicast::join_group(multicastGroup.address().to_v4(), localAddress.to_v4()));
}
else {
BOOST_ASSERT(localAddress.is_v6());
sock.set_option(boost::asio::ip::v6_only(true));
#ifdef WITH_TESTS
// To simplify unit tests, we bind to the "any" IPv6 address if the supplied multicast
// address lacks a scope id. Calling bind() without a scope id would otherwise fail.
if (multicastGroup.address().to_v6().scope_id() == 0)
sock.bind(protocol::endpoint(boost::asio::ip::address_v6::any(), multicastGroup.port()));
else
#endif
sock.bind(multicastGroup);
sock.set_option(boost::asio::ip::multicast::join_group(multicastGroup.address().to_v6()));
BOOST_ASSERT(multicastGroup.address().to_v6().scope_id() != 0);
sock.set_option(ip::v6_only(true));
sock.bind(multicastGroup);
sock.set_option(ip::multicast::join_group(multicastGroup.address().to_v6()));
}
if (netif)
@@ -166,46 +160,28 @@ MulticastUdpTransport::openRxSocket(protocol::socket& sock,
}
void
MulticastUdpTransport::openTxSocket(protocol::socket& sock,
const protocol::endpoint& localEndpoint,
const shared_ptr<const ndn::net::NetworkInterface>& netif,
MulticastUdpTransport::openTxSocket(ip::udp::socket& sock,
const ip::udp::endpoint& localEndpoint,
const ndn::net::NetworkInterface* netif,
bool enableLoopback)
{
BOOST_ASSERT(!sock.is_open());
sock.open(localEndpoint.protocol());
sock.set_option(protocol::socket::reuse_address(true));
sock.set_option(boost::asio::ip::multicast::enable_loopback(enableLoopback));
sock.set_option(boost::asio::socket_base::reuse_address(true));
sock.set_option(ip::multicast::enable_loopback(enableLoopback));
if (localEndpoint.address().is_v4()) {
sock.bind(localEndpoint);
if (!localEndpoint.address().is_unspecified())
sock.set_option(boost::asio::ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
sock.set_option(ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
}
else {
sock.set_option(boost::asio::ip::v6_only(true));
sock.set_option(ip::v6_only(true));
sock.bind(localEndpoint);
if (netif)
sock.set_option(boost::asio::ip::multicast::outbound_interface(netif->getIndex()));
sock.set_option(ip::multicast::outbound_interface(netif->getIndex()));
}
}
template<>
EndpointId
DatagramTransport<boost::asio::ip::udp, Multicast>::makeEndpointId(const protocol::endpoint& ep)
{
if (ep.address().is_v4()) {
return (static_cast<uint64_t>(ep.port()) << 32) |
static_cast<uint64_t>(ep.address().to_v4().to_ulong());
}
else {
size_t seed = 0;
const auto& addrBytes = ep.address().to_v6().to_bytes();
boost::hash_range(seed, addrBytes.begin(), addrBytes.end());
boost::hash_combine(seed, ep.port());
return seed;
}
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+24 -27
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,23 +28,15 @@
#include "datagram-transport.hpp"
#include <boost/asio/ip/udp.hpp>
#include <ndn-cxx/net/network-interface.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_MEMBER_DECL_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Multicast>));
// Explicit specialization of makeEndpointId for the UDP multicast case.
// Note that this "shall be declared before the first use of the specialization
// that would cause an implicit instantiation to take place, in every translation
// unit in which such a use occurs".
template<>
EndpointId
DatagramTransport<boost::asio::ip::udp, Multicast>::makeEndpointId(const protocol::endpoint& ep);
/**
* \brief A Transport that communicates on a UDP multicast group
* \brief A Transport that communicates on a UDP multicast group.
*/
class MulticastUdpTransport final : public DatagramTransport<boost::asio::ip::udp, Multicast>
{
@@ -56,30 +48,36 @@ public:
};
/**
* \brief Creates a UDP-based transport for multicast communication
* \brief Creates a UDP-based transport for multicast communication.
* \param multicastGroup multicast group
* \param recvSocket socket used to receive multicast packets
* \param sendSocket socket used to send to the multicast group
* \param linkType either `ndn::nfd::LINK_TYPE_MULTI_ACCESS` or `ndn::nfd::LINK_TYPE_AD_HOC`
*/
MulticastUdpTransport(const protocol::endpoint& multicastGroup,
protocol::socket&& recvSocket,
protocol::socket&& sendSocket,
MulticastUdpTransport(const boost::asio::ip::udp::endpoint& multicastGroup,
boost::asio::ip::udp::socket&& recvSocket,
boost::asio::ip::udp::socket&& sendSocket,
ndn::nfd::LinkType linkType);
ssize_t
getSendQueueLength() final;
/**
* \brief Opens and configures the receive-side socket.
*/
static void
openRxSocket(protocol::socket& sock,
const protocol::endpoint& multicastGroup,
const boost::asio::ip::address& localAddress,
const shared_ptr<const ndn::net::NetworkInterface>& netif = nullptr);
openRxSocket(boost::asio::ip::udp::socket& sock,
const boost::asio::ip::udp::endpoint& multicastGroup,
const boost::asio::ip::address& localAddress = {},
const ndn::net::NetworkInterface* netif = nullptr);
/**
* \brief Opens and configures the transmit-side socket.
*/
static void
openTxSocket(protocol::socket& sock,
const protocol::endpoint& localEndpoint,
const shared_ptr<const ndn::net::NetworkInterface>& netif = nullptr,
openTxSocket(boost::asio::ip::udp::socket& sock,
const boost::asio::ip::udp::endpoint& localEndpoint,
const ndn::net::NetworkInterface* netif = nullptr,
bool enableLoopback = false);
private:
@@ -90,11 +88,10 @@ private:
doClose() final;
private:
protocol::endpoint m_multicastGroup;
protocol::socket m_sendSocket;
boost::asio::ip::udp::endpoint m_multicastGroup;
boost::asio::ip::udp::socket m_sendSocket;
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_MULTICAST_UDP_TRANSPORT_HPP
+5 -11
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,8 +27,7 @@
#include "face-system.hpp"
#include "common/logger.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_INIT(NetdevBound);
@@ -46,9 +45,7 @@ NetdevBound::processConfig(OptionalConfigSection configSection,
std::vector<Rule> rules;
if (configSection) {
int ruleIndex = 0;
for (const auto& pair : *configSection) {
const std::string& key = pair.first;
const ConfigSection& value = pair.second;
for (const auto& [key, value] : *configSection) {
if (key == "rule") {
rules.push_back(parseRule(ruleIndex++, value));
}
@@ -94,9 +91,7 @@ NetdevBound::parseRule(int index, const ConfigSection& confRule) const
bool hasWhitelist = false;
bool hasBlacklist = false;
for (const auto& pair : confRule) {
const std::string& key = pair.first;
const ConfigSection& value = pair.second;
for (const auto& [key, value] : confRule) {
if (key == "remote") {
try {
rule.remotes.emplace_back(value.get_value<std::string>());
@@ -145,5 +140,4 @@ NetdevBound::parseRule(int index, const ConfigSection& confRule) const
return rule;
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+8 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,14 +26,14 @@
#ifndef NFD_DAEMON_FACE_NETDEV_BOUND_HPP
#define NFD_DAEMON_FACE_NETDEV_BOUND_HPP
#include "network-predicate.hpp"
#include "protocol-factory.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
class FaceSystem;
/** \brief manages netdev-bound faces
/** \brief Manages netdev-bound faces.
*/
class NetdevBound : noncopyable
{
@@ -55,13 +55,13 @@ public:
NetdevBound(const ProtocolFactoryCtorParams& params, const FaceSystem& faceSystem);
/** \brief process face_system.netdev_bound config section
/** \brief Process `face_system.netdev_bound` config section.
*/
void
processConfig(OptionalConfigSection configSection,
FaceSystem::ConfigContext& context);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
struct Rule
{
std::vector<FaceUri> remotes;
@@ -71,7 +71,7 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Rule
parseRule(int index, const ConfigSection& confRule) const;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
const FaceSystem& m_faceSystem;
FaceCreatedCallback m_addFace;
shared_ptr<ndn::net::NetworkMonitor> m_netmon;
@@ -82,7 +82,6 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
std::map<Key, shared_ptr<Face>> m_faces;
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_NETDEV_BOUND_HPP
+13 -18
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,16 +29,15 @@
#include <fnmatch.h>
namespace nfd {
namespace face {
#include <boost/lexical_cast.hpp>
namespace nfd::face {
NetworkPredicateBase::NetworkPredicateBase()
{
this->clear();
}
NetworkPredicateBase::~NetworkPredicateBase() = default;
void
NetworkPredicateBase::clear()
{
@@ -162,13 +161,6 @@ IpAddressPredicate::isRuleValid(const std::string& key, const std::string& value
}
}
bool
NetworkPredicateBase::operator==(const NetworkPredicateBase& other) const
{
return this->m_whitelist == other.m_whitelist &&
this->m_blacklist == other.m_blacklist;
}
static bool
doesMatchPattern(const std::string& ifname, const std::string& pattern)
{
@@ -198,8 +190,10 @@ doesNetifMatchRule(const ndn::net::NetworkInterface& netif, const std::string& r
bool
NetworkInterfacePredicate::operator()(const ndn::net::NetworkInterface& netif) const
{
return std::any_of(m_whitelist.begin(), m_whitelist.end(), bind(&doesNetifMatchRule, std::cref(netif), _1)) &&
std::none_of(m_blacklist.begin(), m_blacklist.end(), bind(&doesNetifMatchRule, std::cref(netif), _1));
return std::any_of(m_whitelist.begin(), m_whitelist.end(),
[&netif] (const auto& rule) { return doesNetifMatchRule(netif, rule); }) &&
std::none_of(m_blacklist.begin(), m_blacklist.end(),
[&netif] (const auto& rule) { return doesNetifMatchRule(netif, rule); });
}
static bool
@@ -219,9 +213,10 @@ doesAddressMatchRule(const boost::asio::ip::address& address, const std::string&
bool
IpAddressPredicate::operator()(const boost::asio::ip::address& address) const
{
return std::any_of(m_whitelist.begin(), m_whitelist.end(), bind(&doesAddressMatchRule, std::cref(address), _1)) &&
std::none_of(m_blacklist.begin(), m_blacklist.end(), bind(&doesAddressMatchRule, std::cref(address), _1));
return std::any_of(m_whitelist.begin(), m_whitelist.end(),
[&address] (const auto& rule) { return doesAddressMatchRule(address, rule); }) &&
std::none_of(m_blacklist.begin(), m_blacklist.end(),
[&address] (const auto& rule) { return doesAddressMatchRule(address, rule); });
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+36 -20
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,21 +28,20 @@
#include "core/common.hpp"
#include <boost/operators.hpp>
#include <boost/property_tree/ptree_fwd.hpp>
#include <ndn-cxx/net/network-interface.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
class NetworkPredicateBase
class NetworkPredicateBase : private boost::equality_comparable<NetworkPredicateBase>
{
public:
NetworkPredicateBase();
virtual
~NetworkPredicateBase();
/**
* \brief Set the whitelist to "*" and clear the blacklist
* \brief Set the whitelist to "*" and clear the blacklist.
*/
void
clear();
@@ -57,14 +56,24 @@ public:
assign(std::initializer_list<std::pair<std::string, std::string>> whitelist,
std::initializer_list<std::pair<std::string, std::string>> blacklist);
bool
operator==(const NetworkPredicateBase& other) const;
protected:
// Explicitly declare the following four special member functions
// to avoid -Wdeprecated-copy-with-dtor warnings from clang.
bool
operator!=(const NetworkPredicateBase& other) const
{
return !this->operator==(other);
}
NetworkPredicateBase(const NetworkPredicateBase&) = delete;
NetworkPredicateBase(NetworkPredicateBase&&) = default;
NetworkPredicateBase&
operator=(const NetworkPredicateBase&) = delete;
NetworkPredicateBase&
operator=(NetworkPredicateBase&&) = default;
// NetworkPredicateBase is not supposed to be used polymorphically, so we make the destructor
// protected to prevent deletion of derived objects through a pointer to the base class,
// which would be UB when the destructor is non-virtual.
~NetworkPredicateBase() = default;
private:
virtual bool
@@ -79,7 +88,15 @@ private:
void
parseList(std::set<std::string>& set, std::initializer_list<std::pair<std::string, std::string>> list);
PUBLIC_WITH_TESTS_ELSE_PROTECTED:
private: // non-member operators (hidden friends)
friend bool
operator==(const NetworkPredicateBase& lhs, const NetworkPredicateBase& rhs)
{
return lhs.m_whitelist == rhs.m_whitelist &&
lhs.m_blacklist == rhs.m_blacklist;
}
NFD_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
std::set<std::string> m_whitelist;
std::set<std::string> m_blacklist;
};
@@ -94,7 +111,7 @@ PUBLIC_WITH_TESTS_ELSE_PROTECTED:
* ndn::net::NetworkInterface is accepted if it matches any entry in the whitelist and none of
* the entries in the blacklist.
*/
class NetworkInterfacePredicate : public NetworkPredicateBase
class NetworkInterfacePredicate final : public NetworkPredicateBase
{
public:
bool
@@ -116,7 +133,7 @@ private:
* 2001:db8:2::/64`) or a wildcard (`*`) that matches all IP addresses. An IP address is
* accepted if it matches any entry in the whitelist and none of the entries in the blacklist.
*/
class IpAddressPredicate : public NetworkPredicateBase
class IpAddressPredicate final : public NetworkPredicateBase
{
public:
bool
@@ -130,7 +147,6 @@ private:
isRuleValid(const std::string& key, const std::string& value) final;
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_NETWORK_PREDICATE_HPP
+3 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,8 +27,7 @@
#include "null-link-service.hpp"
#include "null-transport.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
shared_ptr<Face>
makeNullFace(const FaceUri& uri)
@@ -39,5 +38,4 @@ makeNullFace(const FaceUri& uri)
make_unique<NullTransport>(uri, uri, ndn::nfd::FACE_SCOPE_LOCAL));
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+6 -7
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,15 +28,14 @@
#include "face.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
/** \return a Face that has no underlying transport and drops every packet
/**
* \brief Returns a Face that has no underlying transport and drops every packet.
*/
shared_ptr<Face>
makeNullFace(const FaceUri& uri = FaceUri("null://"));
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_NULL_FACE_HPP
+3 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,8 +28,7 @@
#include "link-service.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief A LinkService that drops every packet.
*/
@@ -57,7 +56,6 @@ private:
}
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_NULL_LINK_SERVICE_HPP
+3 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -25,8 +25,7 @@
#include "null-transport.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
NFD_LOG_INIT(NullTransport);
@@ -43,5 +42,4 @@ NullTransport::NullTransport(const FaceUri& localUri, const FaceUri& remoteUri,
NFD_LOG_FACE_DEBUG("Creating transport");
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+6 -8
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,12 +28,11 @@
#include "transport.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief A Transport that drops every packet.
*/
class NullTransport FINAL_UNLESS_WITH_TESTS : public Transport
class NullTransport NFD_FINAL_UNLESS_WITH_TESTS : public Transport
{
public:
explicit
@@ -44,19 +43,18 @@ public:
protected:
void
doClose() OVERRIDE_WITH_TESTS_ELSE_FINAL
doClose() NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL
{
setState(TransportState::CLOSED);
}
private:
void
doSend(const Block&) OVERRIDE_WITH_TESTS_ELSE_FINAL
doSend(const Block&) NFD_OVERRIDE_WITH_TESTS_ELSE_FINAL
{
}
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_NULL_TRANSPORT_HPP
+22 -17
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,6 +26,8 @@
#include "pcap-helper.hpp"
#include "ethernet-protocol.hpp"
#include "common/privilege-helper.hpp"
#include <pcap/pcap.h>
#include <unistd.h>
@@ -33,11 +35,9 @@
#define PCAP_NETMASK_UNKNOWN 0xffffffff
#endif
namespace nfd {
namespace face {
namespace nfd::face {
PcapHelper::PcapHelper(const std::string& interfaceName)
: m_pcap(nullptr)
{
char errbuf[PCAP_ERRBUF_SIZE] = {};
m_pcap = pcap_create(interfaceName.data(), errbuf);
@@ -55,7 +55,7 @@ PcapHelper::PcapHelper(const std::string& interfaceName)
pcap_set_buffer_size(m_pcap, 4 * 1024 * 1024);
}
PcapHelper::~PcapHelper()
PcapHelper::~PcapHelper() noexcept
{
close();
}
@@ -63,9 +63,15 @@ PcapHelper::~PcapHelper()
void
PcapHelper::activate(int dlt)
{
int ret = pcap_activate(m_pcap);
if (ret < 0)
NDN_THROW(Error("pcap_activate: " + std::string(pcap_statustostr(ret))));
PrivilegeHelper::runElevated([this] {
int ret = pcap_activate(m_pcap);
if (ret < 0)
NDN_THROW(Error("pcap_activate: " + std::string(pcap_statustostr(ret))));
});
char errbuf[PCAP_ERRBUF_SIZE] = {};
if (pcap_setnonblock(m_pcap, 1, errbuf) < 0)
NDN_THROW(Error("pcap_setnonblock: " + std::string(errbuf)));
if (pcap_set_datalink(m_pcap, dlt) < 0)
NDN_THROW(Error("pcap_set_datalink: " + getLastError()));
@@ -75,7 +81,7 @@ PcapHelper::activate(int dlt)
}
void
PcapHelper::close()
PcapHelper::close() noexcept
{
if (m_pcap) {
pcap_close(m_pcap);
@@ -96,7 +102,7 @@ PcapHelper::getFd() const
}
std::string
PcapHelper::getLastError() const
PcapHelper::getLastError() const noexcept
{
return pcap_geterr(m_pcap);
}
@@ -124,20 +130,19 @@ PcapHelper::setPacketFilter(const char* filter) const
NDN_THROW(Error("pcap_setfilter: " + getLastError()));
}
std::tuple<const uint8_t*, size_t, std::string>
PcapHelper::readNextPacket() const
std::tuple<span<const uint8_t>, std::string>
PcapHelper::readNextPacket() const noexcept
{
pcap_pkthdr* header;
const uint8_t* packet;
int ret = pcap_next_ex(m_pcap, &header, &packet);
if (ret < 0)
return std::make_tuple(nullptr, 0, getLastError());
return {span<uint8_t>{}, getLastError()};
else if (ret == 0)
return std::make_tuple(nullptr, 0, "timed out");
return {span<uint8_t>{}, "Nothing to read"};
else
return std::make_tuple(packet, header->caplen, "");
return {{packet, header->caplen}, ""};
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+18 -25
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, Regents of the University of California,
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,7 +28,7 @@
#include "core/common.hpp"
#ifndef HAVE_LIBPCAP
#ifndef NFD_HAVE_LIBPCAP
#error "Cannot include this file when libpcap is not available"
#endif
@@ -36,8 +36,7 @@
struct pcap;
typedef pcap pcap_t;
namespace nfd {
namespace face {
namespace nfd::face {
/**
* @brief Helper class for dealing with libpcap handles.
@@ -48,11 +47,7 @@ public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
using std::runtime_error::runtime_error;
};
/**
@@ -63,7 +58,7 @@ public:
explicit
PcapHelper(const std::string& interfaceName);
~PcapHelper();
~PcapHelper() noexcept;
/**
* @brief Start capturing packets.
@@ -79,7 +74,7 @@ public:
* @sa pcap_close(3pcap)
*/
void
close();
close() noexcept;
/**
* @brief Obtain a file descriptor that can be used in calls such as select(2) and poll(2).
@@ -98,7 +93,7 @@ public:
* @sa pcap_geterr(3pcap)
*/
std::string
getLastError() const;
getLastError() const noexcept;
/**
* @brief Get the number of packets dropped by the kernel, as reported by libpcap.
@@ -120,27 +115,25 @@ public:
/**
* @brief Read the next packet captured on the interface.
* @return If successful, returns a tuple containing a pointer to the received packet
* (including the link-layer header) and the size of the packet; the third
* element must be ignored. On failure, returns a tuple containing nullptr,
* 0, and the reason for the failure.
* @warning The returned pointer must not be freed by the caller, and is valid only
* until the next call to this function.
* @return If successful, returns a tuple containing a read-only view of the received
* packet bytes (including the link-layer header) and a second element that
* must be ignored. On failure, returns a tuple containing an empty span and
* the reason for the failure.
* @warning The returned span is valid only until the next call to this function.
* @sa pcap_next_ex(3pcap)
*/
std::tuple<const uint8_t*, size_t, std::string>
readNextPacket() const;
std::tuple<span<const uint8_t>, std::string>
readNextPacket() const noexcept;
operator pcap_t*() const
operator pcap_t*() const noexcept
{
return m_pcap;
}
private:
pcap_t* m_pcap;
pcap_t* m_pcap = nullptr;
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_PCAP_HELPER_HPP
+3 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,8 +28,7 @@
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
ProtocolFactory::Registry&
ProtocolFactory::getRegistry()
@@ -129,5 +128,4 @@ ProtocolFactory::doGetChannels() const
return {};
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+41 -31
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -33,15 +33,16 @@
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief Parameters to ProtocolFactory constructor
/**
* \brief Parameters to ProtocolFactory constructor.
*
* Every ProtocolFactory subclass is expected to have a constructor that accepts CtorParams,
* which in turn passes it to ProtocolFactory base class constructor. Parameters are passed as a
* struct rather than individually, so that a future change in list of parameters does not
* require updates to subclass constructors.
* Every ProtocolFactory subclass is expected to have a constructor that accepts
* ProtocolFactory::CtorParams, which in turn passes it to ProtocolFactory base class
* constructor. Parameters are passed as a struct rather than individually, so that
* any future changes in the list of parameters will not require updates to all subclass
* constructors.
*/
struct ProtocolFactoryCtorParams
{
@@ -49,44 +50,52 @@ struct ProtocolFactoryCtorParams
shared_ptr<ndn::net::NetworkMonitor> netmon;
};
/** \brief Provides support for an underlying protocol
* \sa FaceSystem
/**
* \brief Provides support for an underlying protocol.
*
* A protocol factory provides support for an underlying protocol and owns Channel objects.
* It can process a subsection of face_system config section and create channels and multicast
* faces accordingly.
* A protocol factory provides support for an underlying protocol and owns Channel objects.
* It can process a subsection of the `face_system` configuration section and create channels
* and multicast faces accordingly.
*
* \sa FaceSystem
*/
class ProtocolFactory : noncopyable
{
public: // registry
using CtorParams = ProtocolFactoryCtorParams;
/** \brief Register a protocol factory type
* \tparam PF subclass of ProtocolFactory
* \param id factory identifier
/**
* \brief Register a protocol factory type.
* \tparam PF subclass of ProtocolFactory
* \param id factory identifier
*/
template<typename PF>
static void
registerType(const std::string& id = PF::getId())
{
Registry& registry = getRegistry();
BOOST_ASSERT(registry.count(id) == 0);
registry[id] = [] (const CtorParams& p) { return make_unique<PF>(p); };
BOOST_ASSERT(!id.empty());
auto r = getRegistry().insert_or_assign(id, [] (auto&&... p) {
return make_unique<PF>(std::forward<decltype(p)>(p)...);
});
BOOST_VERIFY(r.second);
}
/** \brief Create a protocol factory instance
* \retval nullptr if a factory with the given \p id is not registered
/**
* \brief Create a protocol factory instance.
* \retval nullptr if a factory with the given \p id is not registered
*/
static unique_ptr<ProtocolFactory>
create(const std::string& id, const CtorParams& params);
/** \brief Get all registered protocol factory ids
/**
* \brief Get all registered protocol factory IDs.
*/
static std::set<std::string>
[[nodiscard]] static std::set<std::string>
listRegistered();
public:
/** \brief Base class for all exceptions thrown by ProtocolFactory subclasses
/**
* \brief Base class for all exceptions thrown by ProtocolFactory subclasses.
*/
class Error : public std::runtime_error
{
@@ -101,18 +110,20 @@ public:
~ProtocolFactory() = 0;
#ifdef DOXYGEN
/** \brief Get id for this protocol factory
/**
* \brief Get the ID of this protocol factory.
*
* face_system.factory-id config section is processed by the protocol factory.
* `face_system.<factory-id>` config section is processed by the protocol factory.
*/
static const std::string&
getId() noexcept;
#endif
/** \brief Get FaceUri schemes accepted by this protocol factory
/**
* \brief Get FaceUri schemes accepted by this protocol factory.
*/
const std::set<std::string>&
getProvidedSchemes() const
getProvidedSchemes() const noexcept
{
return providedSchemes;
}
@@ -133,7 +144,7 @@ public:
struct CreateFaceRequest
{
FaceUri remoteUri;
optional<FaceUri> localUri;
std::optional<FaceUri> localUri;
FaceParams params;
};
@@ -246,8 +257,7 @@ protected:
shared_ptr<ndn::net::NetworkMonitor> netmon;
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
/** \brief Registers a protocol factory
*
+6 -35
View File
@@ -1,6 +1,7 @@
#include "queues.hpp"
#include "common/global.hpp"
#include <ndn-cxx/encoding/estimator.hpp>
namespace nfd
{
namespace face
@@ -43,7 +44,7 @@ namespace nfd
{
this->needRateLimit = true;
this->tokenBucket = std::make_shared<TokenBucket>(rateLimit, 20 * 1000 * 8, name);
// this->tokenBucket->start();
this->tokenBucket->start();
}
else
{
@@ -59,6 +60,7 @@ namespace nfd
std::string key = interest.getName().getPrefix(1).toUri();
if (this->virtualQueues.count(key) == 0)
{
this->virtualQueues[key] = std::make_shared<VirtualQueue>(1, this->vqSize);
this->virtualQueues[key]->tos = this->tos;
this->flows.push_back(key);
@@ -153,18 +155,13 @@ namespace nfd
{
return currentRate;
}
// if (currentRate > 0) {
// std::cout << "currentRate: " << currentRate << ", " << this->recvBits << "," << this->calObjectRateInterval << ", AvaliableBandwidth: " << this->availableBandwidth << std::endl;
// }
bool hasCleanFlow = false;
for (auto it = this->virtualQueues.begin(); it != this->virtualQueues.end();)
{
// std::cout << "key: " << it->first << ", recvBits" << it->second->recvBits << std::endl;
if (it->second->recvBits == 0 && it->second->empty())
{
this->totalWeight -= it->second->weight;
this->virtualQueues.erase(it++); // here is the key
// std::cout << "do clean: " << std::endl;
hasCleanFlow = true;
}
else
@@ -212,9 +209,6 @@ namespace nfd
consumeRate += item.second->currentFlowRate;
}
NFD_LOG_DEBUG(this->name << " => currentRate: " << item.second->currentFlowRate << ", consumerRate: " << consumeRate << ", objectRate: " << item.second->objectRate << ", availableBandwidth" << this->availableBandwidth << ", weight: " << item.second->weight << ", totalWeight: " << this->totalWeight << ", currentSendRate: " << currentSendRate);
// std::cout << this->name << " => currentRate: " << item.second->currentFlowRate << ", consumerRate: " << consumeRate << ", objectRate: " << item.second->objectRate <<
// ", availableBandwidth" << this->availableBandwidth << ", weight: " << item.second->weight << ", totalWeight: " <<
// this->totalWeight << ", currentSendRate: " << currentSendRate << std::endl;
item.second->recvBits = 0;
}
@@ -230,8 +224,6 @@ namespace nfd
item.second->objectRate += (remainRate * item.second->weight / totalHightSpeedFlowWeight);
}
NFD_LOG_DEBUG(this->name << " => objectRate: " << item.second->objectRate << ", remainRate: " << remainRate << ", item.weight: " << item.second->weight << ", totalWeight: " << totalHightSpeedFlowWeight);
// std::cout << this->name << " => objectRate: " << item.second->objectRate << ", remainRate: " <<
// remainRate << ", item.weight: " << item.second->weight << ", totalWeight: " << totalHightSpeedFlowWeight << std::endl;
}
}
@@ -246,7 +238,6 @@ namespace nfd
}
if (item.second->gredyTimes == item.second->gredyThreshold)
{
// std::cout << item.first << ": PenaltyFactor => " << item.second->gredyTimes << ", currentFlowRate: " << item.second->currentFlowRate << ", objectRate: " << item.second->objectRate << std::endl;
item.second->penaltyFactor = 0.5;
item.second->size = 20;
}
@@ -259,10 +250,6 @@ namespace nfd
}
}
}
// if (this->virtualQueues.size() > 0)
// {
// std::cout << "\n\n=====================: " << this->availableBandwidth << std::endl;
// }
for (auto &item : this->virtualQueues)
{
if (item.second->penaltyFactor > 0.99)
@@ -270,15 +257,7 @@ namespace nfd
auto rate = this->calDiscountFactor(item.second->currentSize * 1.0 / item.second->size);
item.second->objectRate *= rate;
}
// std::cout << item.first << ", currentFlowRate: " << item.second->currentFlowRate
// << ", objectRate: " << item.second->objectRate << ", size: " << item.second->currentSize
// << ", weight: " << item.second->weight << ", penaltyFactor: " << item.second->penaltyFactor
// << std::endl;
}
// if (this->virtualQueues.size() > 0)
// {
// std::cout << "\n----------------------" << std::endl;
// }
this->sendBits = 0;
this->recvBits = 0;
return currentRate;
@@ -391,13 +370,10 @@ namespace nfd
int remain = this->availableBandwidth - totalRate;
if (hightSppedFlowNum > 0)
{
// std::cout << "high speed flow num: " << hightSppedFlowNum << ", totalHightSpeedFlowWeight: " << totalHightSpeedFlowWeight << std::endl;
for (auto &queue : this->queues)
{
if (queue->getRemainBandwidthRate(queue->originAvaliableBandwidth) < 0.2)
{
// std::cout << "!!!" << queue->getWeight() * remain * 1.0 / totalHightSpeedFlowWeight +
// queue->originAvaliableBandwidth << std::endl;
queue->updateAvailableBandwidth(
queue->getWeight() * remain * 1.0 / totalHightSpeedFlowWeight +
queue->originAvaliableBandwidth);
@@ -410,7 +386,6 @@ namespace nfd
}
else
{
// std::cout << "has flow queue num: " << hasFlowQueueNum << ", totalHasFlowQueueWeight: " << totalHasFlowQueueWeight << std::endl;
for (auto &queue : this->queues)
{
if (queue->getRemainBandwidthRate(queue->originAvaliableBandwidth) < 0.95)
@@ -490,7 +465,6 @@ namespace nfd
{
serviceClass = (*interest.getServiceClass()) % 8;
}
// std::cout << "appendInterest => serviceClass: " << serviceClass << std::endl;
return this->getQueueByTos(serviceClass)->appendInterest(interest);
}
void GlobalSP::receiveInterest(const Interest &interest)
@@ -498,20 +472,18 @@ namespace nfd
ndn::encoding::EncodingEstimator estimator;
auto size = interest.wireEncode(estimator) + 9;
this->interestBytes += size;
// std::cout << this << "receiveInterest => size: " << size << ", interestBytes: " << this->interestBytes << std::endl;
}
void GlobalSP::calObjectRate(bool getCurrentRateOnly)
{
// getScheduler().schedule(time::nanoseconds(1000000 * this->calObjectRateInterval),
// [this] { this->calObjectRate(false); });
getScheduler().schedule(time::nanoseconds(1000000 * this->calObjectRateInterval),
[this]
{ this->calObjectRate(false); });
uint32_t remain = this->availableBandwidth;
remain -= this->interestBytes * 8000 / this->calObjectRateInterval;
this->interestBytes = 0;
remain -= this->delaySensitiveServiceSp.calObjectRate(false);
// std::cout << "AvaliableBandwidth: " << this->availableBandwidth << ", remain: " << remain << ", interestBytes" << this->interestBytes << std::endl;
this->wfqQueue.calObjectRate(remain);
}
void GlobalSP::assignObjectRate(const Data &data)
@@ -522,7 +494,6 @@ namespace nfd
{
serviceClass = (*data.getServiceClass()) % 8;
}
// std::cout << "assignObjectRate => serviceClass: " << serviceClass << std::endl;
auto objectRate = this->getQueueByTos(serviceClass)->getObjectRateByFlowKey(key);
auto targetRate = data.getTargetRate();
if (!targetRate || *targetRate > objectRate)
+141 -112
View File
@@ -3,87 +3,109 @@
#include <deque>
#include <unordered_map>
#include <memory>
#include <iostream>
#include "common/global.hpp"
#include "link-service.hpp"
#include <ndn-cxx/lp/tags.hpp>
#include "TokenBucket.hpp"
namespace nfd {
namespace face {
#include <iostream>
namespace nfd
{
namespace face
{
class VirtualQueue;
struct VirtualQueueItem {
struct VirtualQueueItem
{
int seq;
std::shared_ptr<const Interest> item;
EndpointId endpointId;
uint32_t dataSize;
uint32_t waitNsTime;
std::shared_ptr<VirtualQueue> queue;
};
class VirtualQueue : public std::enable_shared_from_this<VirtualQueue>{
class VirtualQueue : public std::enable_shared_from_this<VirtualQueue>
{
public:
explicit VirtualQueue(double weight, int size) :
std::enable_shared_from_this<VirtualQueue>(),
penaltyFactor(1.0),
weight(weight), size(size), currentSize(0), lastSeq(0),
C(0) {
explicit VirtualQueue(double weight, int size) : std::enable_shared_from_this<VirtualQueue>(),
penaltyFactor(1.0),
weight(weight), size(size), currentSize(0), lastSeq(0),
C(0)
{
}
void enableTokenBucket(uint32_t limitRate) {
void enableTokenBucket(uint32_t limitRate)
{
this->C = limitRate;
}
bool push(int seq, const std::shared_ptr<const Interest>& interest,
bool push(int seq, const std::shared_ptr<const Interest> &interest, const EndpointId &endpointId,
uint64_t dataSize, bool needInsert);
bool empty() {
bool empty()
{
return this->innerQueue.empty();
}
uint32_t frontSeq() {
if (this->innerQueue.empty()) {
uint32_t frontSeq()
{
if (this->innerQueue.empty())
{
return this->lastSeq;
}
return this->innerQueue.front().seq;
}
VirtualQueueItem front() {
VirtualQueueItem front()
{
return this->innerQueue.front();
}
uint32_t backSeq() {
uint32_t backSeq()
{
return this->lastSeq;
}
VirtualQueueItem back() {
VirtualQueueItem back()
{
return this->innerQueue.back();
}
void pop() {
if (this->currentSize <= 0) {
void pop()
{
if (this->currentSize <= 0)
{
return;
}
this->currentSize--;
this->innerQueue.pop_front();
}
void popBack() {
if (this->currentSize <= 0) {
void popBack()
{
if (this->currentSize <= 0)
{
return;
}
this->currentSize--;
this->innerQueue.pop_back();
}
int len() {
int len()
{
return this->innerQueue.size();
}
void setLastSeq(uint32_t seq) {
void setLastSeq(uint32_t seq)
{
this->lastSeq = seq;
}
uint32_t getLastSeq() {
uint32_t getLastSeq()
{
return lastSeq;
}
void setWeight(double weight) {
void setWeight(double weight)
{
this->weight = weight;
}
double getWeight() {
double getWeight()
{
return this->weight;
}
public:
uint32_t objectRate;
double penaltyFactor = 1.0;
uint32_t gredyTimes = 0;
double gredyRatio = 1.2;
double gredyThreshold = 10;
double gredyThreshold = 5;
double weight = 1.0;
uint32_t tos = 5;
double balance = 0;
@@ -92,81 +114,89 @@ namespace nfd {
uint32_t recvBits = 0;
uint32_t currentFlowRate = 0;
double currentRatio = 0.0;
private:
uint32_t lastSeq;
int C;
std::deque<VirtualQueueItem> innerQueue;
};
class WDRRQueue {
class WDRRQueue
{
public:
explicit WDRRQueue(uint32_t rateLimit, uint32_t availableBandwidth, double weight, const std::string& name,
uint32_t tos = 5, size_t vqSize = 20);
explicit WDRRQueue(uint32_t rateLimit, uint32_t availableBandwidth, double weight, const std::string &name,
uint32_t tos = 5, size_t vqSize = 20);
void updateAvailableBandwidth(uint32_t C);
bool appendInterest(const Interest &interest);
bool appendInterest(const Interest &interest, const EndpointId &endpointId);
std::shared_ptr<VirtualQueueItem> scheduleNext();
uint32_t calObjectRate(bool getCurrentRateOnly);
void setCDTLimit(int cdt) {
void setCDTLimit(int cdt)
{
this->cdt = cdt;
}
uint32_t scheduleOnePacketForWFQ(uint32_t totalLastSeq);
std::shared_ptr<VirtualQueueItem> frontForWFQ(uint32_t totalLastSeq) {
if (this->cachePacketForWFQ == nullptr) {
std::shared_ptr<VirtualQueueItem> frontForWFQ(uint32_t totalLastSeq)
{
if (this->cachePacketForWFQ == nullptr)
{
this->scheduleOnePacketForWFQ(totalLastSeq);
}
return this->cachePacketForWFQ;
}
void popForWFQ() {
void popForWFQ()
{
this->cachePacketForWFQ = nullptr;
}
double getRemainBandwidthRate(double curAvailableBandWidth) {
double getRemainBandwidthRate(double curAvailableBandWidth)
{
auto currentRate = this->calObjectRate(true);
if (currentRate > curAvailableBandWidth) {
if (currentRate > curAvailableBandWidth)
{
return 0;
}
return (curAvailableBandWidth - currentRate) * 1.0 / curAvailableBandWidth;
}
uint32_t getRemainBandwidth() {
uint32_t getRemainBandwidth()
{
return this->availableBandwidth - this->calObjectRate(true);
}
double getWeight() {
double getWeight()
{
return this->weight;
}
uint32_t getAvailableBandwidth() {
uint32_t getAvailableBandwidth()
{
return this->availableBandwidth;
}
/**
* @brief
*
* @brief
*
* \sigma=\frac{1}{3}\arccot\funcapply(8\delta-4)
* @param x
* @return double
* @param x
* @return double
*/
double calDiscountFactor(double x) {
double calDiscountFactor(double x)
{
return 1.0 / 3 * (M_PI / 2 - atan(8 * x - 4)) + 0.034;
}
/**
* @brief Get the Object Rate By Flow Key object
*
* @param key
* @return uint32_t
*
* @param key
* @return uint32_t
*/
uint32_t getObjectRateByFlowKey(const std::string& key) {
if (this->virtualQueues.count(key) == 0) {
std::cout << "FUCK: " << key << ", count: " << this->virtualQueues.size() <<
", flow: " << this->flows.size() << "availbleRate: " << this->availableBandwidth << std::endl;
uint32_t getObjectRateByFlowKey(const std::string &key)
{
if (this->virtualQueues.count(key) == 0)
{
std::cout << "FUCK: " << key << ", count: " << this->virtualQueues.size() << ", flow: " << this->flows.size() << "availbleRate: " << this->availableBandwidth << std::endl;
return 0;
}
return this->virtualQueues[key]->objectRate;
}
void triggerByCurrentTime(long currentTime) {
if (this->needRateLimit) {
this->tokenBucket->generateTokenByCurrentTime(currentTime);
}
}
public:
double originAvaliableBandwidth = 0;
private:
std::unordered_map<std::string, std::shared_ptr<VirtualQueue>> virtualQueues;
std::vector<std::string> flows;
@@ -189,72 +219,81 @@ namespace nfd {
int64_t lastSeq = -1;
std::shared_ptr<VirtualQueueItem> cachePacketForWFQ = nullptr;
};
class DelaySensitiveServiceSP {
class DelaySensitiveServiceSP
{
public:
explicit DelaySensitiveServiceSP(uint32_t availableBandwidth, size_t vqSize = 20) {
this->CS7Queue = std::make_shared<WDRRQueue>((uint32_t) (0.2 * availableBandwidth), (uint32_t) (0.2 * availableBandwidth), 2, "CS7", 2, vqSize);
this->CS6Queue = std::make_shared<WDRRQueue>((uint32_t) (0.2 * availableBandwidth), (uint32_t) (0.2 * availableBandwidth), 2, "CS6", 1, vqSize);
this->EFQueue = std::make_shared<WDRRQueue>((uint32_t) (0.3 * availableBandwidth), (uint32_t) (0.3 * availableBandwidth), 3, "EF", 0, vqSize);
explicit DelaySensitiveServiceSP(uint32_t availableBandwidth, size_t vqSize = 20)
{
this->CS7Queue = std::make_shared<WDRRQueue>((uint32_t)(0.2 * availableBandwidth), (uint32_t)(0.2 * availableBandwidth), 2, "CS7", 2, vqSize);
this->CS6Queue = std::make_shared<WDRRQueue>((uint32_t)(0.2 * availableBandwidth), (uint32_t)(0.2 * availableBandwidth), 2, "CS6", 1, vqSize);
this->EFQueue = std::make_shared<WDRRQueue>((uint32_t)(0.3 * availableBandwidth), (uint32_t)(0.3 * availableBandwidth), 3, "EF", 0, vqSize);
}
std::shared_ptr<VirtualQueueItem> scheduleNext();
uint32_t calObjectRate(bool getCurrentRateOnly);
std::shared_ptr<WDRRQueue> getCS7Queue() {
std::shared_ptr<WDRRQueue> getCS7Queue()
{
return this->CS7Queue;
}
std::shared_ptr<WDRRQueue> getCS6Queue() {
std::shared_ptr<WDRRQueue> getCS6Queue()
{
return this->CS6Queue;
}
std::shared_ptr<WDRRQueue> getEFQueue() {
std::shared_ptr<WDRRQueue> getEFQueue()
{
return this->EFQueue;
}
void triggerByCurrentTime(long currentTime) {
this->CS7Queue->triggerByCurrentTime(currentTime);
this->CS6Queue->triggerByCurrentTime(currentTime);
this->EFQueue->triggerByCurrentTime(currentTime);
}
private:
std::shared_ptr<WDRRQueue> CS7Queue;
std::shared_ptr<WDRRQueue> CS6Queue;
std::shared_ptr<WDRRQueue> EFQueue;
};
class WFQQueue {
class WFQQueue
{
public:
explicit WFQQueue(uint32_t availableBandwidth, size_t vqSize) :
AF4Weight(5),
AF3Weight(4),
AF2Weight(3),
AF1Weight(2),
BEWeight(1),
totalWeight(AF4Weight + AF3Weight + AF2Weight + AF1Weight + BEWeight),
queues(5),
lastSeq(0),
availableBandwidth(availableBandwidth) {
explicit WFQQueue(uint32_t availableBandwidth, size_t vqSize) : AF4Weight(5),
AF3Weight(4),
AF2Weight(3),
AF1Weight(2),
BEWeight(1),
totalWeight(AF4Weight + AF3Weight + AF2Weight + AF1Weight + BEWeight),
queues(5),
lastSeq(0),
availableBandwidth(availableBandwidth)
{
this->queues[0] = std::make_shared<WDRRQueue>(0, availableBandwidth * AF4Weight / totalWeight, 5, "AF4", 3, vqSize);
this->queues[1] = std::make_shared<WDRRQueue>(0, availableBandwidth * AF3Weight / totalWeight, 4, "AF3", 4, vqSize);
this->queues[2] = std::make_shared<WDRRQueue>(0, availableBandwidth * AF2Weight / totalWeight, 3, "AF2", 5, vqSize);
this->queues[3] = std::make_shared<WDRRQueue>(0, availableBandwidth * AF1Weight / totalWeight, 2, "AF1", 6, vqSize);
this->queues[4] = std::make_shared<WDRRQueue>(0, availableBandwidth * BEWeight / totalWeight, 1, "BE", 7, vqSize);
for (auto &queue: this->queues) {
for (auto &queue : this->queues)
{
queue->setCDTLimit(this->cdt);
}
}
std::shared_ptr<VirtualQueueItem> scheduleNext();
uint32_t calObjectRate(uint32_t availableBandwidth);
std::shared_ptr<WDRRQueue> getAF4Queue() {
std::shared_ptr<WDRRQueue> getAF4Queue()
{
return this->queues[0];
}
std::shared_ptr<WDRRQueue> getAF3Queue() {
std::shared_ptr<WDRRQueue> getAF3Queue()
{
return this->queues[1];
}
std::shared_ptr<WDRRQueue> getAF2Queue() {
std::shared_ptr<WDRRQueue> getAF2Queue()
{
return this->queues[2];
}
std::shared_ptr<WDRRQueue> getAF1Queue() {
std::shared_ptr<WDRRQueue> getAF1Queue()
{
return this->queues[3];
}
std::shared_ptr<WDRRQueue> getBEQueue() {
std::shared_ptr<WDRRQueue> getBEQueue()
{
return this->queues[4];
}
private:
double AF4Weight = 5;
double AF3Weight = 4;
@@ -268,42 +307,32 @@ namespace nfd {
int cdt = 200;
int hql;
};
class GlobalSP {
class GlobalSP
{
public:
explicit GlobalSP(uint32_t availableBandwidth, size_t vqSize = 20) :
delaySensitiveServiceSp(availableBandwidth, vqSize),
wfqQueue(availableBandwidth, vqSize),
availableBandwidth(availableBandwidth) {
lastTriggerTime = getCurrentTime();
// getScheduler().schedule(time::nanoseconds(1000000 * this->calObjectRateInterval),
// [this] { this->calObjectRate(false); });
explicit GlobalSP(uint32_t availableBandwidth, size_t vqSize = 20) : delaySensitiveServiceSp(availableBandwidth, vqSize),
wfqQueue(availableBandwidth, vqSize),
availableBandwidth(availableBandwidth)
{
getScheduler().schedule(time::nanoseconds(1000000 * this->calObjectRateInterval),
[this]
{ this->calObjectRate(false); });
}
std::shared_ptr<VirtualQueueItem> scheduleNext();
bool appendInterest(const Interest &interest);
bool appendInterest(const Interest &interest, const EndpointId &endpointId);
void receiveInterest(const Interest &interest);
void calObjectRate(bool getCurrentRateOnly);
std::shared_ptr<WDRRQueue> getQueueByTos(int tosValue);
long getCurrentTime() {
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count();
}
void triggerCalObjectRate() {
auto currentTime = getCurrentTime();
this->delaySensitiveServiceSp.triggerByCurrentTime(currentTime);
if (currentTime - lastTriggerTime > calObjectRateInterval) {
this->calObjectRate(false);
lastTriggerTime = currentTime;
}
}
void assignObjectRate(const Data &data);
private:
DelaySensitiveServiceSP delaySensitiveServiceSp;
WFQQueue wfqQueue;
int calObjectRateInterval = 100;
uint32_t availableBandwidth;
size_t interestBytes = 0;
long lastTriggerTime = 0;
};
}
}
#endif //NS_QUEUES_HPP
#endif // NS_QUEUES_HPP
+3 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2018, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -33,8 +33,7 @@
#include <sys/socket.h>
#endif
namespace nfd {
namespace face {
namespace nfd::face {
ssize_t
getTxQueueLength(int fd)
@@ -53,5 +52,4 @@ getTxQueueLength(int fd)
return queueLength;
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+4 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2018, Regents of the University of California,
* Copyright (c) 2014-2022, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,10 +28,9 @@
#include "core/common.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief obtain send queue length from a specified system socket
/** \brief Obtain send queue length from a specified system socket.
* \param fd file descriptor of the socket
* \retval QUEUE_UNSUPPORTED this operation is unsupported on the current platform
* \retval QUEUE_ERROR there was an error retrieving the send queue length
@@ -42,7 +41,6 @@ namespace face {
ssize_t
getTxQueueLength(int fd);
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_SOCKET_UTILS_HPP
+19 -15
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -32,22 +32,26 @@
#include <queue>
namespace nfd {
namespace face {
#include <boost/asio/defer.hpp>
#include <boost/asio/write.hpp>
/** \brief Implements Transport for stream-based protocols.
namespace nfd::face {
/**
* \brief Implements a Transport for stream-based protocols.
*
* \tparam Protocol a stream-based protocol in Boost.Asio
* \tparam Protocol a stream-based protocol in Boost.Asio
*/
template<class Protocol>
class StreamTransport : public Transport
{
public:
typedef Protocol protocol;
using protocol = Protocol;
/** \brief Construct stream transport.
/**
* \brief Construct stream transport.
*
* \param socket Protocol-specific socket for the created transport
* \param socket Protocol-specific socket for the created transport
*/
explicit
StreamTransport(typename protocol::socket&& socket);
@@ -143,12 +147,12 @@ StreamTransport<T>::doClose()
// Use the non-throwing variants and ignore errors, if any.
boost::system::error_code error;
m_socket.cancel(error);
m_socket.shutdown(protocol::socket::shutdown_both, error);
m_socket.shutdown(boost::asio::socket_base::shutdown_both, error);
}
// Ensure that the Transport stays alive at least until
// all pending handlers are dispatched
getGlobalIoService().post([this] { deferredClose(); });
boost::asio::defer(getGlobalIoService(), [this] { deferredClose(); });
// Some bug or feature of Boost.Asio (see https://redmine.named-data.net/issues/1856):
//
@@ -244,16 +248,17 @@ StreamTransport<T>::handleReceive(const boost::system::error_code& error,
NFD_LOG_FACE_TRACE("Received: " << nBytesReceived << " bytes");
m_receiveBufferSize += nBytesReceived;
auto bufferView = ndn::make_span(m_receiveBuffer, m_receiveBufferSize);
size_t offset = 0;
bool isOk = true;
while (m_receiveBufferSize - offset > 0) {
while (offset < bufferView.size()) {
Block element;
std::tie(isOk, element) = Block::fromBuffer(m_receiveBuffer + offset, m_receiveBufferSize - offset);
std::tie(isOk, element) = Block::fromBuffer(bufferView.subspan(offset));
if (!isOk)
break;
offset += element.size();
BOOST_ASSERT(offset <= m_receiveBufferSize);
BOOST_ASSERT(offset <= bufferView.size());
this->receive(element);
}
@@ -332,7 +337,6 @@ StreamTransport<T>::getSendQueueBytes() const
return m_sendQueueBytes;
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_STREAM_TRANSPORT_HPP
+38 -39
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,19 +29,19 @@
#include "tcp-transport.hpp"
#include "common/global.hpp"
namespace nfd {
namespace face {
#include <boost/asio/ip/v6_only.hpp>
NFD_LOG_INIT(TcpChannel);
namespace nfd::face {
namespace ip = boost::asio::ip;
NFD_LOG_INIT(TcpChannel);
TcpChannel::TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking,
DetermineFaceScopeFromAddress determineFaceScope)
: m_localEndpoint(localEndpoint)
, m_acceptor(getGlobalIoService())
, m_socket(getGlobalIoService())
, m_wantCongestionMarking(wantCongestionMarking)
, m_acceptor(getGlobalIoService())
, m_determineFaceScope(std::move(determineFaceScope))
{
setUri(FaceUri(m_localEndpoint));
@@ -51,7 +51,7 @@ TcpChannel::TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMa
void
TcpChannel::listen(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed,
int backlog/* = tcp::acceptor::max_connections*/)
int backlog)
{
if (isListening()) {
NFD_LOG_CHAN_WARN("Already listening");
@@ -59,7 +59,7 @@ TcpChannel::listen(const FaceCreatedCallback& onFaceCreated,
}
m_acceptor.open(m_localEndpoint.protocol());
m_acceptor.set_option(ip::tcp::acceptor::reuse_address(true));
m_acceptor.set_option(boost::asio::socket_base::reuse_address(true));
if (m_localEndpoint.address().is_v6()) {
m_acceptor.set_option(ip::v6_only(true));
}
@@ -98,10 +98,19 @@ TcpChannel::connect(const tcp::Endpoint& remoteEndpoint,
void
TcpChannel::createFace(ip::tcp::socket&& socket,
const FaceParams& params,
const FaceCreatedCallback& onFaceCreated)
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onFaceCreationFailed)
{
shared_ptr<Face> face;
tcp::Endpoint remoteEndpoint = socket.remote_endpoint();
boost::system::error_code ec;
tcp::Endpoint remoteEndpoint = socket.remote_endpoint(ec);
if (ec) {
NFD_LOG_CHAN_DEBUG("Retrieve socket remote endpoint failed: " << ec.message());
if (onFaceCreationFailed) {
onFaceCreationFailed(500, "Retrieve socket remote endpoint failed: " + ec.message());
}
return;
}
auto it = m_channelFaces.find(remoteEndpoint);
if (it == m_channelFaces.end()) {
@@ -123,16 +132,13 @@ TcpChannel::createFace(ip::tcp::socket&& socket,
if (params.defaultCongestionThreshold) {
options.defaultCongestionThreshold = *params.defaultCongestionThreshold;
}
if (params.bandwidth) {
options.C = *params.bandwidth;
}
auto linkService = make_unique<GenericLinkService>(options);
auto faceScope = m_determineFaceScope(socket.local_endpoint().address(),
socket.remote_endpoint().address());
auto transport = make_unique<TcpTransport>(std::move(socket), params.persistency, faceScope);
face = make_shared<Face>(std::move(linkService), std::move(transport));
face->setChannel(shared_from_this()); // use weak_from_this() in C++17
face->setChannel(weak_from_this());
m_channelFaces[remoteEndpoint] = face;
connectFaceClosedSignal(*face, [this, remoteEndpoint] { m_channelFaces.erase(remoteEndpoint); });
@@ -143,7 +149,7 @@ TcpChannel::createFace(ip::tcp::socket&& socket,
NFD_LOG_CHAN_TRACE("Reusing existing face for " << remoteEndpoint);
boost::system::error_code error;
socket.shutdown(ip::tcp::socket::shutdown_both, error);
socket.shutdown(boost::asio::socket_base::shutdown_both, error);
socket.close(error);
}
@@ -156,31 +162,25 @@ void
TcpChannel::accept(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed)
{
m_acceptor.async_accept(m_socket, [=] (const auto& e) { this->handleAccept(e, onFaceCreated, onAcceptFailed); });
}
void
TcpChannel::handleAccept(const boost::system::error_code& error,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed)
{
if (error) {
if (error != boost::asio::error::operation_aborted) {
NFD_LOG_CHAN_DEBUG("Accept failed: " << error.message());
if (onAcceptFailed)
onAcceptFailed(500, "Accept failed: " + error.message());
m_acceptor.async_accept([=] (const boost::system::error_code& error, ip::tcp::socket socket) {
if (error) {
if (error != boost::asio::error::operation_aborted) {
NFD_LOG_CHAN_DEBUG("Accept failed: " << error.message());
if (onAcceptFailed)
onAcceptFailed(500, "Accept failed: " + error.message());
}
return;
}
return;
}
NFD_LOG_CHAN_TRACE("Incoming connection from " << m_socket.remote_endpoint());
NFD_LOG_CHAN_TRACE("Incoming connection from " << socket.remote_endpoint());
FaceParams params;
params.persistency = ndn::nfd::FACE_PERSISTENCY_ON_DEMAND;
createFace(std::move(m_socket), params, onFaceCreated);
FaceParams params;
params.persistency = ndn::nfd::FACE_PERSISTENCY_ON_DEMAND;
createFace(std::move(socket), params, onFaceCreated, onAcceptFailed);
// prepare accepting the next connection
accept(onFaceCreated, onAcceptFailed);
// prepare accepting the next connection
accept(onFaceCreated, onAcceptFailed);
});
}
void
@@ -204,7 +204,7 @@ TcpChannel::handleConnect(const boost::system::error_code& error,
}
NFD_LOG_CHAN_TRACE("Connected to " << socket->remote_endpoint());
createFace(std::move(*socket), params, onFaceCreated);
createFace(std::move(*socket), params, onFaceCreated, onConnectFailed);
}
void
@@ -222,5 +222,4 @@ TcpChannel::handleConnectTimeout(const tcp::Endpoint& remoteEndpoint,
onConnectFailed(504, "Connection timed out");
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+22 -29
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,51 +28,50 @@
#include "channel.hpp"
namespace nfd {
#include <boost/asio/ip/tcp.hpp>
namespace tcp {
typedef boost::asio::ip::tcp::endpoint Endpoint;
} // namespace tcp
namespace nfd::tcp {
using Endpoint = boost::asio::ip::tcp::endpoint;
} // namespace nfd::tcp
namespace face {
namespace nfd::face {
using DetermineFaceScopeFromAddress = std::function<ndn::nfd::FaceScope(const boost::asio::ip::address& local,
const boost::asio::ip::address& remote)>;
/**
* \brief Class implementing TCP-based channel to create faces
* \brief Class implementing a TCP-based channel to create faces.
*
* Channel can create faces as a response to incoming TCP
* connections (TcpChannel::listen needs to be called for that
* to work) or explicitly after using TcpChannel::connect method.
* The channel can create faces as a response to incoming TCP connections (TcpChannel::listen()
* needs to be called for that to work) or explicitly by using TcpChannel::connect().
*/
class TcpChannel : public Channel
class TcpChannel final : public Channel
{
public:
/**
* \brief Create TCP channel for the local endpoint
* \brief Create a TCP channel for the specified \p localEndpoint.
*
* To enable creation faces upon incoming connections,
* one needs to explicitly call TcpChannel::listen method.
* To enable the creation of faces upon incoming connections, one needs to
* explicitly call listen().
*/
TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking,
DetermineFaceScopeFromAddress determineFaceScope);
bool
isListening() const override
isListening() const final
{
return m_acceptor.is_open();
}
size_t
size() const override
size() const final
{
return m_channelFaces.size();
}
/**
* \brief Enable listening on the local endpoint, accept connections,
* and create faces when remote host makes a connection
* and create faces when remote host makes a connection.
* \param onFaceCreated Callback to notify successful creation of the face
* \param onAcceptFailed Callback to notify when channel fails (accept call
* returns an error)
@@ -82,10 +81,10 @@ public:
void
listen(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed,
int backlog = boost::asio::ip::tcp::acceptor::max_connections);
int backlog = boost::asio::socket_base::max_listen_connections);
/**
* \brief Create a face by establishing a TCP connection to \p remoteEndpoint
* \brief Create a face by establishing a TCP connection to \p remoteEndpoint.
*/
void
connect(const tcp::Endpoint& remoteEndpoint,
@@ -98,17 +97,13 @@ private:
void
createFace(boost::asio::ip::tcp::socket&& socket,
const FaceParams& params,
const FaceCreatedCallback& onFaceCreated);
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onFaceCreationFailed);
void
accept(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed);
void
handleAccept(const boost::system::error_code& error,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed);
void
handleConnect(const boost::system::error_code& error,
const tcp::Endpoint& remoteEndpoint,
@@ -125,14 +120,12 @@ private:
private:
const tcp::Endpoint m_localEndpoint;
const bool m_wantCongestionMarking;
boost::asio::ip::tcp::acceptor m_acceptor;
boost::asio::ip::tcp::socket m_socket;
std::map<tcp::Endpoint, shared_ptr<Face>> m_channelFaces;
bool m_wantCongestionMarking;
DetermineFaceScopeFromAddress m_determineFaceScope;
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_TCP_CHANNEL_HPP
+15 -14
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -25,8 +25,9 @@
#include "tcp-factory.hpp"
namespace nfd {
namespace face {
#include <boost/lexical_cast.hpp>
namespace nfd::face {
namespace ip = boost::asio::ip;
@@ -151,31 +152,31 @@ TcpFactory::doCreateFace(const CreateFaceRequest& req,
const FaceCreationFailedCallback& onFailure)
{
if (req.localUri) {
NFD_LOG_TRACE("Cannot create unicast TCP face with LocalUri");
NFD_LOG_TRACE("createFace: unsupported LocalUri");
onFailure(406, "Unicast TCP faces cannot be created with a LocalUri");
return;
}
if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
NFD_LOG_TRACE("createFace: unsupported FacePersistency");
onFailure(406, "Outgoing TCP faces do not support on-demand persistency");
return;
}
tcp::Endpoint endpoint(ip::address::from_string(req.remoteUri.getHost()),
tcp::Endpoint endpoint(ip::make_address(req.remoteUri.getHost()),
boost::lexical_cast<uint16_t>(req.remoteUri.getPort()));
// a canonical tcp4/tcp6 FaceUri cannot have a multicast address
BOOST_ASSERT(!endpoint.address().is_multicast());
if (req.params.wantLocalFields && !endpoint.address().is_loopback()) {
NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
NFD_LOG_TRACE("createFace: cannot create non-local face with local fields enabled");
onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
if (req.params.mtu) {
NFD_LOG_TRACE("createFace cannot create a TCP face with an overridden MTU");
NFD_LOG_TRACE("createFace: cannot create TCP face with overridden MTU");
onFailure(406, "TCP faces do not support MTU overrides");
return;
}
@@ -200,8 +201,9 @@ TcpFactory::createChannel(const tcp::Endpoint& endpoint)
if (it != m_channels.end())
return it->second;
auto channel = make_shared<TcpChannel>(endpoint, m_wantCongestionMarking,
bind(&TcpFactory::determineFaceScopeFromAddresses, this, _1, _2));
auto channel = make_shared<TcpChannel>(endpoint, m_wantCongestionMarking, [this] (auto&&... args) {
return determineFaceScopeFromAddresses(std::forward<decltype(args)>(args)...);
});
m_channels[endpoint] = channel;
return channel;
}
@@ -213,8 +215,8 @@ TcpFactory::doGetChannels() const
}
ndn::nfd::FaceScope
TcpFactory::determineFaceScopeFromAddresses(const boost::asio::ip::address& localAddress,
const boost::asio::ip::address& remoteAddress) const
TcpFactory::determineFaceScopeFromAddresses(const ip::address& localAddress,
const ip::address& remoteAddress) const
{
if (m_local(localAddress) && m_local(remoteAddress)) {
return ndn::nfd::FACE_SCOPE_LOCAL;
@@ -222,5 +224,4 @@ TcpFactory::determineFaceScopeFromAddresses(const boost::asio::ip::address& loca
return ndn::nfd::FACE_SCOPE_NON_LOCAL;
}
} // namespace face
} // namespace nfd
} // namespace nfd::face
+14 -16
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2018, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,14 +27,15 @@
#define NFD_DAEMON_FACE_TCP_FACTORY_HPP
#include "protocol-factory.hpp"
#include "network-predicate.hpp"
#include "tcp-channel.hpp"
namespace nfd {
namespace face {
namespace nfd::face {
/** \brief Protocol factory for TCP over IPv4 and IPv6
/**
* \brief Protocol factory for TCP over IPv4 and IPv6.
*/
class TcpFactory : public ProtocolFactory
class TcpFactory final : public ProtocolFactory
{
public:
static const std::string&
@@ -43,33 +44,31 @@ public:
using ProtocolFactory::ProtocolFactory;
/**
* \brief Create TCP-based channel using tcp::Endpoint
* \brief Create TCP-based channel using tcp::Endpoint.
*
* tcp::Endpoint is really an alias for boost::asio::ip::tcp::endpoint.
* tcp::Endpoint is an alias for boost::asio::ip::tcp::endpoint.
*
* If this method is called twice with the same endpoint, only one channel
* will be created. The second call will just return the existing channel.
*
* \return always a valid pointer to a TcpChannel object, an exception
* \return Always a valid pointer to a TcpChannel object, an exception
* is thrown if it cannot be created.
*/
shared_ptr<TcpChannel>
createChannel(const tcp::Endpoint& localEndpoint);
private:
/** \brief process face_system.tcp config section
*/
void
doProcessConfig(OptionalConfigSection configSection,
FaceSystem::ConfigContext& context) override;
FaceSystem::ConfigContext& context) final;
void
doCreateFace(const CreateFaceRequest& req,
const FaceCreatedCallback& onCreated,
const FaceCreationFailedCallback& onFailure) override;
const FaceCreationFailedCallback& onFailure) final;
std::vector<shared_ptr<const Channel>>
doGetChannels() const override;
doGetChannels() const final;
ndn::nfd::FaceScope
determineFaceScopeFromAddresses(const boost::asio::ip::address& local,
@@ -79,11 +78,10 @@ private:
bool m_wantCongestionMarking = false;
std::map<tcp::Endpoint, shared_ptr<TcpChannel>> m_channels;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
IpAddressPredicate m_local;
};
} // namespace face
} // namespace nfd
} // namespace nfd::face
#endif // NFD_DAEMON_FACE_TCP_FACTORY_HPP
Loaded 100 of 538 files, more files were not shown because too many files have changed in this diff. Show more