133 Commits
Author SHA1 Message Date
Davide Pesavento fd1e940648 Switch to Face::getIoContext() and simplify some code
Change-Id: Iba49171f6e59ead02283e8f975219ab97fcbeb00
2023-11-13 15:40:41 -05:00
Davide Pesavento 5849ee7582 build: require boost >= 1.71.0
Refs: #5276
Change-Id: I6eaae86beb89e00adf3891deb87816a1f176fdd6
2023-11-12 20:00:21 -05:00
Junxiao Shi 2ecb059eb9 lsa: define NameLsa operator==
refs #4094

Change-Id: I99650cb3c6c452b157595a394c30227e47aa88c8
2023-08-27 20:27:34 +00:00
Junxiao Shi 20377645fb lsa: split test suites and reduce includes
refs #4094

Change-Id: I25817cc4786711432b0af60c7819a54b6e41311a
2023-08-27 20:27:17 +00:00
Junxiao Shi 6593a43fa3 route: use ndn::FaceUri type for faceUri
refs #4227

Change-Id: I1b0d7ed97e43e4d0c50770ed306cbe85382dfc9a
2023-08-25 10:06:59 +00:00
Junxiao Shi 931ca9f576 name-prefix-list: delete unused methods and cleanup tests
Unit tests for NamePrefixList type are deduplicated. This allows
deleting countSources() method and NamePair type, which were used
sparsely in the unit tests and not needed by the rest of the codebase.

refs #4094

Change-Id: Id5a6e6b90f863dfeef2ed71e67a9823d84088a48
2023-08-21 10:14:46 +00:00
Davide Pesavento cd77aabaa9 build: update waf to version 2.0.26
Change-Id: I786be093be266ccd1720cc5c7752b00323ee09b6
2023-08-21 02:42:11 +00:00
Davide Pesavento eed3209c8d build: sync default build flags with ndn-cxx
Refactor default-compiler-flags.py to reduce duplication

Change-Id: I71b9255caed4d9262d73155c392a202ec7674e71
2023-08-21 02:42:00 +00:00
Davide Pesavento 5110a8a4ee build: align minimum build requirements with ndn-cxx
Change-Id: Ia28aabc9e496f7467fa58525cde97d44ad159003
2023-08-21 02:41:43 +00:00
Junxiao Shi 52f16644ab name-prefix-list: compare names only in operator==
NamePrefixList type is now a sorted container. The sort() method is
deleted.

The remove() method is renamed to erase(), in accordance with ndn-cxx
code style recommendations.

refs #4094

Change-Id: I2d3f2fa768a8dd9a51108f6f4064243b21fd6df8
2023-08-21 01:47:10 +00:00
Junxiao Shi 43f37a08fc Change namespace of DummyClientFace, Signal, Segmenter, SegmentFetcher
refs #3940

Change-Id: Ia3c9b4adcca9ff79a14be705ca9da525914f3dff
2023-08-20 02:23:22 +00:00
Saurab Dulal ecb0b7180e Prepare release 0.7.0
Change-Id: I3d707d1f1684879fa9133ac87d1b53710465dea1
2023-08-17 21:48:54 -04:00
Junxiao Shi 771a0de40c tests: change FaceId in test-nlsr and test-fib
DummyClientFace is no longer overwriting FaceId of prefix registration
reply, so that we can use FaceId other than 1.

refs #5011

Change-Id: I50ff0a6ee023ebe5cc78e6d62a45ce375798ad41
2023-08-14 10:49:07 +00:00
Davide Pesavento 907675bd06 tests: fix sync prefix test if SVS support is disabled
Amends a2599dafa9

Change-Id: I21b4379ad83f2241ad6749759ac3a95d98929a17
2023-08-02 20:11:12 -04:00
Varun Patil 7543f590a3 sync: use incomingFace for SVS
Change-Id: I28c24fd6d8da58fdfd7f125736ac22af91179fed
2023-07-21 18:15:59 +00:00
Varun Patil a2599dafa9 comm: do not use localhop for SVS
SVS does not work with localhop; Sync Interests need to
be forwarded at the network layer to all nodes in the group.

Change-Id: I32cba55f98f5a77257dd249d1b7c92d78460b39b
2023-07-19 16:56:16 -07:00
Junxiao Shi f7ea150405 tools: exit with non-zero on advertise/withdraw error
refs #5271

Change-Id: I287fc5746ac1fd2930bb85ac49e5ad732abd3581
2023-06-23 04:30:19 +00:00
Davide Pesavento 658fd85bc7 Avoid using deprecated ndn-cxx type aliases
Change-Id: I55fd500377698adc8035113bdff2d64091a36e07
2023-05-10 22:15:03 -04:00
Davide Pesavento 070ee3b52d Add missing include
Change-Id: Ia350ad412e931c96b963595019f361a6f0181c4e
2023-03-16 22:36:36 -04:00
Davide Pesavento e0ad5808e3 tests: fix two dangling-reference warnings with gcc 13
Change-Id: Iccb9045eaa468f4af7782dc466bd8a28a53ffa73
2023-02-20 21:10:03 -05:00
Davide Pesavento fa54ee99b4 ci: adopt reusable workflows from named-data/actions
Switch source archive (tarball) to xz compression

Change-Id: I3e1963bc1f101b7815f1919b4a16da973261f158
2023-02-20 04:22:42 -05:00
Davide Pesavento 1e9faf1d1b build: bump ndn-cxx, ChronoSync, PSync dependencies
Also fix a few outdated URLs in docs

Change-Id: I4269ca53f55433568e8fd93eec497697c01b3c6d
2023-01-21 16:04:50 -05:00
Davide Pesavento 1b640fd092 docs: improve formatting and document structure
Change-Id: I530d58f2700eb264855843021db32f568d373a1d
2023-01-05 04:02:02 -05:00
Davide Pesavento fcef058206 build: update waf to version 2.0.24
Change-Id: I2b367680138454e51c7aa82d3b93de70d4573d12
2022-12-06 15:08:05 -05:00
Varun Patil 7d2d689d89 communication: add SVS support
Change-Id: I74c5a091c8b1c05dd186a0c10849aa5bb4f39e50
Signed-off-by: Varun Patil <varunpatil@ucla.edu>
2022-12-05 15:27:56 +00:00
Davide Pesavento 65ee992149 lsdb: use ndn-cxx's Segmenter
This commit also makes lld the preferred linker on Linux

Change-Id: I178ca7d28ad21d8a1e3f3daf99f80206e8b1c54e
2022-11-20 22:08:09 -05:00
Davide Pesavento 69904fcb73 tests: fix compatibility with signed Interests in v0.3 format
Change-Id: I52bd2bfb5d9551614e2cf012b19b966d84306368
2022-10-14 09:45:34 -04:00
Davide Pesavento 1954a0c5ce communication: adapt to API changes in PSync
Pass the KeyChain instance to psync::FullProducer

Change-Id: Ia97356dc364c7bdaf6dc80ad57fa351eeabe997d
2022-09-30 16:40:24 -04:00
Davide Pesavento d1cb063482 docs: simplify conf.py and fix compatibility with upcoming Sphinx 6.0
Change-Id: Ib68b2cf40c9b3e74251bb87aa76ca18b7e371f3c
2022-09-25 14:11:23 -04:00
Davide Pesavento ede5963845 build+ci: support CentOS Stream 9 and macOS/arm64
This commit also syncs the CI config and scripts with ndn-cxx

Change-Id: Ie46b1d4b299bc95b03aa05d48efe366e1c72d54d
2022-08-26 20:35:44 -04:00
Davide Pesavento c1d0e8e34d build: migrate to C++17
Change-Id: Ic9f09efd20b608bfcb713fd319834b2666cf6242
2022-06-29 15:04:57 -04:00
awlane 0c87b12458 lsdb: Fix for issues involving incorrect retransmission behavior
Change-Id: I912ca04ccc8303f0c621cd5065553193d09bd26f
2022-06-17 15:53:10 -05:00
Dylan fabe9729b9 Re-add exception handler for dummy keychain
refs: #5206
Change-Id: I8099a99892e62c9365732a53b20f2f5030a67cc7
2022-05-24 16:51:31 -04:00
Alexander Afanasyev 135288cf4f lsdb: Fetch LSA from the face the notification about LSAs came from
Change-Id: Iadb7a22bcc8b2d7801787e5d88b37eec4eafc974
2022-05-24 16:12:14 -04:00
Davide Pesavento 8de8a8b37a tests: sync common testing infrastructure with ndn-cxx
Change-Id: I1e5cdcda8f6d3d9f9addc7a9f17359aedef9db7e
2022-05-12 01:26:43 -04:00
Junxiao Shi b032fcb38f conf+security: accommodate certificate name in KeyLocator
refs #5195

Change-Id: I88709f891fe78fc9f2699bc021d35ca72ebc6850
2022-04-28 01:28:50 +00:00
Davide Pesavento 583473a76f 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: I265b23eb21a5c229b8ce7b4099b342cecd4925a3
2022-04-20 13:23:06 -04:00
Davide Pesavento e28d8756ce Avoid deprecated ndn-cxx functions
Change-Id: I763368c2ea12902b4ea400f92c23b17ad5a5628e
2022-03-19 03:55:25 -04:00
Davide Pesavento d1f1df802c 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)

Also improve some test cases

Change-Id: Ib81d082a19e61940fa6f1d89204ea8de8ed57940
2022-03-12 16:40:37 -05:00
Junxiao Shi a3a63975d1 nlsrc: run command on remote router
refs #4544

Change-Id: I977ebfb94c84730bd2bcc73515f77cc4773ec2de
2022-01-24 02:03:41 +00:00
Davide Pesavento ea94f83039 build: update waf to version 2.0.23
Change-Id: I0d8a12968548fcf183cd2183a53b27690e13237c
2022-01-02 18:46:23 -05:00
Davide Pesavento cf14807f7d ci: add code coverage reporting via gcovr
Change-Id: Idc442d4e960360f0c82bcfda0bc8c97004b5d0aa
2021-11-06 19:38:01 -04:00
Davide Pesavento 7bc3d438e7 Improve error handling and reporting
Change-Id: I41a58409c1d488ab2038ae534851e1ab59c6d952
2021-10-26 23:11:04 -04:00
Davide Pesavento ba8a4ed2d2 ci: replace Travis with GitHub Actions
Change-Id: I6316bc7872fe25644dceafb1e2e2119c9c6e5ac3
2021-10-13 21:58:29 -04:00
Davide Pesavento 7ae8b08fc2 build+docs: align minimum requirements with ndn-cxx/NFD
* Recommend boost >= 1.65.1 and gcc >= 7.4.0
 * Require clang >= 4.0, or Xcode >= 9.0 on macOS
 * Silence an ABI-related diagnostic message from gcc on armv7
 * Update waf to version 2.0.21
 * Make graphviz optional for building documentation
 * Sync sphinx configuration

Change-Id: Ib271da841cd12e7595ae83d75bd0fc681f8c231f
2021-10-13 21:57:36 -04:00
Ashlesh Gawande 6f0f35d96d fib: fix route unregister bug during update
refs: #5179

Change-Id: I19952ebcb0c78c405f3d820694a7b0f1cf7a3fe6
2021-09-06 21:20:31 -07:00
Ashlesh Gawande 3781c7ebc1 NameLsa: fix Lsdb update bug by sorting the NPLs before difference
Change-Id: Ib3d5bbf546de3356e0594732ca09671d7c32dbf1
2021-06-11 07:42:18 -07:00
Davide Pesavento 22520e68f5 Fix build with BOOST_FILESYSTEM_NO_DEPRECATED
Change-Id: Ibdd3e7c4de0e8a0a4d6ae08c26386ea780f97f57
2021-06-08 22:16:52 -04:00
Davide Pesavento 6184c2088b Use InterestSigner instead of deprecated CommandInterestSigner
Change-Id: Idb2f1ee7fe99981c229b4a587ebcf671b876e624
2021-05-17 02:28:03 -04:00
Ashlesh Gawande e63b7fa7dc Fix recurring sync prefix registration on every hello data
refs: #5157

Change-Id: Id0f77789976bd84720d2f96b549013b285e58978
2021-04-11 10:47:00 -07:00
Eric Newberry 04bfe0465a tests: make agnostic to whether name components typed or markers
refs #5044

Change-Id: If776224368556c864d6e1db74260cc00ff68d9fa
2021-04-02 11:03:51 -07:00
Ashlesh Gawande 30d96e4875 Do not compile ChronoSync support by default
ChronoSync dependency is now made optional
and is kept for testing purposes only.

Also change sig-type to ecdsa-sha256 in nlsr.conf
as ndn-cxx now has strict checking for it.

refs: #5147

Change-Id: I95c9fb844681ebf2c4e7bbb03cc7796a0795de83
2021-03-27 11:00:40 -07:00
Davide Pesavento 6002e6ab4b tests: explicitly set CanBePrefix in one more place
Refs: #4582
Change-Id: I000d09a0a936db873d50129b66cadfd21a621200
2021-03-17 15:37:32 -04:00
Ashlesh Gawande 5d93aa5b04 lsdb: emit signals when modified
RoutingTable and NamePrefixTable consume the signal
and behave accordingly.

refs: #4127

Change-Id: I6540f30f0222f804b01dc7d9640831c84e5264cc
2021-02-27 08:04:41 -08:00
Davide Pesavento d90338d230 Replace remaining uses of BOOST_THROW_EXCEPTION with NDN_THROW
Change-Id: I0c149acbe5607d928cdf9e8d73813d5e74ca45d0
2021-01-08 11:50:43 -05:00
Saurab Dulal cf06444860 Prepare release 0.6.0
Change-Id: I8c08855856fe781a244695f3eec702bf8f7ba7cc
2021-01-07 11:46:55 -06:00
Ashlesh Gawande 214032e7ac hello-protocol: fix wrong reaction on hello Interest timeout
refs: #5139

Change-Id: If043a618106633de8d1414c81dddf29af6576dff
2020-12-30 18:33:03 -08:00
Ashlesh Gawande 0af4627ad7 tools: fix compilation for ubuntu 16.04
Change-Id: Ifdbc43994e0060b67ffb94a72fdac026671a3be2
2020-12-12 16:58:57 -05:00
Davide Pesavento e4edb3952c Add missing include
Fixes compilation with gcc 10

Change-Id: I54f0808c7519b8bf1a668f05c4d09d4ca3d3b11f
2020-12-06 14:05:45 -05:00
Davide Pesavento d8d6bbcbe6 tests: fix range-loop-construct warning with clang 10 and later
Change-Id: I69a40705201f07147dccb21b3aea2db4f384b24e
2020-11-24 21:38:44 -05:00
Davide Pesavento 4a90b9ae52 ci: disable frames in lcov HTML coverage report
Change-Id: I82d521b75b9e05aa56f12c19a0b159e2ef966a6d
2020-08-09 02:21:46 -04:00
Ashlesh Gawande 7a231c0dc1 route: replace FibEntry class with struct
fix warnings from ndn-cxx

Change-Id: I1be322251dcfe5d867717a64547e1908b99c78ba
2020-07-28 22:11:20 -07:00
Ashlesh GawandeandNick Gordon 57a8717ec7 lsdb: rebuild using boost::multi_index to replace 3 LSA lists
refs: #4127

Co-authored-by: Nick Gordon <nmgordon@memphis.edu>

Change-Id: Ic179f90019e472157b0d61c6db02a4afaf4843b6
2020-07-18 19:17:26 -07:00
Ashlesh Gawande 0421bc6bcd **breaking** route: consolidate routing tlv into route
refs: #5116

Plus some misc improvements

Change-Id: Id0902fec65160b4368b1b5066f460433aced98ed
2020-06-12 07:09:40 -07:00
Alexander Afanasyev 0ad01f3834 Adjust includes for the updated locations of ndn-cxx security headers
Change-Id: I01787a91cdb70b7136f3c4e9e646e68888e6d064
2020-06-10 12:24:26 -04:00
Alexander Afanasyev 96ebd9b7c3 Rename VERSION to VERSION.info to avoid conflicts with modern STL
On case-insensitive file systems (e.g., macOS), inclusion of the new
standard <version> header resulted in unexpected inclusion of VERSION
file.

Change-Id: I84d6e37fd5f31666ced4b8b47816ff28dd911f17
2020-06-01 19:16:52 -04:00
Davide Pesavento a122abf5f6 ci: update Travis configuration
* Add testing on arm64, ppc64le, and s390x with select compiler versions
 * Drop clang 3.9
 * Reenable ASan on Linux with clang 7, the upstream bug has been fixed
 * Add clang 11 (development branch)
 * Drop Xcode 9.2 (macOS 10.12 is no longer supported)
 * Replace Xcode 11 with 11.3 and 11.4
 * Various cleanups

Change-Id: I7c27cb7765961eb5b057406b0a69d6e40b0e4ca8
2020-05-01 02:51:34 -04:00
Davide Pesavento 4b9d30f8e2 src: fix -Wrange-loop-construct warning with clang 10
Change-Id: Ife00440ffa456c6ad2119fc656a34681327e0ab3
2020-05-01 02:48:34 -04:00
Davide Pesavento f6be8e37f6 build+ci: switch to python3
Also in this commit:
 * Sync CI scripts with other projects
 * Modernize docs/conf.py
 * Replace redmine_issue extension with sphinx.ext.extlinks
 * Minor updates to docs/doxygen.conf.in
 * Cleanup README.md and INSTALL.rst

Refs: #5095
Change-Id: I614e876e6aed73659f4f4cea01813f4604599263
2020-04-30 19:45:26 -04:00
Ashlesh Gawande 0db4d4d8fc **breaking** consolidate src/tlv/*lsa* into src/lsa/*lsa*
Lsa de/serialize functions are replaced by wireEncode/Decode.
Update LSA wire formats. Change TLV assignments as required.
Update nlsrc to print using new encoding.

refs: #4787

Change-Id: Ie8d40b7836d51ea5bb444c8db208dc2b3a0d1cec
2020-04-14 20:06:01 -07:00
Ashlesh Gawande f89878c12c tlv: remove unused class LsdbStatus
refs: #4787

Change-Id: I9c7ce59238a3bac06d3db32423853f11f22e9160
2020-03-31 19:18:46 -07:00
Davide Pesavento fd021d5e3d build: upgrade waf to version 2.0.19
Change-Id: I34f4e78b109012f44aab597e2990a95dde9162ca
2020-02-24 00:42:41 -05:00
Saurab Dulal 1158c55878 Prepare release 0.5.2
Change-Id: If4489a9fcb7f2bdb9c9f2315dca932aa93f847ed
2020-02-19 09:33:58 -06:00
Saurab Dulal 427e012304 security: refactor CertificateStore class
Refs: #5075

Change-Id: I8ab92012b3acf405503ab33c9320463accc682a9
2020-02-13 23:05:28 -06:00
Eric Newberry 4a5334cba7 docs: restructure and update AUTHORS.md
refs #5078

Change-Id: Id87c4fa070170dc6bcf68d3b27a5ce8e372e9ca3
2020-02-05 17:20:04 -08:00
Ashlesh Gawande 55d1b5c2c0 sequencing-manager: remove support for old combined seq no file
refs: #4143

Change-Id: I3334ef136f75b18225828ebfba17f63c468708db
2020-01-13 21:17:33 -08:00
Davide Pesavento cb065f1773 tests: sync common test infrastructure with ndn-cxx
Change-Id: I6f2ee4b5b644d6fddcebbe1158b1dd9ad2159417
2019-12-27 01:03:34 -05:00
Ashlesh Gawande 328fc11217 conf-file-processor: fix empty file creation if conf file is same as dynamic
refs: #5071

Change-Id: I031381156d3c9aee21bb8ab7d018a37189e4a321
2019-12-12 17:27:48 -06:00
Ashlesh Gawande 6b388fc36d src: change initialization order
Send Hello Interest after route to neighbor is successfully registered
--> First Hello interval is eliminated
--> After Hello Nack, wait exponentially before processing it as a timeout
Register sync route for each neighbor after its Hello Data is validated

refs: #5009

Change-Id: Ice39a591f1e58e474b494d93c913fa45e10f24f2
2019-11-13 19:16:50 -06:00
Davide Pesavento f75bfdaa34 build: pass pkg_config_path to check_cfg()
Instead of modifying os.environ

Refs: #5042
Change-Id: Ibc17cf8f310ccd058ebacc3151fa6b4e3d355319
2019-11-10 18:34:13 -05:00
Ashlesh Gawande 842b1cf1f0 src: do not crash if identity cannot be created
This is useful during testing with dummy keychain to save overhead

Change-Id: I73eee512aba9afc3d768270e0e5b4212c7adf058
2019-10-03 22:16:56 -05:00
Davide Pesavento d21d83d892 ci: upgrade Travis config to Ubuntu 18.04
Also in this commit:

 * Drop clang 3.8 (no easy way to install it on 18.04)
 * Add clang 10 (trunk)
 * Drop Xcode 8.3
 * Upgrade Xcode 10.2 to 10.3
 * Add Xcode 11

Change-Id: I5b18eee860dd5e92ec51ae832998b57aa7681854
2019-10-01 01:00:02 -04:00
Ashlesh Gawande 4187857a9a src: onFaceEventNotification only proceed if face id was zero or updated
refs: #5010

Change-Id: Ie5b1f8a5ca2a372890a9ef2a28dc00e1a7c0a366
2019-09-30 13:36:26 -05:00
dulalsaurab d0816a3ced route: handle zero cost links
refs: #4978

Change-Id: I461bdac9e10cb8362a7624b177ee68aa20d3ff3e
2019-09-03 14:53:30 -05:00
Nick Gordon c64bed22a8 publisher: remove unused functions
Change-Id: Ifc9a590de11fa841b1d27027d46a9376c5dff41f
refs: #4127
2019-07-22 09:33:57 -05:00
Tianxing Ma 9ea3639be2 tlv: Use the encoding/decoding functions for "double" from ndn-cxx
refs: #4615

Change-Id: I0bde7085876646f272ee6006f4d3cfbd513d4ffd
2019-07-16 16:32:02 -05:00
Davide Pesavento cf22053914 ci: add gcc-9 to Travis CI build matrix
Change-Id: I9c7d2c42390f1314e57745c7459962dd98788f8a
2019-06-25 13:43:17 -04:00
dulalsaurab 348321368d Prepare release 0.5.1
Change-Id: I96ce5a15fe653cc59650edec2a9e42c2253f99a1
2019-06-12 21:33:06 -05:00
Ashlesh Gawande 08bce9c325 src: set best-route strategy for certificate prefixes
refs: #4881

Change-Id: I655c261233e478bf01ff298b74af5eb62a33ffaf
2019-05-25 08:20:39 -07:00
Junxiao Shi 0b1b7d9ff4 tests: add FreshnessPeriod where MustBeFresh is used
refs #4913

Change-Id: Idf7e85b46ea9530678b51bf1f472ecfcfca5773f
2019-05-22 15:37:18 +00:00
Ashlesh Gawande 15052408e9 src: use InMemoryStoragePersistent instead of custom LsaSegmentStorage
refs: #4788

Change-Id: Ie5d8721915864ead2f30e7f5e6181f56acefc559
2019-03-26 11:02:26 -05:00
Ashlesh Gawande dec85d2da4 src: disable network interest in CertificateFetcherDirectFetch
refs: #4879

Change-Id: I6b34b34710bdfcdf0a82327637be83bc452b16d9
2019-03-22 14:03:59 -05:00
Davide Pesavento af7a2113e4 Follow ndn::Scheduler API changes
Switch from ndn::EventId to ndn::scheduler::EventId
and simplify some code.

Refs: #4883
Change-Id: Ifbd3b00da441ca0a277900265f8f6e31fdcebf2a
2019-03-20 08:01:58 -07:00
Davide Pesavento 0b0eddd60c ci: update .travis.yml and jenkins scripts
Change-Id: I315196cb9d8e96f46e706a78c2d15d856a0a8d8b
2019-03-19 14:42:15 -04:00
Ashlesh Gawande 9ecbdc95c5 src: fix canonization by resetting io service after each neighbor
refs: #4872

Change-Id: I87e83eb36f1a17d0dc2633f04c529f71d751a497
2019-03-12 16:45:12 -05:00
Saurab Dulal b2fea6d79f NLSR Release 0.5.0: Minor change to AUTHORS.md file
Change-Id: I79f62495583a57e24e1c589e80e47d0e1d8095e1
2019-02-24 15:53:00 -06:00
Saurab Dulal d3b60a8b24 Prepare release 0.5.0
Change-Id: I8ebb2f5779d7da0c0b6c2f11cc9c653e8d3b1d90
2019-02-23 17:34:26 -06:00
Davide Pesavento 0da3eab4da Add systemd unit file
Refs: #4594
Change-Id: I415bafa14902e9d43be4891f66349192e12b9166
2019-02-22 13:50:37 -06:00
dulalsaurab 82a34c2cd8 **breaking change** nlsr.conf: rename seq-dir as state-dir
update: conf file in seperate directory for runtime modification

refs:  #4823

Change-Id: I5378d831294814e382ad23a9e522d0b576180f20
2019-02-19 15:49:38 -06:00
Ashlesh Gawande 85998a1dc9 src: decouple classes from Nlsr object
refs: #1952, #2803, #3960, #4288

Change-Id: Ibe3ac3820f11e8107ee4b13e510d53c27467a6cb
2019-02-01 14:23:55 -06:00
Ashlesh Gawande 7e3f6d75c8 src: move and simplify canonize functionality to ConfFileProcessor
refs: #4817

Change-Id: I0a7f448f50994906d0403bcb97a3973dc1a25917
2019-02-01 11:54:48 -06:00
Davide Pesavento e3c741da9a main: fix error handling and normalize exit codes
Change-Id: I3b6d6dd1f5a8fac3ec4998bd81af80a232350337
2019-01-30 23:45:32 -05:00
Davide Pesavento 5859ed3dfb Use the official markdown version of the GPLv3
Change-Id: I5de645c2b29c29e2927e19b12831c0b336ad54b7
2019-01-29 19:49:09 -05:00
Davide Pesavento e556991595 build: various updates
* Upgrade waf to 2.0.14
 * Sync default compiler flags with ndn-cxx

Change-Id: I9e5bbbc7c13d1770e6ac0b0b5f5c0fbe17f89f23
2019-01-29 19:39:06 -05:00
Saurab Dulal 72b2b25cd2 route: remove redundant function
refs: #4811

Change-Id: I31b1031f57a344e7c3176b917ffbad2f6b2bd821
2019-01-25 05:06:50 -06:00
laqinfan 7c13ba5448 nlsrc: demarcate LS and HR routing table in dry run mode
refs: #4452

Change-Id: I522493e473810f90e4e982b35a58310154816cae
2019-01-22 21:47:51 -06:00
Junxiao Shi 008c9b18a5 tests: set CanBePrefix in test suites
refs #4581

Change-Id: Ia53e2a865dbc8a422626640d8d7f3878e49066ba
2019-01-13 23:15:56 +00:00
Saurab Dulal 7526cee087 update: Add/delete prefix to the conf file
refs: #4303

Change-Id: I401885bf76be90a5076365eebc311275461813c4
2019-01-08 20:56:09 -06:00
Ashlesh Gawande 939b6f8652 src: use psync::SegmentPublisher and fix proccessing of interests w/ segments
refs: #4784, #4760

Change-Id: Ia017a6f340e1cd35991068453c9da595c453ca1f
2018-12-22 15:45:50 -06:00
Ashlesh Gawande e5002b3fc4 fib: don't refresh neighbor router's FIB entry (it is already installed w/ expiry=never)
refs: #4799

Change-Id: Ib55687655ccd8673eeae14d8418e458ad8ab00aa
2018-12-21 12:18:49 -06:00
Ashlesh Gawande 32ec3fd51e communication: sync protocol adapater to add psync
refs: #4082

Change-Id: Ibe4649e709dfbc3cdc1f2afbfc4ff03f75a3f136
2018-12-10 10:38:41 -06:00
David Arjona 2fa23ea104 docs: Improving documentation for NLSR
Change-Id: Iada3c9bbc56b53fb66bfea1c99ef2204afaf9039
2018-12-07 12:29:20 -06:00
Ashlesh Gawande 744e481642 ci: enable leak sanitizer
src: fix memory leaks caused by segment fetcher

refs: #4682

Change-Id: I4fdf24f369e2d27845f1f6e6ca9978905110a024
2018-11-25 10:43:40 -08:00
ashiqopu 8433cfeace ci: install gcovr via apt
Change-Id: I0e24a2299c99d4e685a9bb5a1ddba34d06ba2f77
refs: #4771
2018-11-25 06:47:37 +00:00
David Arjona 2e6c8bb896 docs: A beginners' guide to installing and testing on Fedora
Change-Id: I2345fe8443981dab60782f8daa8c4ae0b107a1bf
2018-11-15 16:44:25 -06:00
Ashlesh Gawande 3494f7366a src: disallow interest loopbacks
refs: #4768

Change-Id: If5ec53fc9869b65e318c3eaf950708cfa36e658a
2018-11-06 17:30:40 -06:00
Ashlesh Gawande 05cb728c63 src+tools: use segment fetcher start
jenkins: re-compile ChronoSync on ndn-cxx change

refs: #4464

Change-Id: Ia627e00b8f13bad0068e213a6019f62a84cad41a
2018-09-25 17:55:43 -05:00
Ashlesh Gawande 057005460e hello-protocol: set canBePrefix to true
refs: #4691, #4679

Change-Id: I5f57d7bb6a75af074fc64206fe6061f2fc758b40
2018-08-28 11:13:28 -07:00
Ashlesh Gawande e8d8bd5276 adjacency-list: fix crash in equals operator
some minor code improvements

refs: #4705

Change-Id: I28805981a88a94c79f699956bb7e62a268d9ba49
2018-08-26 13:25:27 -05:00
Ashlesh Gawande 481010723b communication: use ChronoSync Logic instead of Socket
refs: #4623

Change-Id: I6950af9d92a254b4fe05f7570ab6bc8b8a9599c8
2018-06-08 13:12:04 -07:00
Davide Pesavento a08dc3f1f1 build: require gcc >= 5.3 and switch to C++14
Change-Id: I93c8fc238cc2654346bbc69a9d8ea83d1c0b099e
Refs: #3076, #4462
2018-06-06 16:27:47 -04:00
Saurab Dulal 301220346e docs: Prepare version 0.4.3 release notes
Change-Id: I0b3a6166eac489be67ea03ff69a13ffe35616f63
2018-05-21 12:54:11 -05:00
Ashlesh Gawande 8df15986ef tlv: avoid misaligned memory access
They cause unit test crashing on ARM platform.

refs: #4609

Change-Id: Ifdb0401529de48b5c08ebcf6938d80ba87ff883d
2018-05-19 22:21:25 -07:00
Ryan Wickman f3c79a6f87 src: make LSA's isEqualContent methods of type const
refs: #4137
Change-Id: Idb1cdea33d4efbc3af3c07d901a620d3ef253979
2018-05-10 20:15:01 -05:00
Ashlesh Gawande cba0ae2f56 **breaking** Change NLSR to nlsr for various prefixes
src: register router prefix to fix remote requests

refs: #4543

Change-Id: I698484318bf8e641f955ea40e6c51c6865cad8bf
2018-04-19 14:34:29 -05:00
Eric Newberry f1a8ee66de build: find Boost lib architecture automatically
refs #4573

Change-Id: I383f821bc651926ba5d2ed830b20dd3116e8a3fc
2018-04-07 16:38:47 -07:00
Ashlesh Gawande d65786a0ea src/lsa-segment-storage: fix convergence w/o content store
refs: #4430

Change-Id: I5124e9fd49bd9850c904c31d221b42b4249553a3
2018-04-02 22:55:17 -05:00
Ashlesh Gawande e6ba9158e0 Fix build with clang-5.0
refs: #4547

Change-Id: I7fd0411b3dc7c62651875aa035bbfb6ca269bf81
2018-03-30 16:20:27 -05:00
Eric Newberry aa41b04807 docs: disable sphinxcontrib-googleanalytics
refs #4553

Change-Id: I94529272787b0facd9370f9c6fca06435a636093
2018-03-26 15:16:43 -07:00
Alexander Afanasyev 67758b1fba build: update waf to version 2.0.6
Fix discovered build issues

Change-Id: I9a861c955283c1b20cc5065a4baa22bd7c2ab0c1
2018-03-11 12:17:41 -04:00
Ashlesh Gawande 350d58489b docs: Prepare version 0.4.2 release notes
Change-Id: I36780f66b803b6049e5399fde6e1a097c40a65b3
2018-03-05 12:04:31 -06:00
Ashlesh Gawande 8c6d8c831a lsa-segment-storage: fix segfault in scheduled erase of lsa segment
refs: #4520

Change-Id: I597604b4be9e063a08ff5031faa8d305408b676d
2018-03-01 12:54:15 -06:00
Ashlesh Gawande 0b27c1ff5c Update symlink to latest release notes
Change-Id: I0956f0be737af0b4d43810ff7c7c91fd89982c8a
2018-02-26 14:35:53 -06:00
229 changed files with 12123 additions and 16783 deletions

No files matched your search

+16
View File
@@ -0,0 +1,16 @@
name: CI
on:
push:
paths-ignore:
- 'docs/**'
- '*.md'
- '.mailmap'
workflow_dispatch:
permissions: {}
jobs:
Ubuntu:
uses: named-data/actions/.github/workflows/jenkins-script-ubuntu.yml@v1
macOS:
uses: named-data/actions/.github/workflows/jenkins-script-macos.yml@v1
+21
View File
@@ -0,0 +1,21 @@
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:
# Deploy only the master branch and release tags
deploy: ${{ !inputs.skip-deploy && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/NLSR-')) }}
secrets: inherit
man:
uses: named-data/actions/.github/workflows/docs-man.yml@v1
+32 -7
View File
@@ -1,7 +1,32 @@
.DS*
.waf-1*
.waf3-*
.lock*
**/*.pyc
build/
VERSION
# Emacs
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
.\#*
# Visual Studio Code
.vscode/
# KDevelop
*.kdev*
# macOS
.DS_Store
.AppleDouble
.LSOverride
._*
# Waf build system
/build/
.waf-*-*/
.waf3-*-*/
.lock-waf*
# Compiled python code
__pycache__/
*.py[cod]
# Other
/VERSION.info
+46 -4
View File
@@ -1,10 +1,52 @@
#!/usr/bin/env bash
set -e
set -eo pipefail
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
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
for file in "$DIR"/.jenkins.d/*; do
export CACHE_DIR=${CACHE_DIR:-/tmp}
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
echo "Run: $file"
if [[ -n $GITHUB_ACTIONS ]]; then
label=$(basename "$file" | sed -E 's/[[:digit:]]+-(.*)\..*/\1/')
echo "::group::${label}"
fi
echo "\$ $file"
"$file"
if [[ -n $GITHUB_ACTIONS ]]; then
echo "::endgroup::"
fi
done
+29 -25
View File
@@ -1,34 +1,38 @@
#!/usr/bin/env bash
set -e
set -eo pipefail
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
APT_PKGS=(build-essential pkg-config python3-minimal
libboost-all-dev libssl-dev libsqlite3-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 has OSX $NODE_LABELS; then
FORMULAE=(boost pkg-config openssl)
if [[ $ID == macos ]]; then
if [[ -n $GITHUB_ACTIONS ]]; then
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
fi
brew update
if [[ -n $TRAVIS ]]; then
# travis images come with a large number of brew packages
# pre-installed, don't waste time upgrading all of them
for FORMULA in "${FORMULAE[@]}"; do
brew outdated $FORMULA || brew upgrade $FORMULA
done
else
brew upgrade
fi
brew install "${FORMULAE[@]}"
brew cleanup
fi
if has Ubuntu $NODE_LABELS; then
brew install --formula "${FORMULAE[@]}"
elif [[ $ID_LIKE == *debian* ]]; then
sudo apt-get -qq update
sudo apt-get -qy install build-essential pkg-config libboost-all-dev \
libsqlite3-dev libssl-dev
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
fi
if [[ $JOB_NAME == *"code-coverage" ]]; then
sudo apt-get -qy install lcov libgd-perl python-setuptools
sudo easy_install --upgrade gcovr
fi
if (( ${#PIP_PKGS[@]} )); then
pip3 install --user --upgrade --upgrade-strategy=eager "${PIP_PKGS[@]}"
fi
+17 -23
View File
@@ -1,16 +1,11 @@
#!/usr/bin/env bash
set -e
set -exo pipefail
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
set -x
pushd "${CACHE_DIR:-/tmp}" >/dev/null
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
@@ -22,35 +17,34 @@ if [[ -z $INSTALLED_VERSION ]]; then
INSTALLED_VERSION=$(git -C ndn-cxx rev-parse HEAD 2>/dev/null || echo NONE)
fi
sudo rm -Rf ndn-cxx-latest
git clone --depth 1 git://github.com/named-data/ndn-cxx ndn-cxx-latest
sudo rm -rf ndn-cxx-latest
git clone --depth 1 https://github.com/named-data/ndn-cxx.git ndn-cxx-latest
LATEST_VERSION=$(git -C ndn-cxx-latest rev-parse HEAD 2>/dev/null || echo UNKNOWN)
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
sudo rm -Rf ndn-cxx
sudo rm -rf ndn-cxx
mv ndn-cxx-latest ndn-cxx
else
sudo rm -Rf ndn-cxx-latest
sudo rm -rf ndn-cxx-latest
fi
sudo rm -f /usr/local/bin/ndnsec*
sudo rm -fr /usr/local/include/ndn-cxx
sudo rm -f /usr/local/lib/libndn-cxx*
sudo rm -f /usr/local/lib/pkgconfig/libndn-cxx.pc
sudo rm -f /usr/local/lib{,64}/libndn-cxx*
sudo rm -f /usr/local/lib{,64}/pkgconfig/libndn-cxx.pc
pushd ndn-cxx >/dev/null
./waf configure --color=yes --enable-shared --disable-static --without-osx-keychain
./waf build --color=yes -j${WAF_JOBS:-1}
sudo env "PATH=$PATH" ./waf install --color=yes
./waf --color=yes configure --without-osx-keychain
./waf --color=yes build
sudo ./waf --color=yes install
popd >/dev/null
popd >/dev/null
if has Linux $NODE_LABELS; then
if [[ $ID_LIKE == *fedora* ]]; then
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
fi
if [[ $ID_LIKE == *linux* ]]; then
sudo ldconfig
elif has FreeBSD10 $NODE_LABELS; then
sudo ldconfig -m
fi
+26 -36
View File
@@ -1,59 +1,49 @@
#!/usr/bin/env bash
set -e
set -exo pipefail
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
PROJ=ChronoSync
set -x
pushd "${CACHE_DIR:-/tmp}" >/dev/null
pushd "$CACHE_DIR" >/dev/null
INSTALLED_VERSION=
if has OSX $NODE_LABELS; then
BOOST=$(brew ls --versions boost)
OLD_BOOST=$(cat boost_chrono.txt || :)
if [[ $OLD_BOOST != $BOOST ]]; then
echo "$BOOST" > boost_chrono.txt
INSTALLED_VERSION=NONE
fi
NDN_CXX=$(ndnsec version)
OLD_NDN_CXX=$(cat "$PROJ-ndn-cxx.txt" || :)
if [[ $OLD_NDN_CXX != $NDN_CXX ]]; then
echo "$NDN_CXX" > "$PROJ-ndn-cxx.txt"
INSTALLED_VERSION=NONE
fi
if [[ -z $INSTALLED_VERSION ]]; then
INSTALLED_VERSION=$(git -C ChronoSync rev-parse HEAD 2>/dev/null || echo NONE)
INSTALLED_VERSION=$(git -C "$PROJ" rev-parse HEAD 2>/dev/null || echo NONE)
fi
sudo rm -Rf ChronoSync-latest
git clone --depth 1 git://github.com/named-data/ChronoSync ChronoSync-latest
LATEST_VERSION=$(git -C ChronoSync-latest rev-parse HEAD 2>/dev/null || echo UNKNOWN)
sudo rm -rf "$PROJ-latest"
git clone --depth 1 "https://github.com/named-data/$PROJ.git" "$PROJ-latest"
LATEST_VERSION=$(git -C "$PROJ-latest" rev-parse HEAD 2>/dev/null || echo UNKNOWN)
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
sudo rm -Rf ChronoSync
mv ChronoSync-latest ChronoSync
sudo rm -rf "$PROJ"
mv "$PROJ-latest" "$PROJ"
else
sudo rm -Rf ChronoSync-latest
sudo rm -rf "$PROJ-latest"
fi
sudo rm -fr /usr/local/include/ChronoSync
sudo rm -f /usr/local/lib/libChronoSync*
sudo rm -f /usr/local/lib/pkgconfig/ChronoSync*
sudo rm -fr /usr/local/include/"$PROJ"
sudo rm -f /usr/local/lib{,64}/lib"$PROJ"*
sudo rm -f /usr/local/lib{,64}/pkgconfig/"$PROJ".pc
pushd ChronoSync >/dev/null
pushd "$PROJ" >/dev/null
if has FreeBSD10 $NODE_LABELS; then
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/
fi
./waf configure --color=yes
./waf build --color=yes -j${WAF_JOBS:-1}
sudo env "PATH=$PATH" ./waf install --color=yes
./waf --color=yes configure
./waf --color=yes build
sudo ./waf --color=yes install
popd >/dev/null
popd >/dev/null
if has Linux $NODE_LABELS; then
if [[ $ID_LIKE == *fedora* ]]; then
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
fi
if [[ $ID_LIKE == *linux* ]]; then
sudo ldconfig
elif has FreeBSD10 $NODE_LABELS; then
sudo ldconfig -m
fi
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
set -exo pipefail
PROJ=PSync
pushd "$CACHE_DIR" >/dev/null
INSTALLED_VERSION=
NDN_CXX=$(ndnsec version)
OLD_NDN_CXX=$(cat "$PROJ-ndn-cxx.txt" || :)
if [[ $OLD_NDN_CXX != $NDN_CXX ]]; then
echo "$NDN_CXX" > "$PROJ-ndn-cxx.txt"
INSTALLED_VERSION=NONE
fi
if [[ -z $INSTALLED_VERSION ]]; then
INSTALLED_VERSION=$(git -C "$PROJ" rev-parse HEAD 2>/dev/null || echo NONE)
fi
sudo rm -rf "$PROJ-latest"
git clone --depth 1 "https://github.com/named-data/$PROJ.git" "$PROJ-latest"
LATEST_VERSION=$(git -C "$PROJ-latest" rev-parse HEAD 2>/dev/null || echo UNKNOWN)
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
sudo rm -rf "$PROJ"
mv "$PROJ-latest" "$PROJ"
else
sudo rm -rf "$PROJ-latest"
fi
sudo rm -fr /usr/local/include/"$PROJ"
sudo rm -f /usr/local/lib{,64}/lib"$PROJ"*
sudo rm -f /usr/local/lib{,64}/pkgconfig/"$PROJ".pc
pushd "$PROJ" >/dev/null
./waf --color=yes configure
./waf --color=yes build
sudo ./waf --color=yes install
popd >/dev/null
popd >/dev/null
if [[ $ID_LIKE == *fedora* ]]; then
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
fi
if [[ $ID_LIKE == *linux* ]]; then
sudo ldconfig
fi
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
set -exo pipefail
PROJ=ndn-svs
pushd "$CACHE_DIR" >/dev/null
INSTALLED_VERSION=
NDN_CXX=$(ndnsec version)
OLD_NDN_CXX=$(cat "$PROJ-ndn-cxx.txt" || :)
if [[ $OLD_NDN_CXX != $NDN_CXX ]]; then
echo "$NDN_CXX" > "$PROJ-ndn-cxx.txt"
INSTALLED_VERSION=NONE
fi
if [[ -z $INSTALLED_VERSION ]]; then
INSTALLED_VERSION=$(git -C "$PROJ" rev-parse HEAD 2>/dev/null || echo NONE)
fi
sudo rm -rf "$PROJ-latest"
git clone --depth 1 "https://github.com/named-data/$PROJ.git" "$PROJ-latest"
LATEST_VERSION=$(git -C "$PROJ-latest" rev-parse HEAD 2>/dev/null || echo UNKNOWN)
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
sudo rm -rf "$PROJ"
mv "$PROJ-latest" "$PROJ"
else
sudo rm -rf "$PROJ-latest"
fi
sudo rm -fr /usr/local/include/"$PROJ"
sudo rm -f /usr/local/lib{,64}/lib"$PROJ"*
sudo rm -f /usr/local/lib{,64}/pkgconfig/"$PROJ".pc
pushd "$PROJ" >/dev/null
./waf --color=yes configure
./waf --color=yes build
sudo ./waf --color=yes install
popd >/dev/null
popd >/dev/null
if [[ $ID_LIKE == *fedora* ]]; then
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
fi
if [[ $ID_LIKE == *linux* ]]; then
sudo ldconfig
fi
+22 -31
View File
@@ -1,45 +1,36 @@
#!/usr/bin/env bash
set -e
set -eo pipefail
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
if [[ -z $DISABLE_ASAN ]]; then
ASAN="--with-sanitizer=address"
fi
if [[ $JOB_NAME == *"code-coverage" ]]; then
COVERAGE="--with-coverage"
fi
set -x
git submodule init
git submodule sync
git submodule update
if [[ $JOB_NAME == *"code-coverage" ]]; then
COVERAGE="--with-coverage"
elif [[ -z $DISABLE_ASAN ]]; then
ASAN="--with-sanitizer=address"
fi
# Cleanup
sudo env "PATH=$PATH" ./waf --color=yes distclean
if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
# Configure/build in optimized mode with tests
./waf --color=yes configure --with-tests
./waf --color=yes build -j${WAF_JOBS:-1}
# Build in release mode with tests
./waf --color=yes configure --with-tests
./waf --color=yes build
# Cleanup
sudo env "PATH=$PATH" ./waf --color=yes distclean
# Cleanup
./waf --color=yes distclean
# Configure/build in optimized mode without tests
./waf --color=yes configure
./waf --color=yes build -j${WAF_JOBS:-1}
# Build in release mode without tests
./waf --color=yes configure
./waf --color=yes build
# Cleanup
sudo env "PATH=$PATH" ./waf --color=yes distclean
# Cleanup
./waf --color=yes distclean
fi
# Configure/build in debug mode with tests
./waf --color=yes configure --debug --with-tests $ASAN $COVERAGE
./waf --color=yes build -j${WAF_JOBS:-1}
# Build in debug mode with tests
./waf --color=yes configure --debug --with-chronosync --with-psync --with-svs --with-tests $ASAN $COVERAGE
./waf --color=yes build
# (tests will be run against debug version)
# (tests will be run against the debug version)
# Install
sudo env "PATH=$PATH" ./waf --color=yes install
sudo ./waf --color=yes install
+20 -16
View File
@@ -1,23 +1,27 @@
#!/usr/bin/env bash
set -e
set -x
# Prepare environment
rm -Rf ~/.ndn
ut_log_args() {
echo --log_level=test_suite
}
set -eo pipefail
# https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
ASAN_OPTIONS="color=always"
ASAN_OPTIONS+=":detect_stack_use_after_return=true"
ASAN_OPTIONS+=":check_initialization_order=true"
ASAN_OPTIONS+=":strict_init_order=true"
ASAN_OPTIONS+=":detect_invalid_pointer_pairs=1"
ASAN_OPTIONS+=":detect_container_overflow=false"
ASAN_OPTIONS+=":strict_string_checks=true"
ASAN_OPTIONS+=":check_initialization_order=1"
ASAN_OPTIONS+=":detect_stack_use_after_return=1"
ASAN_OPTIONS+=":strict_init_order=1"
ASAN_OPTIONS+=":strict_string_checks=1"
ASAN_OPTIONS+=":detect_invalid_pointer_pairs=2"
ASAN_OPTIONS+=":detect_container_overflow=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
export BOOST_TEST_LOGGER=HRF,test_suite,stdout:XML,all,build/xunit-log.xml
set -x
# Prepare environment
rm -rf ~/.ndn
# Run unit tests
./build/unit-tests-nlsr $(ut_log_args)
./build/unit-tests-nlsr
+14 -13
View File
@@ -1,29 +1,30 @@
#!/usr/bin/env bash
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
set -x
set -exo pipefail
if [[ $JOB_NAME == *"code-coverage" ]]; then
# 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 \
--filter src/ \
--exclude-throw-branches \
--exclude-unreachable-branches \
--cobertura build/coverage.xml \
--html-details build/gcovr/ \
--print-summary
# Generate a detailed HTML report using lcov
lcov --quiet \
--capture \
--directory . \
--exclude "$PWD/tests/*" \
--no-external \
--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 \
--frames \
--legend \
--output-directory build/coverage \
--output-directory build/lcov \
--title "NLSR unit tests" \
build/coverage.info
fi
+24 -24
View File
@@ -1,36 +1,36 @@
CONTINUOUS INTEGRATION SCRIPTS
==============================
# Continuous Integration Scripts
Environment Variables Used in Build Scripts
-------------------------------------------
## Environment Variables
- `NODE_LABELS`: the variable defines a list of OS properties. The set values are used by the
build scripts to select proper behavior for different OS.
- `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 include at least `[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.
Possible values for Linux:
Examples:
* `[OS_TYPE]`: `Linux`
* `[DISTRO_TYPE]`: `Ubuntu`
* `[DISTRO_VERSION]`: `Ubuntu-14.04`, `Ubuntu-16.04`
- On CentOS, `ID_LIKE="centos rhel fedora linux"`
- On Ubuntu, `ID_LIKE="ubuntu debian linux"`
Possible values for OS X / macOS:
- `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`.
* `[OS_TYPE]`: `OSX`
* `[DISTRO_TYPE]`: `OSX` (can be absent)
* `[DISTRO_VERSION]`: `OSX-10.10`, `OSX-10.11`, `OSX-10.12`
- `JOB_NAME`: defines the type of the current CI job. Depending on the job type, the CI
scripts can perform different tasks.
- `JOB_NAME`: optional variable to define type of the job. Depending on the defined job type,
the build scripts can perform different tasks.
Supported values:
Possible values:
- empty: default build task
- `code-coverage`: debug build with tests and code coverage analysis
- `limited-build`: only a single debug build with tests
* empty: default build process
* `code-coverage` (Linux OS is assumed): 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`: the variable defines a path to folder containing cached files from previous builds,
e.g., a compiled version of ndn-cxx library. If not set, `/tmp` is used.
- `DISABLE_ASAN`: disable building with AddressSanitizer. This is automatically set for
the `code-coverage` job type.
- `WAF_JOBS`: number of parallel build jobs used by waf, defaults to 1.
[os-release(5)]: https://www.freedesktop.org/software/systemd/man/os-release.html
-18
View File
@@ -1,18 +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}
}
+16
View File
@@ -0,0 +1,16 @@
A K M Mahmudul Hoque <akmhoque@gmail.com>
<agawande@memphis.edu> <ashu2493@gmail.com>
Nick Gordon <nmgordon@memphis.edu>
Laqin Fan <lfan1@memphis.edu>
Syed Obaid Amin <soamin@memphis.edu>
Syed Obaid Amin <soamin@memphis.edu> <obaidasyed@gmail.com>
Syed Obaid Amin <soamin@memphis.edu> <obaid@Obaids-MacBook.local>
Syed Obaid Amin <soamin@memphis.edu> <obaid@obaids-macbook.memphis.edu>
Syed Obaid Amin <soamin@memphis.edu> <soamin@mira.cs.memphis.edu>
Syed Obaid Amin <soamin@memphis.edu> <soamin@wd222yx4.memphis.edu>
Muktadir R Chowdhury <mrchwdhr@memphis.edu>
Muktadir R Chowdhury <mrchwdhr@memphis.edu> <muktadir.rahman.c@gmail.com>
<aa@cs.fiu.edu> <alexander.afanasyev@ucla.edu>
<davidepesa@gmail.com> <davide.pesavento@lip6.fr>
<enewberry@email.arizona.edu> <enewberry@cs.arizona.edu>
Md Ashiqur Rahman <marahman@email.arizona.edu>
-103
View File
@@ -1,103 +0,0 @@
language: cpp
dist: trusty
sudo: required
env:
global:
- JOB_NAME=limited-build
- WAF_JOBS=2
matrix:
include:
# Linux/gcc
# https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages
- os: linux
env: COMPILER=g++-4.8
- os: linux
env: COMPILER=g++-4.9
addons:
apt:
sources: ubuntu-toolchain-r-test
packages: g++-4.9
- os: linux
env: COMPILER=g++-5
addons:
apt:
sources: ubuntu-toolchain-r-test
packages: g++-5
- os: linux
env: COMPILER=g++-6
addons:
apt:
sources: ubuntu-toolchain-r-test
packages: g++-6
- os: linux
env: COMPILER=g++-7
addons:
apt:
sources: ubuntu-toolchain-r-test
packages: g++-7
# Linux/clang
# https://apt.llvm.org/
- os: linux
env: COMPILER=clang++-3.5
addons:
apt:
packages: clang-3.5
- os: linux
env: COMPILER=clang++-3.6
addons:
apt:
packages: clang-3.6
- os: linux
env: COMPILER=clang++-3.7 DISABLE_ASAN=yes
addons:
apt:
sources: ["llvm-toolchain-precise-3.7", "ubuntu-toolchain-r-test"]
packages: clang-3.7
- os: linux
env: COMPILER=clang++-3.8
addons:
apt:
sources: ["llvm-toolchain-precise-3.8", "ubuntu-toolchain-r-test"]
packages: clang-3.8
- os: linux
env: COMPILER=clang++-3.9 DISABLE_ASAN=yes
addons:
apt:
sources: ["llvm-toolchain-trusty-3.9", "ubuntu-toolchain-r-test"]
packages: clang-3.9
- os: linux
env: COMPILER=clang++-4.0
addons:
apt:
sources: ["llvm-toolchain-trusty-4.0", "ubuntu-toolchain-r-test"]
packages: clang-4.0
- os: linux
env: COMPILER=clang++-5.0
addons:
apt:
sources: ["llvm-toolchain-trusty-5.0", "ubuntu-toolchain-r-test"]
packages: clang-5.0
# macOS/clang
# https://docs.travis-ci.com/user/osx-ci-environment/#OS-X-Version
- os: osx
osx_image: xcode7.3
env: OSX_VERSION=10.11
- os: osx
osx_image: xcode8.3
env: OSX_VERSION=10.12
- os: osx
osx_image: xcode9.2
env: OSX_VERSION=10.12
before_script:
- if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-14.04"; fi
- if [[ ${TRAVIS_OS_NAME} == osx ]]; then export NODE_LABELS="OSX OSX-${OSX_VERSION}"; fi
- if [[ -n ${COMPILER} ]]; then export CXX=${COMPILER}; fi
- ${CXX:-c++} --version
- python --version
script:
- ./.jenkins
+54 -39
View File
@@ -54,9 +54,9 @@ from waflib import Utils, Logs, Errors
from waflib.Configure import conf
from waflib.TaskGen import feature, after_method
BOOST_LIBS = ['/usr/lib/x86_64-linux-gnu', '/usr/lib/i386-linux-gnu',
'/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
BOOST_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 = '''
#include <iostream>
@@ -91,13 +91,18 @@ int main() { boost::thread t; }
BOOST_LOG_CODE = '''
#include <boost/log/trivial.hpp>
int main() { BOOST_LOG_TRIVIAL(info) << "boost_log is working"; }
'''
BOOST_LOG_SETUP_CODE = '''
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
int main() {
using namespace boost::log;
add_common_attributes();
add_console_log(std::clog, keywords::format = "%Message%");
BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl;
BOOST_LOG_TRIVIAL(info) << "boost_log_setup is working";
}
'''
@@ -146,7 +151,7 @@ def options(opt):
opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
help='''select libraries with tags (gd for debug, static is automatically added),
see doc Boost, Getting Started, chapter 6.1''')
opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
opt.add_option('--boost-linkage_autodetect', action='store_true', dest='boost_linkage_autodetect',
help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
opt.add_option('--boost-toolset', type='string',
default='', dest='boost_toolset',
@@ -176,7 +181,7 @@ def boost_get_version(self, d):
try:
txt = node.read()
except EnvironmentError:
Logs.error("Could not read the file %r" % node.abspath())
Logs.error('Could not read the file %r' % node.abspath())
else:
re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M)
m1 = re_but1.search(txt)
@@ -184,7 +189,7 @@ def boost_get_version(self, d):
m2 = re_but2.search(txt)
if m1 and m2:
return (m1.group(1), m2.group(1))
return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":")
return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(':')
@conf
def boost_get_includes(self, *k, **kw):
@@ -195,10 +200,10 @@ def boost_get_includes(self, *k, **kw):
if self.__boost_get_version_file(d):
return d
if includes:
self.end_msg('headers not found in %s' % includes)
self.end_msg('headers not found in %s' % includes, 'YELLOW')
self.fatal('The configuration failed')
else:
self.end_msg('headers not found, please provide a --boost-includes argument (see help)')
self.end_msg('headers not found, please provide a --boost-includes argument (see help)', 'YELLOW')
self.fatal('The configuration failed')
@@ -241,10 +246,10 @@ def __boost_get_libs_path(self, *k, **kw):
break
if not path:
if libs:
self.end_msg('libs not found in %s' % libs)
self.end_msg('libs not found in %s' % libs, 'YELLOW')
self.fatal('The configuration failed')
else:
self.end_msg('libs not found, please provide a --boost-libs argument (see help)')
self.end_msg('libs not found, please provide a --boost-libs argument (see help)', 'YELLOW')
self.fatal('The configuration failed')
self.to_log('Found the boost path in %r with the libraries:' % path)
@@ -314,7 +319,7 @@ def boost_get_libs(self, *k, **kw):
libs.append(format_lib_name(file.name))
break
else:
self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
self.end_msg('lib %s not found in %s' % (lib, path.abspath()), 'YELLOW')
self.fatal('The configuration failed')
return libs
@@ -355,7 +360,7 @@ def _check_pthread_flag(self, *k, **kw):
# ... -mt is also the pthreads flag for HP/aCC
# -lpthread: GNU Linux, etc.
# --thread-safe: KAI C++
if Utils.unversioned_sys_platform() == "sunos":
if Utils.unversioned_sys_platform() == 'sunos':
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
@@ -363,23 +368,22 @@ def _check_pthread_flag(self, *k, **kw):
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"]
boost_pthread_flags = ['-pthreads', '-lpthread', '-mt', '-pthread']
else:
boost_pthread_flags = ["", "-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread",
"-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"]
boost_pthread_flags = ['', '-lpthreads', '-Kthread', '-kthread', '-llthread', '-pthread',
'-pthreads', '-mthreads', '-lpthread', '--thread-safe', '-mt']
for boost_pthread_flag in boost_pthread_flags:
try:
self.env.stash()
self.env['CXXFLAGS_%s' % var] += [boost_pthread_flag]
self.env['LINKFLAGS_%s' % var] += [boost_pthread_flag]
self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False)
self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False, quiet=True)
self.end_msg(boost_pthread_flag)
return
except self.errors.ConfigurationError:
self.env.revert()
self.end_msg('None')
self.end_msg('none')
@conf
def check_boost(self, *k, **kw):
@@ -404,16 +408,24 @@ def check_boost(self, *k, **kw):
var = kw.get('uselib_store', 'BOOST')
self.start_msg('Checking boost includes')
self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
versions = self.boost_get_version(inc)
self.env.BOOST_VERSION = versions[0]
self.env.BOOST_VERSION_NUMBER = int(versions[1])
self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000,
int(versions[1]) / 100 % 1000,
int(versions[1]) % 100))
if Logs.verbose:
Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
if not self.env.DONE_FIND_BOOST_COMMON:
self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False)
if self.env.DPKG_ARCHITECTURE:
deb_host_multiarch = self.cmd_and_log([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH'])
BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch.strip())
self.start_msg('Checking boost includes')
self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
versions = self.boost_get_version(inc)
self.env.BOOST_VERSION = versions[0]
self.env.BOOST_VERSION_NUMBER = int(versions[1])
self.end_msg('%d.%d.%d' % (int(versions[1]) / 100000,
int(versions[1]) / 100 % 1000,
int(versions[1]) % 100))
if Logs.verbose:
Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
self.env.DONE_FIND_BOOST_COMMON = True
if not params['lib'] and not params['stlib']:
return
@@ -425,7 +437,7 @@ def check_boost(self, *k, **kw):
self.env['STLIBPATH_%s' % var] = [path]
self.env['LIB_%s' % var] = libs
self.env['STLIB_%s' % var] = stlibs
self.end_msg('ok')
self.end_msg(' '.join(libs + stlibs))
if Logs.verbose:
Logs.pprint('CYAN', ' path : %s' % path)
Logs.pprint('CYAN', ' shared libs : %s' % libs)
@@ -446,15 +458,18 @@ def check_boost(self, *k, **kw):
self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False)
if has_lib('thread'):
self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False)
if has_lib('log'):
if has_lib('log') or has_lib('log_setup'):
if not has_lib('thread'):
self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS']
if has_shlib('log'):
if has_shlib('log') or has_shlib('log_setup'):
self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK']
self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)
if has_lib('log_setup'):
self.check_cxx(fragment=BOOST_LOG_SETUP_CODE, use=var, execute=False)
else:
self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)
if params.get('linkage_autodetect', False):
self.start_msg("Attempting to detect boost linkage flags")
self.start_msg('Attempting to detect boost linkage flags')
toolset = self.boost_get_toolset(kw.get('toolset', ''))
if toolset in ('vc',):
# disable auto-linking feature, causing error LNK1181
@@ -476,10 +491,10 @@ def check_boost(self, *k, **kw):
# we attempt to play with some known-to-work CXXFLAGS combinations
for cxxflags in (['/MD', '/EHsc'], []):
self.env.stash()
self.env["CXXFLAGS_%s" % var] += cxxflags
self.env['CXXFLAGS_%s' % var] += cxxflags
try:
try_link()
self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var]))
self.end_msg('ok: winning cxxflags combination: %s' % (self.env['CXXFLAGS_%s' % var]))
exc = None
break
except Errors.ConfigurationError as e:
@@ -487,17 +502,17 @@ def check_boost(self, *k, **kw):
exc = e
if exc is not None:
self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=exc)
self.end_msg('Could not auto-detect boost linking flags combination, you may report it to boost.py author', ex=exc)
self.fatal('The configuration failed')
else:
self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain")
self.end_msg('Boost linkage flags auto-detection not implemented (needed ?) for this toolchain')
self.fatal('The configuration failed')
else:
self.start_msg('Checking for boost linkage')
try:
try_link()
except Errors.ConfigurationError as e:
self.end_msg("Could not link against boost libraries using supplied options")
self.end_msg('Could not link against boost libraries using supplied options', 'YELLOW')
self.fatal('The configuration failed')
self.end_msg('ok')
+4 -4
View File
@@ -1,15 +1,15 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
from waflib import TaskGen, Logs
from waflib import TaskGen
def options(opt):
opt.add_option('--with-coverage', action='store_true', default=False, dest='with_coverage',
help='''Set compiler flags for gcc to enable code coverage information''')
opt.add_option('--with-coverage', action='store_true', default=False,
help='Add compiler flags to enable code coverage information')
def configure(conf):
if conf.options.with_coverage:
if not conf.options.debug:
conf.fatal("Code coverage flags require debug mode compilation (add --debug)")
conf.fatal('Code coverage flags require debug mode compilation (add --debug)')
conf.check_cxx(cxxflags=['-fprofile-arcs', '-ftest-coverage', '-fPIC'],
linkflags=['-fprofile-arcs'], uselib_store='GCOV', mandatory=True)
+136 -98
View File
@@ -1,73 +1,91 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
from waflib import Logs, Configure, Utils
import platform
from waflib import Configure, Logs, Utils
def options(opt):
opt.add_option('--debug', '--with-debug', action='store_true', default=False, dest='debug',
help='''Compile in debugging mode with minimal optimizations (-O0 or -Og)''')
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')
cxx = conf.env['CXX_NAME'] # CXX_NAME is the generic name of the compiler
ccver = tuple(int(i) for i in conf.env['CC_VERSION'])
cxx = conf.env.CXX_NAME # generic name of the compiler
ccver = tuple(int(i) for i in conf.env.CC_VERSION)
ccverstr = '.'.join(conf.env.CC_VERSION)
errmsg = ''
warnmsg = ''
if cxx == 'gcc':
if ccver < (4, 8, 2):
if ccver < (7, 4, 0):
errmsg = ('The version of gcc you are using is too old.\n'
'The minimum supported gcc version is 4.8.2.')
flags = GccFlags()
'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 ccver < (3, 4, 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 3.4.0.')
flags = ClangFlags()
'The minimum supported clang version is 7.0.')
conf.flags = ClangFlags()
else:
warnmsg = 'Note: %s compiler is unsupported' % cxx
flags = CompilerFlags()
warnmsg = f'{cxx} compiler is unsupported'
conf.flags = CompilerFlags()
if errmsg:
conf.end_msg('.'.join(conf.env['CC_VERSION']), color='RED')
conf.end_msg(ccverstr, color='RED')
conf.fatal(errmsg)
elif warnmsg:
conf.end_msg('.'.join(conf.env['CC_VERSION']), color='YELLOW')
Logs.warn(warnmsg)
conf.end_msg(ccverstr, color='YELLOW')
Logs.warn('WARNING: ' + warnmsg)
else:
conf.end_msg('.'.join(conf.env['CC_VERSION']))
conf.end_msg(ccverstr)
areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
conf.areCustomCxxflagsPresent = len(conf.env.CXXFLAGS) > 0
# General flags are always applied (e.g., selecting C++11 mode)
generalFlags = flags.getGeneralFlags(conf)
# General flags are always applied (e.g., selecting C++ language standard)
generalFlags = conf.flags.getGeneralFlags(conf)
conf.add_supported_cxxflags(generalFlags['CXXFLAGS'])
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
# corresponding environment variables are not set.
# DEFINES are always applied.
if conf.options.debug:
extraFlags = flags.getDebugFlags(conf)
if areCustomCxxflagsPresent:
extraFlags = conf.flags.getDebugFlags(conf)
if conf.areCustomCxxflagsPresent:
missingFlags = [x for x in extraFlags['CXXFLAGS'] if x not in conf.env.CXXFLAGS]
if len(missingFlags) > 0:
Logs.warn("Selected debug mode, but CXXFLAGS is set to a custom value '%s'"
% " ".join(conf.env.CXXFLAGS))
Logs.warn("Default flags '%s' are not activated" % " ".join(missingFlags))
if missingFlags:
Logs.warn('Selected debug mode, but CXXFLAGS is set to a custom value "%s"'
% ' '.join(conf.env.CXXFLAGS))
Logs.warn('Default flags "%s" will not be used' % ' '.join(missingFlags))
else:
extraFlags = flags.getOptimizedFlags(conf)
extraFlags = conf.flags.getOptimizedFlags(conf)
if not areCustomCxxflagsPresent:
if not conf.areCustomCxxflagsPresent:
conf.add_supported_cxxflags(extraFlags['CXXFLAGS'])
conf.add_supported_linkflags(extraFlags['LINKFLAGS'])
conf.env.DEFINES += extraFlags['DEFINES']
@Configure.conf
def add_supported_cxxflags(self, cxxflags):
"""
Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
Check which cxxflags are supported by the active compiler and add them to env.CXXFLAGS variable.
"""
if len(cxxflags) == 0:
return
@@ -75,17 +93,19 @@ def add_supported_cxxflags(self, cxxflags):
self.start_msg('Checking supported CXXFLAGS')
supportedFlags = []
for flag in cxxflags:
if self.check_cxx(cxxflags=['-Werror', flag], mandatory=False):
supportedFlags += [flag]
for flags in cxxflags:
flags = Utils.to_list(flags)
if self.check_cxx(cxxflags=['-Werror'] + flags, mandatory=False):
supportedFlags += flags
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
@@ -93,18 +113,26 @@ def add_supported_linkflags(self, linkflags):
self.start_msg('Checking supported LINKFLAGS')
supportedFlags = []
for flag in linkflags:
if self.check_cxx(linkflags=['-Werror', flag], mandatory=False):
supportedFlags += [flag]
for flags in linkflags:
flags = Utils.to_list(flags)
if self.check_cxx(linkflags=['-Werror'] + flags, mandatory=False):
supportedFlags += flags
self.end_msg(' '.join(supportedFlags))
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_ASIO_NO_DEPRECATED', 'BOOST_FILESYSTEM_NO_DEPRECATED'],
}
def getDebugFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
@@ -114,89 +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++11']
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'] += ['-O0',
'-Og', # gcc >= 4.8, clang >= 4.0
'-g3',
'-pedantic',
'-Wall',
'-Wextra',
'-Werror',
'-Wno-error=deprecated-declarations', # Bug #3795
'-Wno-error=maybe-uninitialized', # Bug #1615
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-fuse-ld=gold', '-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',
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-fuse-ld=gold', '-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)
version = tuple(int(i) for i in conf.env['CC_VERSION'])
if version < (5, 1, 0):
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
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)
version = tuple(int(i) for i in conf.env['CC_VERSION'])
if version < (5, 1, 0):
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
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':
flags['CXXFLAGS'] += ['-stdlib=libc++']
flags['LINKFLAGS'] += ['-stdlib=libc++']
# Bug #4296
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',
'-Wno-error=deprecated-register',
'-Wno-error=ignored-qualifiers',
'-Wno-error=infinite-recursion', # Bug #3358
'-Wno-error=keyword-macro', # Bug #3235
'-Wno-error=unneeded-internal-declaration', # Bug #1588
'-Wno-keyword-macro',
'-Wno-nested-anon-types',
'-Wno-sign-compare',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
return flags
def getOptimizedFlags(self, conf):
flags = super(ClangFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wno-keyword-macro',
'-Wno-nested-anon-types',
'-Wno-sign-compare',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
return flags
+8 -8
View File
@@ -44,28 +44,28 @@ def apply_sphinx(self):
task.inputs.append(conf)
confdir = conf.parent.abspath()
buildername = getattr(self, "builder", "html")
srcdir = getattr(self, "srcdir", confdir)
outdir = self.path.find_or_declare(getattr(self, "outdir", buildername)).get_bld()
doctreedir = getattr(self, "doctreedir", os.path.join(outdir.abspath(), ".doctrees"))
buildername = getattr(self, 'builder', 'html')
srcdir = getattr(self, 'srcdir', confdir)
outdir = self.path.find_or_declare(getattr(self, 'outdir', buildername)).get_bld()
doctreedir = getattr(self, 'doctreedir', os.path.join(outdir.abspath(), '.doctrees'))
task.env['BUILDERNAME'] = buildername
task.env['SRCDIR'] = srcdir
task.env['DOCTREEDIR'] = doctreedir
task.env['OUTDIR'] = outdir.abspath()
task.env['VERSION'] = "version=%s" % self.VERSION
task.env['RELEASE'] = "release=%s" % self.VERSION
task.env['VERSION'] = 'version=%s' % self.version
task.env['RELEASE'] = 'release=%s' % getattr(self, 'release', self.version)
import imp
confData = imp.load_source('sphinx_conf', conf.abspath())
if buildername == "man":
if buildername == 'man':
for i in confData.man_pages:
target = outdir.find_or_declare('%s.%d' % (i[1], i[4]))
task.outputs.append(target)
if self.install_path:
self.bld.install_files("%s/man%d/" % (self.install_path, i[4]), target)
self.bld.install_files('%s/man%d/' % (self.install_path, i[4]), target)
else:
task.outputs.append(outdir)
+34 -53
View File
@@ -1,57 +1,38 @@
NLSR Authors
============
# NLSR Authors
NLSR is an open source project includes contributions from the members of the
[NDN project team](http://named-data.net/project/participants/).
The following lists maintainers, primary developers, and all much-appreciated contributors to NLSR in alphabetical order.
The specific contributions of individual authors can be obtained from the git history of the [official NLSR repository](https://github.com/named-data/NLSR).
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>.
## Project co-leads:
* Alexander Afanasyev <https://users.cs.fiu.edu/~afanasyev>
* Adam Alyyan <https://github.com/a64adam>
* Syed Obaid Amin <http://obaidamin.weebly.com/>
* Pedro David Arjona Villicaña <https://github.com/david-arjona>
* Muktadir R. Chowdhury <https://github.com/alvyC>
* Damian Coomes <https://github.com/dmcoomes>
* ***(Maintainer)*** Saurab Dulal <https://dulalsaurab.github.io>
* Laqin Fan <https://github.com/laqinfan>
* Simon Fayer <https://github.com/sfayer>
* ***(Former Maintainer)*** Ashlesh Gawande <https://www.linkedin.com/in/agawande>
* ***(Former Maintainer)*** Nicholas Gordon <https://github.com/gorgonical>
* ***(Former Maintainer)*** A. K. M. Mahmudul Hoque <https://sites.google.com/site/akmhoque/home>
* ***(Former Maintainer)*** Vince Lehman <http://vslehman.com>
* Tianxing Ma <https://github.com/matianxing1992>
* Spyridon Mastorakis <https://sites.google.com/site/spyridonmastorakis>
* Eric Newberry <https://ericnewberry.com>
* João Pereira <http://website.jpereira.co.uk>
* Davide Pesavento <https://github.com/Pesa>
* Md Ashiqur Rahman <https://ashiqrahman.com>
* Junxiao Shi <https://cs.arizona.edu/~shijunxiao>
* Salvatore Signorello <https://wwwen.uni.lu/snt/people/salvatore_signorello>
* Jiewen Tan <https://www.linkedin.com/in/jiewentan>
* Alejandro Gil Torres <https://github.com/gltorres>
* Ryan Wickman <http://rwickman.github.io>
* Yingdi Yu <https://irl.cs.ucla.edu/~yingdi>
* Minsheng Zhang <https://www.linkedin.com/in/minsheng-zhang-032023a1>
* Ashlesh Gawande <https://www.linkedin.com/in/agawande>
* Nicholas Gordon <nmgordon@memphis.edu>
## Technical Advisors
## Past project leads:
* A K M Mahmudul Hoque <https://sites.google.com/site/akmhoque/home>
* Vince Lehman <http://vslehman.com>
## Technical advisors:
* Lan Wang <http://www.cs.memphis.edu/~lanwang/>
* Beichuan Zhang <http://www.cs.arizona.edu/~bzhang/>
* Lixia Zhang <http://www.cs.ucla.edu/~lixia/>
## All project authors, contributors and their affiliations:
* The University of Memphis
* A K M Mahmudul Hoque <https://sites.google.com/site/akmhoque/home>
* Ashlesh Gawande <https://www.linkedin.com/in/agawande>
* Minsheng Zhang <https://www.linkedin.com/in/minsheng-zhang-032023a1>
* Syed Obaid Amin <http://obaidamin.weebly.com/>
* Vince Lehman <http://vslehman.com>
* Muktadir R Chowdhury <mrchwdhr@memphis.edu>
* Nicholas Gordon <nmgordon@memphis.edu>
* Laqin Fan <lfan1@memphis.edu>
* Damian Coomes <dmcoomes@memphis.edu>
* Saurab Dulal <sdulal@memphis.edu>
* University of California, Los Angeles
* Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/web/index.html>
* Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
* Spyridon Mastorakis <http://cs.ucla.edu/~mastorakis/>
* Jiewen Tan <https://www.linkedin.com/in/jiewentan>
* University of Arizona
* Junxiao Shi <https://www.linkedin.com/in/shijunxiao>
* University Pierre & Marie Curie, Sorbonne University
* Davide Pesavento <https://www.linkedin.com/in/davidepesavento>
## Queries about NLSR
Any question related to NLSR should be directed to Ashlesh Gawande (agawande@memphis.edu),
Muktadir R Chowdhury (mrchwdhr@memphis.edu), and Nicholas Gordon (nmgordon@memphis.edu).
* Lan Wang <http://www.cs.memphis.edu/~lanwang>
* Beichuan Zhang <https://cs.arizona.edu/~bzhang>
* Lixia Zhang <https://web.cs.ucla.edu/~lixia>
+371 -370
View File
File diff suppressed because it is too large. Load diff
+18 -18
View File
@@ -1,15 +1,17 @@
Requirements
------------
# Notes for NLSR developers
Contributions to NLSR must be licensed under GPL 3.0 or compatible license. If you are
choosing GPL 3.0, please use the following license boilerplate in all `.hpp` and `.cpp`
files:
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).
Include the following header in all `.hpp` and `.cpp` files:
## Licensing requirements
Contributions to NLSR 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; -*- */
/**
* Copyright (c) [Year(s)], [Copyright Holder(s)].
/*
* Copyright (c) [Year(s)], [Copyright Holder(s)].
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
@@ -24,17 +26,15 @@ Include the following header in all `.hpp` and `.cpp` files:
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
If you are affiliated with an NSF-supported NDN project institution,
please use the [NDN Team License Boilerplate]
(https://redmine.named-data.net/projects/nlsr/wiki/NDN_Team_License_Boilerplate_(NLSR)).
If you are affiliated with an NSF-supported NDN project institution, please use the [NDN Team License
Boilerplate](https://redmine.named-data.net/projects/nlsr/wiki/NDN_Team_License_Boilerplate_(NLSR)).
Recommendations
---------------
## Recommendations
NLSR code is subject to the code style, defined here:
https://redmine.named-data.net/projects/nfd/wiki/CodeStyle
NLSR code is subject to the code style defined
[here](https://redmine.named-data.net/projects/nfd/wiki/CodeStyle).
NLSR Developer's guide can be found here:
https://github.com/named-data/NLSR/blob/developers-guide/NLSR-Developers-Guide.pdf
NLSR Developer's guide can be found
[here](https://github.com/named-data/NLSR/blob/developers-guide/NLSR-Developers-Guide.pdf).
+31 -31
View File
@@ -1,51 +1,51 @@
NLSR - Named Data Link State Routing Protocol
=============================================
# NLSR: Named Data Link State Routing Protocol
For complete documentation and more extensive information,
please visit the [NLSR homepage](http://named-data.net/doc/NLSR/current/).
[![CI](https://github.com/named-data/NLSR/actions/workflows/ci.yml/badge.svg)](https://github.com/named-data/NLSR/actions/workflows/ci.yml)
[![Docs](https://github.com/named-data/NLSR/actions/workflows/docs.yml/badge.svg)](https://github.com/named-data/NLSR/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/NLSR?label=Latest%20version)
If you are new to the NDN community of software generally, read the
[Contributor's Guide](https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md).
> For more extensive documentation, please visit the [NLSR homepage](https://docs.named-data.net/NLSR/current/).
## Overview
NLSR is a routing protocol in NDN that populates NDN's Routing Information Base. NLSR
will continue to evolve alongside the Named Data Networking [protocol](http://named-data.net/doc/ndn-tlv/).
NLSR is a routing protocol for Named Data Networking (NDN) that populates the Routing Information
Base (RIB) of an NDN router, such as [NFD](https://github.com/named-data/NFD). NLSR continues to
evolve alongside the core [NDN protocol](https://docs.named-data.net/NDN-packet-spec/current/).
NLSR is an open and free software package licensed under the GPL 3.0 license and free to all
Internet users and developers. For more information about the licensing details and
limitations, refer to [COPYING.md](https://github.com/named-data/NLSR/blob/master/COPYING.md).
NLSR is developed by the members of the [NSF-sponsored NDN project team](https://named-data.net/project/participants/).
For more details, please refer to [AUTHORS.md](https://github.com/named-data/NLSR/blob/master/AUTHORS.md).
Bug reports and feedback are highly appreciated and can be made through the
[Redmine site](https://redmine.named-data.net/projects/nlsr).
The main design goal of NLSR is to provide a routing protocol to populate NDN's FIB.
The main design goal of NLSR is to provide a routing protocol to populate NDN's RIB.
NLSR calculates the routing table using link-state or hyperbolic routing and produces
multiple faces for each reachable name prefix in a single authoritative domain. NLSR
will continue to evolve over time to include neighbor discovery and to become a full
fledged inter-domain routing protocol for NDN.
NLSR was mainly developed by members of the NSF-sponsored [NDN project team](
https://named-data.net/project/participants/). See [`AUTHORS.md`](AUTHORS.md) for details.
Source releases
---------------
## Source releases
The source code and source-code installation instructions are always available at
the following links:
The source code and installation instructions are available at the following locations:
- [Installation](https://named-data.net/doc/NLSR/current/INSTALL.html)
- [Getting Started with NLSR](https://named-data.net/doc/NLSR/current/GETTING-STARTED.html)
- [GitHub NLSR repository](https://github.com/named-data/NLSR)
- [Installation](https://docs.named-data.net/NLSR/current/INSTALL.html)
- [Getting started with NLSR](https://docs.named-data.net/NLSR/current/GETTING-STARTED.html)
- [NLSR GitHub repository](https://github.com/named-data/NLSR)
Additional information
----------------------
## Reporting bugs
- [Contributor's Guide](https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md)
- [NLSR Wiki](https://redmine.named-data.net/projects/nlsr/wiki/)
- Feature requests and bug reports are welcome on our
[NLSR on NDN Redmine](https://redmine.named-data.net/projects/nlsr)
Please submit any bug reports or feature requests to the
[NLSR issue tracker](https://redmine.named-data.net/projects/nlsr/issues).
## Additional resources
- [Contributor's Guide](https://github.com/named-data/.github/blob/main/CONTRIBUTING.md)
- [NLSR Wiki](https://redmine.named-data.net/projects/nlsr/wiki)
- [NLSR Issue Tracker](https://redmine.named-data.net/projects/nlsr/issues)
- [NLSR Mailing List Sign Up](https://listserv.memphis.edu/scripts/wa.exe?GETPW1)
- [NLSR Mailing List](https://listserv.memphis.edu/scripts/wa.exe?SUBED1=NLSR-HELP-L&A=1)
- [NLSR Mailing List Archives](https://listserv.memphis.edu/scripts/wa.exe?A0=NLSR-HELP-L)
- [NLSR Developer's guide](https://github.com/named-data/NLSR/blob/developers-guide/NLSR-Developers-Guide.pdf)
## License
NLSR is free software distributed under the GNU General Public License version 3.
See [`COPYING.md`](COPYING.md) for details.
+21 -12
View File
@@ -7,14 +7,13 @@ Getting Started with NLSR
Getting Source
--------------
- `GitHub NLSR repository <https://github.com/named-data/NLSR>`_
- `GitHub NLSR repository <https://github.com/named-data/NLSR>`__
Installation
------------
:doc:`INSTALL`
Important Notes About Configuration
-----------------------------------
@@ -23,10 +22,9 @@ specified in ``nlsr.conf``. Instead, it relies on the pre-existence of
the Faces in NFD. NLSR will obtain this information from NFD, and
configure its neighbors using this information.
For people who were relying on NLSR to automagically configure their
networks, this must now be done with ``nfdc``. Its documentation can
be found `here
<https://named-data.net/doc/NFD/current/manpages/nfdc.html>`_
For users who were relying on NLSR to automagically configure their networks,
this must now be done with ``nfdc``. See ``man nfdc`` for its documentation
(`online version <https://docs.named-data.net/NFD/current/manpages/nfdc.html>`__).
Configuration
-------------
@@ -70,9 +68,20 @@ value are enabled.
ERROR error messages
FATAL fatal (will be logged unconditionally)
To obtain logs for NLSR, set the NDN_LOG environment variable with the correct prefix and
log-level settings. For example, running the command `export NDN_LOG=nlsr.*=TRACE && nlsr`
will display all log messages in NLSR with a DEBUG level or below. If the user is presented
with an error message `User does not have read and write permission on the directory` it can
be circumvented by running the application with sudo: `sudo env NDN_LOG=nlsr.*=DEBUG nlsr`.
Use `man ndn-log` for more detailed instructions.
To obtain logs for NLSR, set the ``NDN_LOG`` environment variable with the correct prefix
and log-level settings. For example, running the following command will display all log
messages in NLSR with a DEBUG level or below.
.. code-block:: sh
NDN_LOG='nlsr.*=DEBUG' nlsr
If the user is presented with an error message "User does not have read and write
permission on the directory" it can be circumvented by running the application with sudo:
.. code-block:: sh
sudo env NDN_LOG='nlsr.*=DEBUG' nlsr
See ``man ndn-log`` for more details (`online version
<https://docs.named-data.net/ndn-cxx/current/manpages/ndn-log.html>`__).
+32 -13
View File
@@ -7,36 +7,55 @@ NLSR Installation Instructions
Prerequisites
-------------
- `NFD <http://named-data.net/doc/NFD/current/>`_ and its requirements:
- `NFD <https://github.com/named-data/NFD>`__ and its dependencies.
Refer to `Getting started with NFD <http://named-data.net/doc/NFD/current/INSTALL.html>`_
for detailed installation and running instruction.
Check out the `documentation <https://docs.named-data.net/NFD/current/INSTALL.html>`__
for detailed installation and running instructions.
- ChronoSync library
- PSync library [optional but recommended, enabled by default]
::
Download the PSync library and build it according to the instructions available at
https://github.com/named-data/PSync#build
https://github.com/named-data/ChronoSync#build
- ChronoSync library [optional, deprecated]
For testing purposes, NLSR can be optionally built with ChronoSync support. Download
the ChronoSync library and build it according to the instructions available at
https://github.com/named-data/ChronoSync#build
- SVS library [optional]
NLSR can be used with State Vector Sync as the underlying Sync protocol. Download
the ndn-svs library and build it according to the instructions available at
https://github.com/named-data/ndn-svs#installation
Note that at least one Sync library must be enabled.
Build
-----
Execute the following commands to build NLSR:
::
.. code-block:: sh
./waf configure
./waf
sudo ./waf install
Refer to ``./waf –help`` for more options that can be used during the configure stage and
Refer to ``./waf --help`` for more options that can be used during the configure stage and
how to properly configure NLSR.
If your pkgconfig path is not set properly you can do the following before running ``./waf
configure``
If your pkgconfig path is not set properly, you can do the following before running ``./waf
configure``:
::
.. code-block:: sh
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/
or
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
# or
export PKG_CONFIG_PATH=/path/to/pkgconfig/on/your/machine
If ChronoSync support is desired, NLSR needs to be configured with the following option:
.. code-block:: sh
./waf configure --with-chronosync
-4
View File
@@ -1,4 +0,0 @@
NLSR Release Notes
==================
.. include:: release-notes-latest.rst
+14 -3
View File
@@ -35,6 +35,9 @@ The number represents the connecting face id. For example,
We will walk through setting up the faces and creating the configuration file for
``/ndn/edu/memphis/%C1.Router/router1``.
It is recommended to configure security as described at :doc:`SECURITY-CONFIG`, before
starting router configuration.
Step 1. Ensuring nfd is running
-------------------------------
@@ -46,7 +49,15 @@ Type the following in the terminal:
If you see ``error while connecting to the forwarder (No such file or directory)``,
``nfd`` is not running. Follow the instructions in `Getting started with NFD
<http://named-data.net/doc/NFD/current/INSTALL.html>`_ to run nfd.
<https://docs.named-data.net/NFD/current/INSTALL.html>`_ to run nfd.
Since v0.4.0, NLSR no longer creates Faces for the neighbors that are
specified in ``nlsr.conf``. Instead, it relies on the pre-existence of
the Faces in NFD. NLSR will obtain this information from NFD, and
configure its neighbors using this information.
To create faces it is now necessary to use the ``nfdc`` command. See ``man nfdc`` for
its documentation (`online version <https://docs.named-data.net/NFD/current/manpages/nfdc.html>`__).
Step 2. Determining FaceUri
---------------------------
@@ -83,7 +94,7 @@ configuration commands follows:
; InterestLifetime (in seconds) for LSA fetching
lsa-interest-lifetime 4 ; default value 4. Valid values 1-60
seq-dir /var/lib/nlsr/
state-dir /var/lib/nlsr/ ; state directory to store all dynamic changes to NLSR
}
; the neighbors section contains the configuration for router's neighbors and hello's behavior
@@ -197,7 +208,7 @@ To avoid this, the directory can be set in a user-owned directory. For example:
{
...
seq-dir /home/username/nlsr/log ; path for sequence directory (Absolute path)
state-dir /home/username/nlsr/log ; path for sequence directory and other dynamic changes (Absolute path)
}
...
+5 -2
View File
@@ -35,12 +35,15 @@ router /\<network\>/\<site\>/%C1.Router/\<router-name\> /ndn/edu/ucla/%C
NLSR /\<network\>/\<site\>/%C1.Router/\<router-name\>/NLSR /ndn/edu/ucla/%C1.Router/rt1/NLSR /ndn/edu/ucla/%C1.Router/rt1/NLSR/KEY/5/%00/%01
======== ===================================================== ================================= ===============================================
Users should create keys according to the naming and signing hierarchies above.
Users should create keys according to the naming and signing hierarchies above. The
``%C1.Operator`` and ``%C1.Router`` labels are NDN keywords that should not be modified
by the user.
.. note::
Detailed information about key setup is given in NLSR Developer's Guide.
Detailed information about key setup is given in NLSR Developer's Guide and the
:doc:`beginners-guide`.
Certificate Publishing
----------------------
View File
Whitespace-only changes.
+887
View File
@@ -0,0 +1,887 @@
==========================================================
A beginners guide to installing and testing NLSR on Fedora
==========================================================
:Authors: David Arjona-Villicaña, Octavio Renteria-Vidales, Ashlesh Gawande
:Date: November, 2018
:Abstract: This is an easy to follow guide on how to install and test the NLSR routing protocol for NDN using two Fedora 28 machines. The commands and the paths used in this guide have been tested only in Fedora, although a similar procedure should be used for other linux systems. Specifically, the testing section (§ `5 <#test>`__) is platform independent. Therefore users who have NLSR already installed may skip to this section. Since neither NDN, NLSR nor Fedora are static software developments, it is expected that some commands and features in this guide will change over time. However, this guide is as accurate as it could be at the time it was published.
.. role:: raw-latex(raw)
:format: latex
.. _intro:
1. Introduction
===============
The following instructions are based on the information provided at the
Named Data Networking project web page [NDNmain]_.
Before installing NLSR it is necessary to install different libraries and
programs: ndn-cxx, NFD, ChronoSync [optional], ndn-svs [optional] and PSync.
This document describes the necessary steps to correctly install these
programs (§ `2 <#ndncxx>`__, `3 <#nfd>`__ and `4 <#nlsr>`__) and a brief
guide on how to configure and test NLSR using a simple two-node
network (§ `5 <#test>`__).
Many of the commands in this guide need to be executed as *root*.
Starting from Fedora 28, there is no need to set a root user
[Kolman2018]_. However it is possible to define it,
using the following command:
::
$ sudo -i
And then using the ``passwd`` command to set up a password. After setting
up the root user, it is possible to become root by employing the
following command and providing the root password when prompted:
::
$ su -
Fedora employs the ``dnf`` command to install and verify installed
packages. The following commands may become useful during the
installation process and should be executed as root:
- To verify that all installed packages are up to date
::
$ dnf update
- To verify if a package is already installed in the system
::
$ dnf list --installed <package-name>
- To search for information about a package or family of packages (not
necessarily installed in the system).
::
$ dnf info <package-name>
- To install a package in the system.
::
$ dnf install <package-name>
It is also a good installation practice to download and install all the
NDN programs in a common directory. Therefore, it is recommended to
create a directory at the home directory where all the following
programs may get installed. The name of this directory is not important.
However, the following are provided as suggestions: project, NDNproject,
NDNprograms. Each of the programs in the following sections should be
downloaded to their own directory using the ``git`` command, and then
compiled in this directory.
.. _ndncxx:
2. Installing ndn-cxx
=====================
2.1 Before installing ndn-cxx
-----------------------------
An updated list of the packages and programs that need to be installed
before installing ndn-cxx, is provided at [NDN-cxx]_.
This list is also reproduced below with the commands to verify that all
the packages have been installed in the system. The following commands
should be run as root:
#. gcc and gcc-c++
::
$ dnf list --installed gcc
$ dnf list --installed gcc-c++
#. Python version 3.8 or later
::
$ python3 -V
#. SQLite 3.x
::
$ dnf list --installed sqlite-devel
#. OpenSSL version 1.1.1 or later
::
$ dnf list --installed openssl-devel
#. pkgconf that replaces pkg-config
::
$ dnf list --installed pkgconf*
#. Boost libraries version 1.71.0 or later
::
$ dnf list --installed boost-devel
#. git
::
$ dnf list --installed git
#. doxygen (optional)
::
$ dnf list --installed doxygen
#. graphviz (optional)
::
$ dnf list --installed graphviz
#. python3-pip (optional)
::
$ dnf list --installed python3-pip
#. After verifying that the python3-pip package has been installed, it
is necessary to run the following command:
::
$ pip install sphinx sphinxcontrib-doxylink
2.2 Downloading and installing ndn-cxx
--------------------------------------
The ``git`` command allows to download the ndn-cxx library in its own
folder, also called *ndn-cxx*. Therefore it is recommended to execute
this command at the directory created at § `1 <#intro>`__:
::
$ git clone --depth 1 https://github.com/named-data/ndn-cxx.git
Move to the ndn-cxx directory:
::
$ cd ndn-cxx
Use the following command to verify that everything is ready to compile.
If an error message displays, it is necessary to fix it before
continuing:
::
$ ./waf configure --with-examples
Compile the ndn-cxx library and install the compiled files at the
system's directories:
::
$ ./waf
$ sudo ./waf install
2.3 Configuring ndn-cxx
-----------------------
The commands in this subsection need to be run as root. First, it is
necessary to create file *local.conf*, which contains a line with the
location for the ndn-cxx library:
::
$ echo /usr/local/lib64 >> /etc/ld.so.conf.d/local.conf
The following command configures the libraries:
::
$ ldconfig -v | grep ndn
This command should display a line similar to the following:
::
libndn-cxx.so.0.6.1 -> libndn-cxx.so.0.6.1
Configure the NDN path:
::
$ echo export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig >> /etc/profile.d/ndn.sh
After this command has been executed, it is necessary to apply the
changes by either logging out and back in, and then running the
following command:
::
$ printenv | grep PKG
Or by executing the following command:
::
$ ./etc/profile.d/ndn.sh
For more information and examples about how to compile and configure
this library, users should read the ndn-cxx guide at
[NDN-cxx]_.
.. _nfd:
3. Installing NFD
=================
3.1 Before installing NFD
-------------------------
An updated list of the packages and programs that need to be installed
before NFD is provided at [NDNNFD]_. Before installing
NFD it is necessary to verify that the following packages are installed:
#. pcap library
::
$ dnf list --installed libpcap-devel
3.2 Downloading and installing NFD
----------------------------------
This software is downloaded and installed in a folder called *NFD*, which
should be created at the directory defined at § `1 <#intro>`__. The
following commands need to be run as a regular user:
::
$ git clone --depth 1 https://github.com/named-data/NFD.git
$ cd NFD
$ ./waf configure
If the previous command prints an error message saying that waf cannot
find WebSocket, it is necessary to follow the instructions provided by
this same output, which tells the user to run the following command:
::
$ git submodule update --init
After executing these instructions, complete the configuration by running
``./waf configure`` again. Then complete the installation by means of the
following commands:
::
$ ./waf
$ sudo ./waf install
3.3 Configuring NFD
-------------------
Create a configuration file by running the following command as root:
::
$ cp /usr/local/etc/ndn/nfd.conf.sample /usr/local/etc/ndn/nfd.conf
After the configuration file has been created, NFD's behavior may be
changed by modifying this file. Once the configuration file has been
created, it is recommended to start NFD by using the following command:
::
$ nfd-start
This command does not properly allow to employ the command window to
enter new commands; however it displays the NFD logs. Therefore, it is
recommended to open a new command window. This second window may be used
to verify NDF's status and then stop NFD by using the following
commands:
::
$ nfd-status
$ nfd-stop
.. _nlsr:
4. Installing NLSR
==================
4.1 Installing PSync
--------------------
Before installing NLSR, it is also necessary to download and install
PSync. PSync is a synchronization library which allows NLSR to synchronize LSAs
similar to ChronoSync. More information about PSync may be found at [PSync]_.
This library may be installed by running the following commands as a regular
user and at the directory defined at § `1 <#intro>`__:
::
$ git clone --depth 1 https://github.com/named-data/PSync.git
$ cd PSync
$ ./waf configure
$ ./waf
$ sudo ./waf install
The following command needs to be used again to configure the libraries:
::
$ sudo ldconfig -v | grep -i psync
This command should display a line similar to the following:
::
libPSync.so.0.1.0 -> libPSync.so.0.1.0
4.2 [Optional] Installing ChronoSync
------------------------------------
By default NLSR no longer builds with ChronoSync support.
Since ChronoSync is deprecated, only install it for testing purposes.
Before installing NLSR, it is necessary to first download and install
ChronoSync, which is a synchronization library which allows NLSR routers
to synchronize Link State Advertisements (LSAs). More information about
ChronoSync may be found at [Chronosync]_. This library may be
installed by running the following commands as a regular user and at the
directory defined at § `1 <#intro>`__:
::
$ git clone --depth 1 https://github.com/named-data/ChronoSync.git
$ cd ChronoSync
$ ./waf configure
$ ./waf
$ sudo ./waf install
The following command needs to be used again to configure the libraries:
::
$ sudo ldconfig -v | grep -i chronosync
This command should display a line similar to the following:
::
libChronoSync.so.0.5.0 -> libChronoSync.so.0.5.0
4.3 [Optional] Installing SVS
-----------------------------
NLSR can also use State Vector Sync as the underlying Sync protocol,
using the ndn-svs library.
This library may be installed by running the following commands as a
regular user and at the directory defined at § `1 <#intro>`__:
::
$ git clone --depth 1 https://github.com/named-data/ndn-svs.git
$ cd ndn-svs
$ ./waf configure
$ ./waf
$ sudo ./waf install
The following command needs to be used again to configure the libraries:
::
$ sudo ldconfig -v | grep ndn-svs
This command should display a line similar to the following:
::
libndn-svs.so.0.0.1 -> libndn-svs.so.0.0.1
4.4 Downloading and installing NLSR
-----------------------------------
NLSR is downloaded and installed in a folder called *NLSR* which should
be created at the directory defined at § `1 <#intro>`__. The following
commands need to be run as a regular user:
::
$ git clone --depth 1 https://github.com/named-data/NLSR.git
$ cd NLSR
$ ./waf configure
$ ./waf
$ sudo ./waf install
If ChronoSync support is needed for testing, please configure NLSR with:
::
$ ./waf configure --with-chronosync
4.5 Configuring NLSR
--------------------
Create and configure the following directory by running the following
commands as root:
::
$ mkdir /var/lib/nlsr
$ chmod 777 /var/lib/nlsr
.. _test:
5. Configuring and Testing NLSR
===============================
To test NLSR, the first step is to configure the keys and certificates
that implement a secure communication between the routers. Then it is
necessary to verify that the computers in the test network are
connected, that NFD is running and the faces between the computers are
configured. Finally, the NLSR configuration file has to be edited before
running NLSR. The following subsections are provided as a guide to
define and configure a simple computer network between two computers:
router1 and router2.
.. _security:
5.1 Setting up the security
---------------------------
Configuring security in an NDN network requires to generate, exchange
and install, keys and certificates between the root, site, operator and
router computers that form the network
[NLSRsecconf]_, [NLSRdevguide]_, although in practice, it
is possible to keep more than one of these entities in a single machine.
The following example and *Figure 1* show how to configure security
for a single router, called Router X. In this example, the root, site,
operator and Router X are in different computers:
.. figure:: security_comp.png
:alt: Security configuration example for Router X.
:width: 19cm
:align: center
Fig. 1. Security configuration example for Router X.
#. At the root server, generate the root key:
::
$ ndnsec-key-gen /ndn/ > root.key
#. Generate the certificate for the root key at the root server:
::
$ ndnsec-cert-dump -i /ndn/ > root.cert
#. Install the root certificate at the root server:
::
$ ndnsec-cert-install -f root.cert
#. At the site server, generate the site key:
::
$ ndnsec-key-gen /ndn/edu/uaslp > site.key
#. Copy the site key to the root server and generate the certificate for
the site server:
::
$ ndnsec-cert-gen -s /ndn/ site.key > site.cert
#. Copy the site certificate to the site server and install it:
::
$ ndnsec-cert-install -f site.cert
#. At the operator server, generate the operator key:
::
$ ndnsec-key-gen /ndn/edu/uaslp/%C1.Operator/op > op.key
#. Copy the operator key to the site server and generate the certificate
for the operator server:
::
$ ndnsec-cert-gen -s /ndn/edu/uaslp op.key > op.cert
#. Copy the operator certificate to the operator server and install it:
::
$ ndnsec-cert-install -f op.cert
#. At the router, generate the router key:
::
$ ndnsec-key-gen /ndn/edu/uaslp/%C1.Router/routerX > routerX.key
#. Copy the router key to the operator server and generate the
certificate for the router:
::
$ ndnsec-cert-gen -s /ndn/edu/uaslp/%C1.Operator/op routerX.key >
routerX.cert
#. Copy the router certificate to the router and install it:
::
$ ndnsec-cert-install -f routerX.cert
In the previous steps, the *%C1.Router* and *%C1.Operator* labels are
NDN keywords and should not be changed. These labels will be also used
by the configuration file (§ `5.4 <#configfile>`__)
The following command may be used to verify that the certificates have
been installed in a computer:
::
$ ndnsec-list
This guide recommends that one machine functions as the root, site,
operator and router1, while a different computer only functions as
router2. *Figure 2* shows this
configuration. For router1, the twelve steps described before need to be
executed except for exchanging files between computers. For the router2,
only steps 10 to 12 are needed to generate this router's certificate.
Additionally, the following command may be used to print a list and a
brief description of all the ``ndnsec`` commands:
::
$ man ndnsec
.. figure:: netwk1.png
:alt: Example network.
:width: 19cm
:align: center
Fig. 2. Example network.
5.2 Configuring the network
---------------------------
The first step is to configure the physical network. If two computers
are going to get connected using a single Ethernet cable, it is
necessary to verify that this cable is a crossover. The other option is
to employ a switch between two computers that are then connected using
two regular Ethernet cables.
After the physical network has been assembled, it is necessary to
configure the network addresses and cards for all the computers in the
network. It is important to remember that computers that are connected
to each other should use the same subnetwork address. It is possible to
verify the network configuration in a Linux computer by means of the
``ip addr`` command.
Once the physical network and network cards have been configured, it is
necessary to verify that the computers can communicate with each other.
The simplest way to do this is by using the ``ping`` command:
::
$ ping <remote-ip-address>
5.3 Starting and configuring NFD
--------------------------------
To start and configure NFD it is necessary to open two terminal windows.
The first one will be used to start NFD by means of the ``nfd-start``
command. This terminal will also display the logs that NFD generates. By
default, NFD only generates informational logs (INFO). However, it is
possible to obtain different levels of verbosity for these logs. These
levels can be set before NFD starts by editing the
*/usr/local/etc/ndn/nfd.conf* file. Open this file using a regular text
editor, read the information provided about logging and then modify the
*default-level* variable at the *log* section according to the
instructions provided in the file. Additional information about NFD
configuration may be found at [NDNNFDusage]_.
The second terminal will be used to monitor the NFD status:
::
$ nfd-status
Employ the following command to configure each face that a computer uses
to connect to a neighboring computer:
::
$ nfdc face create udp4://<remote-ip-address>
The face id may be displayed by running:
::
$ nfdc face list
The status of the face may be verified by using the following command:
::
$ nfdc face show id <face-id>
After finishing NLSR testing, it is necessary to destroy the face before
stopping NFD. This operation is described at § `5.6 <#turn_off>`__. For
the two computer network provided as an example (*Figure 2*), it is necessary that both
machines run NFD and that each one configures a face that connects to
the other machine.
.. _configfile:
5.4 Setting up the configuration file
-------------------------------------
Instructions on how to use the configuration file are already provided
at the NLSR's Router Configuration page [NLSRrtrconf]_.
Read the information in this page to understand NLSR router
configuration. The following text describes the instructions that have
been modified at the default nlsr.conf file for router1:
::
; AT general SECTION:
{
network /ndn/ ; name of the network
site /edu/uaslp ; name of the site
router /%C1.Router/router1 ; name of the router: router1
}
;AT neighbors SECTION:
neighbors
{
neighbor
{
name /ndn/edu/uaslp/%C1.Router/router2 ; Neighbor router: router2
face-uri udp://140.220.80.124 ; face to the neighbor
link-cost 30 ; cost of the link
}
}
; AT advertising SECTION:
advertising
{
prefix /ndn/edu/uaslp/office/bldg1 ; Advertising destinations
prefix /ndn/edu/uaslp/office/bldg2 ; for router1
}
; AT security SECTION:
security
{
validator
{
...
trust-anchor
{
type file
file-name "root.cert" ; root certificate file
}
}
prefix-update-validator
{
...
trust-anchor
{
type file
file-name "site.cert" ; site certificate file
}
}
cert-to-publish "root.cert" ; root certificate file
cert-to-publish "site.cert" ; site certificate file
cert-to-publish "op.cert" ; operator certificate file
cert-to-publish "router1.cert" ; router1 certificate file
}
The following text shows the modified instructions for router2:
::
; AT general SECTION:
{
network /ndn/ ; name of the network
site /edu/uaslp ; name of the site
router /%C1.Router/router2 ; name of the router: router2
}
;AT neighbors SECTION:
neighbors
{
neighbor
{
name /ndn/edu/uaslp/%C1.Router/router1 ; Neighbor router: router1
face-uri udp://140.220.80.121 ; face to the neighbor
link-cost 30 ; cost of the link
}
}
; AT advertising SECTION:
advertising
{
prefix /ndn/edu/uaslp/labs/networks ; Advertising destinations
prefix /ndn/edu/uaslp/labs/hardware ; for router2
}
; AT security SECTION:
security
{
validator
{
...
trust-anchor
{
type file
file-name "root.cert" ; root certificate file
} ; this file needs to be copied to
} ; router2
prefix-update-validator
{
...
trust-anchor
{
type file
file-name "site.cert" ; site certificate file
} ; this file needs to be copied to
} ; router2
...
cert-to-publish "router2.cert" ; router2 certificate file
}
Notice that files *root.cert* and *site.cert*, which were generated at
router1, need to be copied to router2. Also notice that the *%C1.Router*
and *%C1.Operator* keywords employed at § `5.1 <#security>`__ are also
referenced by these configuration files.
.. _starting_nlsr:
5.5 Starting NLSR
-----------------
It is recommended to open a third command terminal and run NLSR in this
window. After the NLSR configuration file has been edited and saved as
*nlsr.conf*, it is possible to start NLSR by running either of the
following two commands:
::
$ nlsr
$ nlsr -f <configuration-file>
However, to verify what is NLSR doing, it becomes necessary to employ
NLSR's logging facility [NLSRstarting]_. A brief
description on how to use NDN's logging facility may be displayed by
entering the ``man ndn-log`` command. This guide recommends using one
of the following two instructions to start NLSR:
::
$ export NDN_LOG=nlsr.*=TRACE && nlsr
$ export NDN_LOG=nlsr.*=TRACE && nlsr -f <configuration-file>
The second terminal window may be used to run ``nfd-status`` again and
it should be possible to verify that the status has changed, specially
at the FIB and RIB sections of the generated report.
.. _turn_off:
5.6 Turning everything off
--------------------------
In order to stop NLSR and NFD, the following sequence of events is
recommended:
#. Stop NLSR by pressing the Ctrl+C keys at the third terminal window.
#. Destroy the face to the remote computers using either of the
following two commands at the second terminal window:
::
$ nfdc face destroy <face-id>
$ nfdc face destroy udp4://<remote-ip-address>
#. Stop NFD by entering the following command at the second terminal
window:
::
$ nfd-stop
#. The crossover Ethernet cable may be unplugged and the computers'
network configuration restored to its original settings.
5.7 Where to go from here
-------------------------
Users interested in building and configuring larger networks may want to
take a look at the NDN Ansible repository
[NDNAnsible]_. This repository uses Ansible, which is a
configuration management tool, to manage the official NDN testbed
deployment [NDNTestbed]_.
.. [NDNmain] *Named Data Networking*, https://named-data.net/, March 2018.
.. [Kolman2018] M. Kolman. *Anaconda improvements in Fedora 28*, Fedora Magazine, June 2018.
.. [NDN-cxx] *Getting started with ndn-cxx*, https://docs.named-data.net/ndn-cxx/current/INSTALL.html, April 2018.
.. [NDNNFD] *Getting started with NFD*, https://docs.named-data.net/NFD/current/INSTALL.html, April 2018.
.. [NDNNFDusage] *NFD usage*, https://docs.named-data.net/NFD/current/manpages/nfd.html, May 2018.
.. [Chronosync] Z. Zhu and A. Afanasyev. *Let's ChronoSync: Decentralized dataset state synchronization in Named Data Networking*, in IEEE ICNP, October 2013.
.. [PSync] M. Zhang, V. Lehman, and L. Wang. *Scalable Name-based Data Synchronization for Named Data Networking*, in IEEE INFOCOM, May 2017.
.. [NLSRsecconf] *NLSR Security Configuration*, https://docs.named-data.net/NLSR/current/SECURITY-CONFIG.html June 2018.
.. [NLSRdevguide] V. Lehman, M. Chowdhury, N. Gordon, A. Gawande. *NLSR Developer's Guide*, University of Memphis, November 2017.
.. [NLSRrtrconf] *NLSR Router Configuration*, https://docs.named-data.net/NLSR/current/ROUTER-CONFIG.html, April 2018.
.. [NLSRstarting] *Getting Started with NLSR*, https://docs.named-data.net/NLSR/current/GETTING-STARTED.html, May 2018.
.. [NDNAnsible] *NDN Ansible repository*, https://github.com/WU-ARL/NDN_Ansible, October 2018.
.. [NDNTestbed] *NDN Testbed*, https://named-data.net/ndn-testbed/, October 2018.
+58 -221
View File
@@ -1,255 +1,92 @@
# -*- coding: utf-8 -*-
# Configuration file for the Sphinx documentation builder.
#
# NLSR - Named Data Link State Routing Protocol documentation build configuration file, created by
# sphinx-quickstart on Sun Apr 6 19:58:22 2014.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
import datetime
import importlib.util
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
# -- General configuration ------------------------------------------------
project = 'Named Data Link State Routing Protocol (NLSR)'
copyright = 'Copyright © 2014-2023 Named Data Networking Project.'
author = 'Named Data Networking Project'
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# The short X.Y version.
#version = ''
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.todo',
'redmine_issue'
]
def addExtensionIfExists(extension):
try:
__import__(extension)
extensions.append(extension)
except ImportError:
sys.stderr.write("Extension '%s' in not available. "
"Some documentation may not build correctly.\n" % extension)
sys.stderr.write("To install, use \n"
" sudo pip install %s\n" % extension.replace('.', '-'))
if os.getenv('GOOGLE_ANALYTICS', None):
addExtensionIfExists('sphinxcontrib.googleanalytics')
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'NLSR - Named Data Link State Routing Protocol'
copyright = u'2014-{}, Named Data Networking Project'.format(datetime.date.today().year)
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# The full version, including alpha/beta/rc tags.
#release = ''
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
today_fmt = '%Y-%m-%d'
# -- Options for HTML output ----------------------------------------------
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
needs_sphinx = '4.0'
extensions = [
'sphinx.ext.extlinks',
'sphinx.ext.todo',
]
def addExtensionIfExists(extension: str):
try:
if importlib.util.find_spec(extension) is None:
raise ModuleNotFoundError(extension)
except (ImportError, ValueError):
sys.stderr.write(f'WARNING: Extension {extension!r} not found. '
'Some documentation may not build correctly.\n')
else:
extensions.append(extension)
addExtensionIfExists('sphinxcontrib.doxylink')
templates_path = ['_templates']
exclude_patterns = ['Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
# html_theme = 'default'
html_theme = 'named_data_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = ['./']
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
html_theme_path = ['.']
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
html_copy_source = False
html_show_sourcelink = False
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
html_file_suffix = ".html"
# Output file base name for HTML help builder.
htmlhelp_basename = 'nlsr-docs'
# Disable syntax highlighting of code blocks by default.
highlight_language = 'none'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'nlsr-docs.tex', u'NLSR - Named Data Link State Routing Protocol Documentation',
u'Named Data Networking Project', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# -- Options for manual page output ------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-manual-page-output
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('manpages/nlsr', 'nlsr', u'Named Data Link State Routing Protocol Daemon', None, 1),
('manpages/nlsr.conf', 'nlsr.conf', u'Named Data Link State Routing Protocol Daemon config file', None, 5),
('manpages/nlsrc', 'nlsrc', u'Command-line utility to interact with and collect statistics from NLSR', None, 1),
('manpages/nlsr', 'nlsr', 'Named Data Link State Routing daemon', [], 1),
('manpages/nlsr.conf', 'nlsr.conf', 'Named Data Link State Routing daemon configuration file', [], 5),
('manpages/nlsrc', 'nlsrc', 'command-line utility to interact with and collect statistics from NLSR', [], 1),
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Misc options ------------------------------------------------------------
if os.getenv('GOOGLE_ANALYTICS', None):
googleanalytics_id = os.environ['GOOGLE_ANALYTICS']
googleanalytics_enabled = True
doxylink = {
'nlsr': ('NLSR.tag', 'doxygen/'),
}
redmine_project_url = "https://redmine.named-data.net/"
extlinks = {
'issue': ('https://redmine.named-data.net/issues/%s', 'issue #%s'),
}
+16 -103
View File
@@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = "NLSR - Named Data Link State Routing Protocol"
PROJECT_NAME = "NLSR: Named Data Link State Routing Protocol"
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
@@ -68,7 +68,7 @@ OUTPUT_DIRECTORY = docs/doxygen
# performance problems for the file system.
# The default value is: NO.
CREATE_SUBDIRS = YES
CREATE_SUBDIRS = NO
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
@@ -220,19 +220,13 @@ TAB_SIZE = 4
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
# instance, some of the names that are used will be different. The list of all
# members will be omitted, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_FOR_C = NO
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
# Python sources only. Doxygen will then generate output that is more tailored
@@ -408,7 +402,7 @@ EXTRACT_PRIVATE = NO
# scope will be included in the documentation.
# The default value is: NO.
EXTRACT_PACKAGE = YES
EXTRACT_PACKAGE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
# included in the documentation.
@@ -422,7 +416,7 @@ EXTRACT_STATIC = YES
# for Java sources.
# The default value is: YES.
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_CLASSES = NO
# This flag is only useful for Objective-C code. When set to YES local methods,
# which are defined in the implementation section but not in the interface are
@@ -485,7 +479,7 @@ INTERNAL_DOCS = NO
# and Mac users are advised to set this option to NO.
# The default value is: system dependent.
CASE_SENSE_NAMES = YES
CASE_SENSE_NAMES = NO
# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
# their full class and namespace scopes in the documentation. If set to YES the
@@ -524,7 +518,7 @@ SORT_MEMBER_DOCS = YES
# name. If set to NO the members will appear in declaration order.
# The default value is: NO.
SORT_BRIEF_DOCS = NO
SORT_BRIEF_DOCS = YES
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
# (brief and detailed) documentation of class members so that constructors and
@@ -536,7 +530,7 @@ SORT_BRIEF_DOCS = NO
# detailed member documentation.
# The default value is: NO.
SORT_MEMBERS_CTORS_1ST = NO
SORT_MEMBERS_CTORS_1ST = YES
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
# of group names into alphabetical order. If set to NO the group names will
@@ -968,13 +962,6 @@ VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = YES
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
# which the alphabetical index list will be split.
# Minimum value: 1, maximum value: 20, default value: 5.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all classes will
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
# can be used to specify a prefix (or a list of prefixes) that should be ignored
@@ -1103,21 +1090,13 @@ HTML_COLORSTYLE_SAT = 0
HTML_COLORSTYLE_GAMMA = 91
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting this
# to NO can help when comparing the output of multiple runs.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = YES
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_DYNAMIC_SECTIONS = NO
HTML_DYNAMIC_SECTIONS = YES
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
# shown in the various tree structured indices initially; the user can expand
@@ -1355,7 +1334,7 @@ GENERATE_TREEVIEW = YES
# Minimum value: 0, maximum value: 20, default value: 4.
# This tag requires that the tag GENERATE_HTML is set to YES.
ENUM_VALUES_PER_LINE = 4
ENUM_VALUES_PER_LINE = 1
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
# to set the initial width (in pixels) of the frame in which the tree is shown.
@@ -1380,17 +1359,6 @@ EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are not
# supported properly for IE 6.0, but are supported on all modern browsers.
#
# Note that when changing this option you need to delete any form_*.png files in
# the HTML output directory before the changes have effect.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
FORMULA_TRANSPARENT = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# http://www.mathjax.org) which uses client side Javascript for the rendering
# instead of using prerendered bitmaps. Use this if you do not have LaTeX
@@ -1653,16 +1621,6 @@ LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
# code with syntax highlighting in the LaTeX output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
@@ -1916,18 +1874,14 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = DOXYGEN=1 \
PREDEFINED = DOXYGEN \
INIT_LOGGER(x)= \
BOOST_STATIC_ASSERT(x)= \
BOOST_CONCEPT_ASSERT(x)= \
BOOST_CONCEPT_REQUIRES(x)= \
DECL_OVERRIDE=override \
PUBLIC_WITH_TESTS_ELSE_PRIVATE=private \
PUBLIC_WITH_TESTS_ELSE_PROTECTED=protected \
PROTECTED_WITH_TESTS_ELSE_PRIVATE=private \
VIRTUAL_WITH_TESTS \
DECL_CLASS_FINAL=final \
DECL_FINAL=final
VIRTUAL_WITH_TESTS=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@@ -1993,34 +1947,10 @@ EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of 'which perl').
# The default file (with absolute path) is: /usr/bin/perl.
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
# disabled, but it is recommended to install and use dot, since it yields more
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see:
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
# If set to YES, the inheritance and collaboration graphs will hide inheritance
# and usage relations if the target is undocumented or is not a class.
# The default value is: YES.
@@ -2034,7 +1964,7 @@ HIDE_UNDOC_RELATIONS = NO
# set to NO
# The default value is: NO.
HAVE_DOT = YES
HAVE_DOT = @HAVE_DOT@
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
# to run in parallel. When set to 0 doxygen will base this on the number of
@@ -2046,23 +1976,6 @@ HAVE_DOT = YES
DOT_NUM_THREADS = 0
# When you want a differently looking font n the dot files that doxygen
# generates you can specify the font name using DOT_FONTNAME. You need to make
# sure dot is able to find the font, which can be done by putting it in a
# standard location or by setting the DOTFONTPATH environment variable or by
# setting DOT_FONTPATH to the directory containing the font.
# The default value is: Helvetica.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTNAME = Helvetica
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
# dot graphs.
# Minimum value: 4, maximum value: 24, default value: 10.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTSIZE = 10
# By default doxygen will tell dot to use the default font as specified with
# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
# the path where dot can find it using this tag.
@@ -2150,7 +2063,7 @@ INCLUDED_BY_GRAPH = YES
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALL_GRAPH = YES
CALL_GRAPH = NO
# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
# dependency graph for every global function or class method.
@@ -2161,7 +2074,7 @@ CALL_GRAPH = YES
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALLER_GRAPH = YES
CALLER_GRAPH = NO
# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
# hierarchy of all classes instead of a textual one.
@@ -2264,7 +2177,7 @@ DOT_TRANSPARENT = YES
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_MULTI_TARGETS = NO
DOT_MULTI_TARGETS = YES
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
# explaining the meaning of the various boxes and arrows in the dot generated
+52 -45
View File
@@ -1,19 +1,22 @@
NLSR - Named Data Link State Routing Protocol
=============================================
NLSR: Named Data Link State Routing Protocol
============================================
NLSR is a routing protocol in NDN that populates NDN's Routing Information Base. NLSR will
continue to evolve alongside the Named Data Networking `protocol
<https://named-data.net/doc/ndn-tlv/>`_.
.. toctree::
:hidden:
:maxdepth: 2
NLSR is an open and free software package licensed under the GPL 3.0 license and free to
all Internet users and developers. For more information about the licensing details and
limitations, refer to `COPYING.md
<https://github.com/named-data/NLSR/blob/master/COPYING.md>`_.
GETTING-STARTED
INSTALL
SECURITY-CONFIG
ROUTER-CONFIG
beginners-guide
manpages
release-notes
releases
NLSR is developed by the members of the `NSF-sponsored NDN project team
<https://named-data.net/project/participants/>`_. For more details, please refer to
`AUTHORS.md <https://github.com/named-data/NLSR/blob/master/AUTHORS.md>`_. Bug reports and
feedback are highly appreciated and can be made through the `NLSR Wiki`_.
**NLSR** is a routing protocol for Named Data Networking (NDN) that populates the Routing
Information Base (RIB) of an NDN router, such as `NFD`_. NLSR continues to evolve alongside
the core `NDN protocol`_.
The main design goal of NLSR is to provide a routing protocol to populate NDN's FIB. NLSR
calculates the routing table using link-state or hyperbolic routing and produces multiple
@@ -22,57 +25,61 @@ to evolve over time to include neighbor discovery and to become a full fledged
inter-domain routing protocol for NDN. The protocol design is presented in full detail in
the `NLSR Paper`_.
NLSR Documentation
-------------------
NLSR was mainly developed by members of the NSF-sponsored `NDN project team
<https://named-data.net/project/participants/>`__. See `AUTHORS.md
<https://github.com/named-data/NLSR/blob/master/AUTHORS.md>`__ for details.
.. toctree::
:hidden:
:maxdepth: 3
Bug reports and feedback are highly appreciated and can be made through the `NLSR Redmine`_.
GETTING-STARTED
INSTALL
ROUTER-CONFIG
SECURITY-CONFIG
RELEASE-NOTES
releases
manpages
Documentation
-------------
- :doc:`GETTING-STARTED`
- :doc:`INSTALL`
- :doc:`ROUTER-CONFIG`
- :doc:`SECURITY-CONFIG`
- :doc:`RELEASE-NOTES`
- :doc:`releases`
- :doc:`manpages`
- :doc:`GETTING-STARTED`
- :doc:`INSTALL`
- :doc:`SECURITY-CONFIG`
- :doc:`ROUTER-CONFIG`
- :doc:`beginners-guide`
- :doc:`manpages`
- :doc:`release-notes`
- :doc:`releases`
Downloading
-----------
- `GitHub NLSR repository <https://github.com/named-data/NLSR>`_
- `Source code git repository <https://github.com/named-data/NLSR>`__
NLSR mailing list
-----------------
- `NLSR Mailing List`_
- `NLSR Mailing List Archives`_
- `NLSR Mailing List`_
- `NLSR Mailing List Archives`_
`Sign up`_ is needed to post to the list or access the archives.
Additional information
----------------------
Additional resources
--------------------
- `NLSR Wiki`_
- `NLSR Wiki`_
- `NLSR Redmine`_
Feature requests and bug reports
- `NLSR Redmine`_
Feature requests and bug reports
- `NLSR Paper`_
Detailed explanation of the NLSR design
- `NLSR Paper`_
Detailed explanation of NLSR's design
- `NLSR Developer's Guide`_
For NLSR Development
- `NLSR Developer's Guide`_
For NLSR development
- `API documentation (doxygen) <doxygen/annotated.html>`__
License
-------
NLSR is free software distributed under the GNU General Public License version 3.
See `COPYING.md <https://github.com/named-data/NLSR/blob/master/COPYING.md>`__ for details.
.. _NDN protocol: https://docs.named-data.net/NDN-packet-spec/current/
.. _NFD: https://github.com/named-data/NFD
.. _NLSR Wiki: https://redmine.named-data.net/projects/nlsr/wiki
.. _NLSR Paper: https://named-data.net/wp-content/uploads/2016/01/ndn-0037-1-nlsr.pdf
.. _NLSR Mailing List: https://listserv.memphis.edu/scripts/wa.exe?SUBED1=NLSR-HELP-L&A=1
+5 -7
View File
@@ -1,10 +1,8 @@
.. _Manpages:
Manpages
========
Man pages
=========
.. toctree::
manpages/nlsr
manpages/nlsr.conf
manpages/nlsrc
:glob:
:maxdepth: 1
manpages/*
+29 -9
View File
@@ -6,7 +6,8 @@ Usage
::
nlsrc [-h] [-V] COMMAND [<Command Options>]
nlsrc [-h | -V]
nlsrc [-R <router prefix> [-c <nlsr.conf path> | -k]] COMMAND [<Command Options>]
Description
@@ -24,6 +25,17 @@ Options
``-V``
Show NLSRC version information
``-R <router prefix>``
Target a remote NLSR instance.
The default is the local NLSR instance ``/localhost``.
``-c <nlsr.conf path>``
Verify remote status information with the trust schema loaded from ``security.validator`` section of specified nlsr.conf config file.
The default is loading from ``/etc/ndn/nlsr.conf``.
``-k``
Insecure: do not verify signature on status information retrieved from remote router.
``COMMAND``
``lsdb``
@@ -43,6 +55,11 @@ Options
``name``
The Name prefix to be advertised
``advertise <name> save``
``save``
Advertise a prefix and also save it to the nlsr.conf file residing in the state-dir for the next start of NLSR that operator may copy and use for the next start of NLSR
``withdraw``
Remove a Name prefix advertised through NLSR
@@ -51,24 +68,27 @@ Options
``name``
The Name prefix to be withdrawn
``withdraw <name> delete``
``delete``
Withdraw a prefix and also delete it from the nlsr.conf file residing in the state-dir
Notes
-----
When security is enabled, NLSR will not be allowed to successfully
advertise/withdraw names without first setting a default identity of operator.
If default identity is not set as operator, the user will be presented with the
error message: “Name prefix update error (code: 403)”. To remedy this
issue, use command 'ndn-sec-default'.
error message: "Name prefix update error (code: 403)". To remedy this
issue, use the command ``ndnsec set-default``. Example::
Example:
ndnsec-set-default /ndn/a-site/%C1.Operator/op
ndnsec set-default /ndn/a-site/%C1.Operator/op
Exit Status
-----------
nlsrc exits with one of the following values:
::
nlsrc exits with one of the following values::
0 nlsrc exited successfully
>0 An error occurred
1 generic error
2 bad command line
+5 -15
View File
@@ -12,7 +12,7 @@
<div class="row">
<div class="three columns">
<div id="logo">
<a href="http://named-data.net" title="A Future Internet Architecture"><img src="http://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
<a href="https://named-data.net" title="A Future Internet Architecture"><img src="https://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
</div><!--logo end-->
</div>
@@ -38,12 +38,13 @@
<h3>{{ _('Table Of Contents') }}</h3>
{{ toctree(includehidden=True) }}
<h3>{{ _('Additional documenation') }}</h3>
<h3>{{ _('Developer documentation') }}</h3>
<ul>
<li class="toctree-l1"><a class="reference external" href="http://redmine.named-data.net/projects/nlsr/wiki">NLSR Wiki</a></li>
<li class="toctree-l1"><a class="reference internal" href="doxygen/annotated.html">API documentation (doxygen)</a></li>
<li class="toctree-l1"><a class="reference external" href="https://redmine.named-data.net/projects/nlsr/wiki">NLSR Wiki</a></li>
</ul>
{%- endblock %}
{%- block sidebarsearch %}
<h3 style="margin-top: 1.5em;">{{ _('Search') }}</h3>
<form class="search" action="{{ pathto('search') }}" method="get">
@@ -74,22 +75,11 @@
<div class="row">
<div class="twelve columns">
<div id="copyright">This research is partially supported by NSF (Award <a href="http://www.nsf.gov/awardsearch/showAward?AWD_ID=1040868" target="_blank>">CNS-1040868</a>)<br/><br/><a rel="license" href="http://creativecommons.org/licenses/by/3.0/deed.en_US" target="_blank">Creative Commons Attribution 3.0 Unported License</a> except where noted.</div>
<div id="copyright">This research is partially supported by NSF (Award <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=1040868" target="_blank>">CNS-1040868</a>)<br/><br/><a rel="license" href="https://creativecommons.org/licenses/by/3.0/deed.en_US" target="_blank">Creative Commons Attribution 3.0 Unported License</a> except where noted.</div>
</div>
</div>
</div><!--footer info end-->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-22320603-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
{% endblock %}
{% block relbar1 %}{% endblock %}
@@ -0,0 +1,32 @@
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby
<a href="https://www.doxygen.org/index.html">
<img class="footer" src="$relpath$doxygen.png" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/>
<address class="footer"><small>
$generatedby &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="$relpath$doxygen.png" alt="doxygen"/>
</a> $doxygenversion
</small></address>
<!--END !GENERATE_TREEVIEW-->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '@GOOGLE_ANALYTICS@', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>
+3 -1
View File
@@ -4,7 +4,7 @@
<ul>
$navpath
<li class="footer">$generatedby
<a href="http://www.doxygen.org/index.html">
<a href="https://www.doxygen.org/index.html">
<img class="footer" src="$relpath$doxygen.png" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
@@ -18,5 +18,7 @@ $generatedby &#160;<a href="http://www.doxygen.org/index.html">
</small></address>
<!--END !GENERATE_TREEVIEW-->
<script type="text/javascript">
</script>
</body>
</html>
+4 -4
View File
@@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
@@ -26,13 +26,13 @@ $mathjax
<div class="row">
<div class="three columns">
<div id="logo">
<a href="http://named-data.net" title="A Future Internet Architecture"><img src="http://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
<a href="https://named-data.net" title="A Future Internet Architecture"><img src="https://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
</div><!--logo end-->
</div>
<!--top menu-->
<div class="nine columns" id="menu_container" >
<h1><a href="http://named-data.net/doc/NLSR/$projectnumber/">$projectname $projectnumber documentation</a></h1>
<h1><a href="https://named-data.net/doc/NLSR/$projectnumber/">$projectname $projectnumber documentation</a></h1>
</div>
</div>
</div><!--header container end-->
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

-70
View File
@@ -1,70 +0,0 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# Based on http://doughellmann.com/2010/05/09/defining-custom-roles-in-sphinx.html
"""Integration of Sphinx with Redmine.
"""
from docutils import nodes, utils
from docutils.parsers.rst.roles import set_classes
def redmine_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
"""Link to a Redmine issue.
Returns 2 part tuple containing list of nodes to insert into the
document and a list of system messages. Both are allowed to be
empty.
:param name: The role name used in the document.
:param rawtext: The entire markup snippet, with role.
:param text: The text marked with the role.
:param lineno: The line number where rawtext appears in the input.
:param inliner: The inliner instance that called us.
:param options: Directive options for customization.
:param content: The directive content for customization.
"""
try:
issue_num = int(text)
if issue_num <= 0:
raise ValueError
except ValueError:
msg = inliner.reporter.error(
'Redmine issue number must be a number greater than or equal to 1; '
'"%s" is invalid.' % text, line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
app = inliner.document.settings.env.app
node = make_link_node(rawtext, app, 'issues', str(issue_num), options)
return [node], []
def make_link_node(rawtext, app, type, slug, options):
"""Create a link to a Redmine resource.
:param rawtext: Text being replaced with link node.
:param app: Sphinx application context
:param type: Link type (issue, changeset, etc.)
:param slug: ID of the thing to link to
:param options: Options dictionary passed to role func.
"""
#
try:
base = app.config.redmine_project_url
if not base:
raise AttributeError
except AttributeError:
raise ValueError('redmine_project_url configuration value is not set')
#
slash = '/' if base[-1] != '/' else ''
ref = base + slash + type + '/' + slug + '/'
set_classes(options)
node = nodes.reference(rawtext, 'Issue #' + utils.unescape(slug), refuri=ref,
**options)
return node
def setup(app):
"""Install the plugin.
:param app: Sphinx application context.
"""
app.add_role('issue', redmine_role)
app.add_config_value('redmine_project_url', None, 'env')
return
-1
View File
@@ -1 +0,0 @@
release-notes/release-notes-0.4.0.rst
+4
View File
@@ -0,0 +1,4 @@
Release Notes
=============
.. include:: release-notes/release-notes-0.7.0.rst
+6 -5
View File
@@ -4,19 +4,20 @@ NLSR version 0.1.0 (initial release)
Release date: August 25, 2014
The main design goal of NLSR is to provide a routing protocol to populate `NFD's
<http://named-data.net/doc/NFD/current/>`_ RIB. NLSR calculates the routing table using
<https://github.com/named-data/NFD>`__ RIB. NLSR calculates the routing table using
link-state or hyperbolic routing and produces multiple faces for each reachable name
prefix in a single authoritative domain.
**Included features**:
Included features
^^^^^^^^^^^^^^^^^
- Advertise availability of content through the configured router
- Use `ChronoSync <https://github.com/named-data/ChronoSync>`_ to synchronize routers' LSA sequence numbers and Interest/Data to retrieve LSAs
- Use `ChronoSync <https://github.com/named-data/ChronoSync>`__ to synchronize routers' LSA sequence numbers and Interest/Data to retrieve LSAs
- Produce a list of ranked forwarding options for each name prefix to facilitate NDN's adaptive forwarding strategies
- Configure maximum number of faces per prefix in NFD’s RIB
- Configure maximum number of faces per prefix in NFD's RIB
- Set up NFD tunnels to neighbors automatically and maintain the tunnels to neighbors
@@ -27,4 +28,4 @@ prefix in a single authoritative domain.
- Use a hierarchical trust model for routing within a single administrative domain
- Keep NFD’s RIB updated on failure and recovery
- Keep NFD's RIB updated on failure and recovery
@@ -0,0 +1,6 @@
NLSR version 0.4.2
++++++++++++++++++
**Bug Fixes**:
- Fix segfault in scheduled erase of lsa segment (:issue:`4520`)
@@ -0,0 +1,14 @@
NLSR version 0.4.3
++++++++++++++++++
**Changes**:
- **breaking change** Change NLSR to nlsr for various prefixes (:issue:`4543`)
**Bug Fixes**:
- Fix dry-run mode not working (:issue:`4394`)
- Fix convergence w/o content store (:issue:`4430`)
- Register router prefix to fix remote requests (:issue:`4543`)
- Fix build with clang-5.0 (:issue:`4547`)
- Avoid misaligned memory access (:issue:`4609`)
@@ -0,0 +1,35 @@
NLSR version 0.5.0
++++++++++++++++++
**New Features**
- Set CanBePrefix to false on Hello Interest (:issue:`4581`)
- Optionally write prefixes to a copy of config file via nlsrc advertise (:issue:`4303`)
- Use SegmentPublisher utility from PSync to publish LSA data (:issue:`4760`)
- Add PSync as a dependency and switch it as default in conf file. (:issue:`4082`)
**Changes**
- Decouple classes from Nlsr object for easier unit testing (:issue:`1952`)
- Set sequence number file in SequencingManager constructor. (:issue:`4288`)
- Read conf file in test prefix update processor instead of static string (:issue:`3960`)
- Canonize FaceUri in conf file processor (:issue:`4817`)
- Remove redundant function "calculateHypDryRoutingTable" (:issue:`4811`)
- In dry run mode, print HR and LS routing table in nlsrc separately (:issue:`4452`)
- Fix ASan memory leaks in unit tests (:issue:`4682`)
- Systemd service files dependency corrections for Ubuntu 18.04 (:issue:`4594`)
**Bug Fixes**
- Fix processing of interest w/ segments for segmented LSA data (:issue:`4784`)
- Fib: don't refresh neighbor router's FIB entry (:issue:`4799`)
- Disable Interest filter loopback where ever not needed (:issue:`4768`)
- Avoid crash when ndn-cxx is compiled with tests by setting canBePrefix (:issue:`4691`)
- Make sure NLSR is not using any deprecated API (:issue:`4679`)
- Fix crash in equals operator of adjacency-list (:issue:`4705`)
- Fix error handling and normalize exit codes
**Miscellaneous**
- Improving documentation for NLSR
- A beginners' guide to installing and testing on Fedora
@@ -0,0 +1,15 @@
NLSR version 0.5.1
++++++++++++++++++
**Changes**
- Set best-route strategy for certificate prefixes (:issue:`4881`)
- Use ndn-cxx InMemoryStorage for LsaSegmentStorage (:issue:`4788`)
- Switch from ndn::EventId to ndn::scheduler::EventId (:issue:`4883`)
- Add FreshnessPeriod where MustBeFresh is used (:issue:`4913`)
**Bug Fixes**
- Fix canonization by resetting io service after each neighbor (:issue:`4872`)
- Disable network interest in while fetching NLSR certificate (:issue:`4879`)
@@ -0,0 +1,23 @@
NLSR version 0.5.2
++++++++++++++++++
**Breaking Changes**
The following breaking changes make this release incompatible with the previous version.
- Use PSync version 0.2.0, sync data compression in full sync is enabled by default (:issue:`5061`, :issue:`4917`)
- Use the floating point encoding/decoding functions for hyperbolic coordinates (:issue:`4615`)
**New Features**
- Handle zero cost links in Link State Routing (:issue:`4978`)
**Improvements and Bug Fixes**
- Remove support for old combined seq no file (:issue:`4143`)
- Sync common test infrastructure with ndn-cxx
- Refactor Certificate Storage class (:issue:`5075`)
- Avoid crashing NLSR if identity cannot be created
- Change init order to register sync routes after hello data has been verified (:issue:`5009`)
- Fix empty file creation if conf file is same as dynamic (:issue:`5071`)
- On face event notification, only proceed if face id was zero or updated (:issue:`4394`)
@@ -0,0 +1,12 @@
NLSR version 0.6.0
------------------
Improvements and bug fixes
^^^^^^^^^^^^^^^^^^^^^^^^^^
- *(breaking change)* Major changes in the TLV structure and classes. Reduced codebase size and
improved compilation times. LSA de/serialize functions are replaced by wireEncode/Decode.
Updated LSA wire formats and TLV assignments. Updated nlsrc to print using the new encoding.
(:issue:`4787`, :issue:`5116`)
- LSDB refactor: switch to ``boost::multi_index`` to replace 3 LSA lists (:issue:`4127`)
- Fix wrong reaction on hello Interest timeout (:issue:`5139`)
@@ -0,0 +1,44 @@
NLSR version 0.7.0
------------------
Release date: August 18, 2023
New features
^^^^^^^^^^^^
- Add experimental support for State Vector Sync (SVS) (:issue:`5248`)
- ``nlsrc``: Add an option to query the status from remote routers (:issue:`4544`)
Notable changes and improvements
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- **Deprecate ChronoSync support**: ChronoSync support is now optional and excluded from the
default build; it remains available mainly for testing purposes (:issue:`5147`)
- Switched to the C++17 standard
- The minimum build requirements have been increased as follows:
- Either GCC >= 7.4.0 or Clang >= 6.0 is required on Linux
- On macOS, Xcode 11.3 or later is recommended; older versions may still work but are not
officially supported
- Boost >= 1.65.1 and ndn-cxx >= 0.8.1 are required on all platforms
- Sphinx 4.0 or later is required to build the documentation
- Refactor LSDB for readability and add signals to notify of modifications (:issue:`4127`)
- Retrieve LSA from the face that triggered the notification of LSA changes
- Accommodate certificate name in ``KeyLocator`` (:issue:`5195`)
- Change ``sig-type`` to ``ecdsa-sha256`` in ``nlsr.conf`` as ndn-cxx now has strict checking for it
- Improve error handling and reporting
- Stop using the ``gold`` linker on Linux; prefer instead linking with ``lld`` if installed
- Update waf build system to version 2.0.24
- Various test suite and documentation improvements
Bug fixes
^^^^^^^^^
- lsdb: Fix for issues involving incorrect retransmission behavior in segment fetcher
- Prevent NLSR from unregistering route during update for router that advertised it initially
(:issue:`5179`)
- NameLsa: fix LSDB update bug by sorting the NPLs before difference
- Fix recurring sync prefix registration on every hello data (:issue:`5157`)
- Return the appropriate exit codes when executing ``nlsrc`` advertise/withdraw commands
(:issue:`5271`)
+56 -20
View File
@@ -1,70 +1,106 @@
NLSR Versions
+++++++++++++
All NLSR Releases
=================
.. toctree::
:glob:
:hidden:
:maxdepth: 1
:reversed:
release-notes/release-notes-0.4.1
release-notes/release-notes-0.4.0
release-notes/release-notes-0.3.2
release-notes/release-notes-0.3.1
release-notes/release-notes-0.3.0
release-notes/release-notes-0.2.2
release-notes/release-notes-0.2.1
release-notes/release-notes-0.2.0
release-notes/release-notes-0.1.0
release-notes/*
* **NLSR version 0.7.0**
(:doc:`Release Notes <release-notes/release-notes-0.7.0>`, `Documentation <https://docs.named-data.net/NLSR/0.7.0/>`__)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.7.0>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.7.0.tar.xz>`__ (`checksum <https://named-data.net/downloads/nlsr-0.7.0.tar.xz.sha256>`__)
* **NLSR version 0.6.0**
(:doc:`Release Notes <release-notes/release-notes-0.6.0>`, `Documentation <https://docs.named-data.net/NLSR/0.6.0/>`__)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.6.0>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.6.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.6.0.tar.bz2.sha256>`__)
* **NLSR version 0.5.2**
(:doc:`Release Notes <release-notes/release-notes-0.5.2>`, `Documentation <https://docs.named-data.net/NLSR/0.5.2/>`__)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.5.2>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.5.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.5.2.tar.bz2.sha256>`__)
* **NLSR version 0.5.1**
(:doc:`Release Notes <release-notes/release-notes-0.5.1>`, `Documentation <https://docs.named-data.net/NLSR/0.5.1/>`__)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.5.1>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.5.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.5.1.tar.bz2.sha256>`__)
* **NLSR version 0.5.0**
(:doc:`Release Notes <release-notes/release-notes-0.5.0>`, `Documentation <https://docs.named-data.net/NLSR/0.5.0/>`__)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.5.0>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.5.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.5.0.tar.bz2.sha256>`__)
* **NLSR version 0.4.3**
(:doc:`Release Notes <release-notes/release-notes-0.4.3>`, `Documentation <https://docs.named-data.net/NLSR/0.4.3/>`__)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.4.3>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.4.3.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.4.3.tar.bz2.sha256>`__)
* **NLSR version 0.4.2**
(:doc:`Release Notes <release-notes/release-notes-0.4.2>`, `Documentation <https://docs.named-data.net/NLSR/0.4.2/>`__)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.4.2>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.4.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.4.2.tar.bz2.sha256>`__)
* **NLSR version 0.4.1**
(:doc:`Release Notes <release-notes/release-notes-0.4.1>`, `Documentation <https://named-data.net/doc/NLSR/0.4.1/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.4.1>`, `Documentation <https://docs.named-data.net/NLSR/0.4.1/>`__)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.4.1>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.4.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.4.1.tar.bz2.sha256>`__)
* **NLSR version 0.4.0**
(:doc:`Release Notes <release-notes/release-notes-0.4.0>`, `Documentation <https://named-data.net/doc/NLSR/0.4.0/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.4.0>`, `Documentation <https://docs.named-data.net/NLSR/0.4.0/>`__)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.4.0>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.4.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.4.0.tar.bz2.sha256>`__)
* **NLSR version 0.3.2**
(:doc:`Release Notes <release-notes/release-notes-0.3.2>`, `Documentation <https://named-data.net/doc/NLSR/0.3.2/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.3.2>`)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.3.2>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.3.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.3.2.tar.bz2.sha256>`__)
* **NLSR version 0.3.1**
(:doc:`Release Notes <release-notes/release-notes-0.3.1>`, `Documentation <https://named-data.net/doc/NLSR/0.3.1/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.3.1>`)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.3.1>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.3.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.3.1.tar.bz2.sha256>`__)
* **NLSR version 0.3.0**
(:doc:`Release Notes <release-notes/release-notes-0.3.0>`, `Documentation <https://named-data.net/doc/NLSR/0.3.0/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.3.0>`)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.3.0>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.3.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.3.0.tar.bz2.sha256>`__)
* **NLSR version 0.2.2**
(:doc:`Release Notes <release-notes/release-notes-0.2.2>`, `Documentation <https://named-data.net/doc/NLSR/0.2.2/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.2.2>`)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.2.2>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.2.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.2.2.tar.bz2.sha256>`__)
* **NLSR version 0.2.1**
(:doc:`Release Notes <release-notes/release-notes-0.2.1>`, `Documentation <https://named-data.net/doc/NLSR/0.2.1/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.2.1>`)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.2.1>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.2.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.2.1.tar.bz2.sha256>`__)
* **NLSR version 0.2.0**
(:doc:`Release Notes <release-notes/release-notes-0.2.0>`, `Documentation <https://named-data.net/doc/NLSR/0.2.0/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.2.0>`)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.2.0>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.2.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.2.0.tar.bz2.sha256>`__)
* **NLSR version 0.1.0**
(:doc:`Release Notes <release-notes/release-notes-0.1.0>`, `Documentation <https://named-data.net/doc/NLSR/0.1.0/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.1.0>`)
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.1.0>`__,
`src (tarball) <https://named-data.net/downloads/nlsr-0.1.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.1.0.tar.bz2.sha256>`__)
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

+52 -26
View File
@@ -4,7 +4,7 @@ general
{
; mandatory configuration command section network, site and router
network /ndn/ ; name of the network the router belongs to in ndn URI format
network /ndn ; name of the network the router belongs to in ndn URI format
site /edu/memphis ; name of the site the router belongs to in ndn URI format
router /%C1.Router/cs/pollux ; name of the router in ndn URI format
@@ -19,13 +19,16 @@ general
; InterestLifetime (in seconds) for LSA fetching
lsa-interest-lifetime 4 ; default value 4. Valid values 1-60
; sync interest lifetime of ChronoSync in milliseconds
; select sync protocol: chronosync / psync / svs
sync-protocol psync
; sync interest lifetime of ChronoSync/PSync in milliseconds
sync-interest-lifetime 60000 ; default value 60000. Valid values 1000-120,000
seq-dir /var/lib/nlsr ; path for sequence directory (Absolute path)
state-dir /var/lib/nlsr ; path for intermediate state files including sequence directory (Absolute path)
}
; the neighbor's section contains the configuration for router's neighbors and hellos behavior
; the neighbors section contains the configuration for router's neighbors and hello protocol behavior
neighbors
{
@@ -35,7 +38,7 @@ neighbors
hello-retries 3 ; interest retries number in integer. Default value 3
; valid values 1-10
hello-timeout 1 ; interest time out value in integer. Default value 1
hello-timeout 1 ; interest time out value in seconds. Default value 1
; Valid values 1-15
hello-interval 60 ; interest sending interval in seconds. Default value 60
@@ -44,12 +47,7 @@ neighbors
; adj-lsa-build-interval is the time to wait in seconds after an Adjacency LSA build is scheduled
; before actually building the Adjacency LSA
adj-lsa-build-interval 5 ; default value 5. Valid values 0-5. It is recommended that
; adj-lsa-build-interval have a lower value than routing-calc-interval
; first-hello-interval is the time to wait in seconds before sending the first Hello Interest
first-hello-interval 10 ; Default value 10. Valid values 0-10
adj-lsa-build-interval 10 ; default value 10. Valid values 5-30.
face-dataset-fetch-tries 3 ; default is 3. Valid values 1-10. The FaceDataset is
; gotten from NFD, and is needed to configure NLSR
@@ -141,21 +139,21 @@ security
filter
{
type name
regex ^[^<NLSR><INFO>]*<NLSR><INFO><><>$
regex ^[^<nlsr><INFO>]*<nlsr><INFO><><>$
}
checker
{
type customized
sig-type rsa-sha256
sig-type ecdsa-sha256
key-locator
{
type name
hyper-relation
{
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><>$
k-regex ^([^<KEY><nlsr>]*)<nlsr><KEY><>{1,3}$
k-expand \\1
h-relation equal
p-regex ^([^<NLSR><INFO>]*)<NLSR><INFO><><>$
p-regex ^([^<nlsr><INFO>]*)<nlsr><INFO><><>$
p-expand \\1
}
}
@@ -169,28 +167,56 @@ security
filter
{
type name
regex ^[^<NLSR><LSA>]*<NLSR><LSA>
regex ^[^<nlsr><LSA>]*<nlsr><LSA>
}
checker
{
type customized
sig-type rsa-sha256
sig-type ecdsa-sha256
key-locator
{
type name
hyper-relation
{
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><>$
k-regex ^([^<KEY><nlsr>]*)<nlsr><KEY><>{1,3}$
k-expand \\1
h-relation equal
; the last four components in the prefix should be <lsaType><seqNo><version><segmentNo>
p-regex ^<localhop>([^<NLSR><LSA>]*)<NLSR><LSA>(<>*)<><><><>$
p-regex ^<localhop>([^<nlsr><LSA>]*)<nlsr><LSA>(<>*)<><><><>$
p-expand \\1\\2
}
}
}
}
rule
{
id "NLSR datasets"
for data
filter
{
type name
regex ^[^<nlsr>]*<nlsr>[<lsdb><routing-table>]
}
checker
{
type customized
sig-type ecdsa-sha256
key-locator
{
type name
hyper-relation
{
k-regex ^([^<KEY>]*)<KEY><>{1,3}$ ; router key or certificate
k-expand \\1
h-relation equal
p-regex ^([^<nlsr>]*)<nlsr>[<lsdb><routing-table>]
p-expand \\1
}
}
}
}
rule
{
id "NLSR Hierarchy Exception Rule"
@@ -198,18 +224,18 @@ security
filter
{
type name
regex ^[^<KEY><%C1.Router>]*<%C1.Router>[^<KEY><NLSR>]*<KEY><><><>$
regex ^[^<KEY><%C1.Router>]*<%C1.Router>[^<KEY><nlsr>]*<KEY><><><>$
}
checker
{
type customized
sig-type rsa-sha256
sig-type ecdsa-sha256
key-locator
{
type name
hyper-relation
{
k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>{1,3}$
k-expand \\1
h-relation equal
p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><><><>$
@@ -231,7 +257,7 @@ security
checker
{
type hierarchical
sig-type rsa-sha256
sig-type ecdsa-sha256
}
}
@@ -258,11 +284,11 @@ security
checker
{
type customized
sig-type rsa-sha256
sig-type ecdsa-sha256
key-locator
{
type name
regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>{1,3}$
}
}
}
@@ -279,7 +305,7 @@ security
checker
{
type hierarchical
sig-type rsa-sha256
sig-type ecdsa-sha256
}
}
+44 -99
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -20,9 +20,6 @@
**/
#include "adjacency-list.hpp"
#include "adjacent.hpp"
#include "common.hpp"
#include "logger.hpp"
#include <algorithm>
@@ -31,41 +28,24 @@ namespace nlsr {
INIT_LOGGER(AdjacencyList);
AdjacencyList::AdjacencyList()
bool
AdjacencyList::insert(const Adjacent& adjacent)
{
}
AdjacencyList::~AdjacencyList()
{
}
int32_t
AdjacencyList::insert(Adjacent& adjacent)
{
std::list<Adjacent>::iterator it = find(adjacent.getName());
auto it = find(adjacent.getName());
if (it != m_adjList.end()) {
return -1;
return false;
}
m_adjList.push_back(adjacent);
return 0;
}
void
AdjacencyList::addAdjacents(AdjacencyList& adl)
{
for (std::list<Adjacent>::iterator it = adl.getAdjList().begin();
it != adl.getAdjList().end(); ++it) {
insert((*it));
}
return true;
}
Adjacent
AdjacencyList::getAdjacent(const ndn::Name& adjName)
{
Adjacent adj(adjName);
std::list<Adjacent>::iterator it = find(adjName);
auto it = find(adjName);
if (it != m_adjList.end()) {
return (*it);
return *it;
}
return adj;
}
@@ -73,62 +53,54 @@ AdjacencyList::getAdjacent(const ndn::Name& adjName)
bool
AdjacencyList::operator==(const AdjacencyList& adl) const
{
if (m_adjList.size() != adl.getAdjList().size()) {
auto theirList = adl.getAdjList();
if (m_adjList.size() != theirList.size()) {
return false;
}
std::set<Adjacent> ourList(m_adjList.cbegin(), m_adjList.cend());
std::set<Adjacent> theirList(adl.getAdjList().cbegin(), adl.getAdjList().cend());
return ourList == theirList;
std::set<Adjacent> ourSet(m_adjList.cbegin(), m_adjList.cend());
std::set<Adjacent> theirSet(theirList.cbegin(), theirList.cend());
return ourSet == theirSet;
}
bool
AdjacencyList::isNeighbor(const ndn::Name& adjName) const
{
std::list<Adjacent>::const_iterator it = find(adjName);
if (it == m_adjList.end())
{
return false;
}
return true;
return find(adjName) != m_adjList.end();
}
void
AdjacencyList::incrementTimedOutInterestCount(const ndn::Name& neighbor)
{
std::list<Adjacent>::iterator it = find(neighbor);
if (it == m_adjList.end()) {
return ;
auto it = find(neighbor);
if (it != m_adjList.end()) {
it->setInterestTimedOutNo(it->getInterestTimedOutNo() + 1);
}
(*it).setInterestTimedOutNo((*it).getInterestTimedOutNo() + 1);
}
void
AdjacencyList::setTimedOutInterestCount(const ndn::Name& neighbor,
uint32_t count)
AdjacencyList::setTimedOutInterestCount(const ndn::Name& neighbor, uint32_t count)
{
std::list<Adjacent>::iterator it = find(neighbor);
auto it = find(neighbor);
if (it != m_adjList.end()) {
(*it).setInterestTimedOutNo(count);
it->setInterestTimedOutNo(count);
}
}
int32_t
AdjacencyList::getTimedOutInterestCount(const ndn::Name& neighbor) const
{
std::list<Adjacent>::const_iterator it = find(neighbor);
auto it = find(neighbor);
if (it == m_adjList.end()) {
return -1;
}
return (*it).getInterestTimedOutNo();
return it->getInterestTimedOutNo();
}
Adjacent::Status
AdjacencyList::getStatusOfNeighbor(const ndn::Name& neighbor) const
{
std::list<Adjacent>::const_iterator it = find(neighbor);
auto it = find(neighbor);
if (it == m_adjList.end()) {
return Adjacent::STATUS_UNKNOWN;
}
@@ -140,7 +112,7 @@ AdjacencyList::getStatusOfNeighbor(const ndn::Name& neighbor) const
void
AdjacencyList::setStatusOfNeighbor(const ndn::Name& neighbor, Adjacent::Status status)
{
std::list<Adjacent>::iterator it = find(neighbor);
auto it = find(neighbor);
if (it != m_adjList.end()) {
it->setStatus(status);
}
@@ -163,8 +135,7 @@ AdjacencyList::isAdjLsaBuildable(const uint32_t interestRetryNo) const
{
uint32_t nTimedOutNeighbors = 0;
for (const Adjacent& adjacency : m_adjList) {
for (const auto& adjacency : m_adjList) {
if (adjacency.getStatus() == Adjacent::STATUS_ACTIVE) {
return true;
}
@@ -173,21 +144,15 @@ AdjacencyList::isAdjLsaBuildable(const uint32_t interestRetryNo) const
}
}
if (nTimedOutNeighbors == m_adjList.size()) {
return true;
}
else {
return false;
}
return nTimedOutNeighbors == m_adjList.size();
}
int32_t
AdjacencyList::getNumOfActiveNeighbor() const
{
int32_t actNbrCount = 0;
for (std::list<Adjacent>::const_iterator it = m_adjList.begin(); it != m_adjList.end(); it++) {
if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
for (const auto& adjacent: m_adjList) {
if (adjacent.getStatus() == Adjacent::STATUS_ACTIVE) {
actNbrCount++;
}
}
@@ -197,72 +162,52 @@ AdjacencyList::getNumOfActiveNeighbor() const
std::list<Adjacent>::iterator
AdjacencyList::find(const ndn::Name& adjName)
{
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
m_adjList.end(),
std::bind(&Adjacent::compare,
_1, std::cref(adjName)));
return it;
return std::find_if(m_adjList.begin(), m_adjList.end(),
std::bind(&Adjacent::compare, _1, std::cref(adjName)));
}
std::list<Adjacent>::const_iterator
AdjacencyList::find(const ndn::Name& adjName) const
{
std::list<Adjacent>::const_iterator it = std::find_if(m_adjList.cbegin(),
m_adjList.cend(),
std::bind(&Adjacent::compare,
_1, std::cref(adjName)));
return it;
return std::find_if(m_adjList.cbegin(), m_adjList.cend(),
std::bind(&Adjacent::compare, _1, std::cref(adjName)));
}
AdjacencyList::iterator
AdjacencyList::findAdjacent(const ndn::Name& adjName)
{
return std::find_if(m_adjList.begin(),
m_adjList.end(),
std::bind(&Adjacent::compare,
_1, std::cref(adjName)));
return std::find_if(m_adjList.begin(), m_adjList.end(),
std::bind(&Adjacent::compare, _1, std::cref(adjName)));
}
AdjacencyList::iterator
AdjacencyList::findAdjacent(uint64_t faceId)
{
return std::find_if(m_adjList.begin(),
m_adjList.end(),
std::bind(&Adjacent::compareFaceId,
_1, faceId));
return std::find_if(m_adjList.begin(), m_adjList.end(),
std::bind(&Adjacent::compareFaceId, _1, faceId));
}
AdjacencyList::iterator
AdjacencyList::findAdjacent(const ndn::FaceUri& faceUri)
{
return std::find_if(m_adjList.begin(),
m_adjList.end(),
std::bind(&Adjacent::compareFaceUri,
_1, faceUri));
return std::find_if(m_adjList.begin(), m_adjList.end(),
std::bind(&Adjacent::compareFaceUri, _1, faceUri));
}
uint64_t
AdjacencyList::getFaceId(const ndn::FaceUri& faceUri)
{
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
m_adjList.end(),
std::bind(&Adjacent::compareFaceUri,
_1, faceUri));
if (it != m_adjList.end()) {
return it->getFaceId();
}
return 0;
auto it = std::find_if(m_adjList.begin(), m_adjList.end(),
std::bind(&Adjacent::compareFaceUri, _1, faceUri));
return it != m_adjList.end() ? it->getFaceId() : 0;
}
void
AdjacencyList::writeLog()
{
NLSR_LOG_DEBUG("-------Adjacency List--------");
for (std::list<Adjacent>::iterator it = m_adjList.begin();
it != m_adjList.end(); it++) {
(*it).writeLog();
for (const auto& adjacent : m_adjList) {
NLSR_LOG_DEBUG(adjacent);
}
}
+7 -46
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -26,31 +26,17 @@
#include "common.hpp"
#include <list>
#include <boost/cstdint.hpp>
namespace nlsr {
class AdjacencyList
{
public:
typedef std::list<Adjacent>::const_iterator const_iterator;
typedef std::list<Adjacent>::iterator iterator;
using const_iterator = std::list<Adjacent>::const_iterator;
using iterator = std::list<Adjacent>::iterator;
AdjacencyList();
~AdjacencyList();
/*! \brief Inserts an adjacency into the list.
\param adjacent The adjacency that we want to add to this list.
\retval 0 Indicates success.
\retval 1 Indicates failure.
This function attempts to insert the supplied adjacency into this
object, which is an adjacency list.
*/
int32_t
insert(Adjacent& adjacent);
bool
insert(const Adjacent& adjacent);
std::list<Adjacent>&
getAdjList();
@@ -76,16 +62,6 @@ public:
void
setTimedOutInterestCount(const ndn::Name& neighbor, uint32_t count);
/*! \brief Copies the adjacencies in a list to this one.
\param adl The adjacency list, the entries of which we want to
copy into this object.
Copies the entries contained in one list into this object.
*/
void
addAdjacents(AdjacencyList& adl);
/*! \brief Determines whether this list can be used to build an adj. LSA.
\param interestRetryNo The maximum number of hello-interest
retries to contact a neighbor.
@@ -122,9 +98,7 @@ public:
void
reset()
{
if (m_adjList.size() > 0) {
m_adjList.clear();
}
m_adjList.clear();
}
AdjacencyList::iterator
@@ -136,19 +110,6 @@ public:
AdjacencyList::iterator
findAdjacent(const ndn::FaceUri& faceUri);
/*! \brief Hack to stop developers from using this function
It is here so that faceUri cannot be passed in as string,
converted to Name and findAdjacent(Name) be used.
So when faceUri is passed as string this will cause a compile error
*/
template <typename T = float> void
findAdjacent(const std::string& faceUri)
{
BOOST_STATIC_ASSERT_MSG(std::is_integral<T>::value,
"Don't use std::string with findAdjacent!");
}
uint64_t
getFaceId(const ndn::FaceUri& faceUri);
+132 -43
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
@@ -16,53 +16,145 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "adjacent.hpp"
#include "logger.hpp"
#include <iostream>
#include <string>
#include <cmath>
#include <limits>
#include "tlv-nlsr.hpp"
namespace nlsr {
INIT_LOGGER(Adjacent);
const float Adjacent::DEFAULT_LINK_COST = 10.0;
Adjacent::Adjacent()
: m_name()
, m_faceUri()
, m_linkCost(DEFAULT_LINK_COST)
, m_status(STATUS_INACTIVE)
, m_interestTimedOutNo(0)
, m_faceId(0)
: m_name()
, m_faceUri()
, m_linkCost(DEFAULT_LINK_COST)
, m_status(STATUS_INACTIVE)
, m_interestTimedOutNo(0)
, m_faceId(0)
{
}
Adjacent::Adjacent(const ndn::Block& block)
{
wireDecode(block);
}
Adjacent::Adjacent(const ndn::Name& an)
: m_name(an)
, m_faceUri()
, m_linkCost(DEFAULT_LINK_COST)
, m_status(STATUS_INACTIVE)
, m_interestTimedOutNo(0)
, m_faceId(0)
{
: m_name(an)
, m_faceUri()
, m_linkCost(DEFAULT_LINK_COST)
, m_status(STATUS_INACTIVE)
, m_interestTimedOutNo(0)
, m_faceId(0)
{
}
Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
Status s, uint32_t iton, uint64_t faceId)
: m_name(an)
, m_faceUri(faceUri)
, m_status(s)
, m_interestTimedOutNo(iton)
, m_faceId(faceId)
{
this->setLinkCost(lc);
}
void
Adjacent::setLinkCost(double lc)
{
// NON_ADJACENT_COST is a negative value and is used for nodes that aren't direct neighbors.
// But for direct/active neighbors, the cost cannot be negative.
if (lc < 0 && lc != NON_ADJACENT_COST) {
NLSR_LOG_ERROR(" Neighbor's link-cost cannot be negative");
NDN_THROW(ndn::tlv::Error("Neighbor's link-cost cannot be negative"));
}
Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
Status s, uint32_t iton, uint64_t faceId)
: m_name(an)
, m_faceUri(faceUri)
, m_linkCost(lc)
, m_status(s)
, m_interestTimedOutNo(iton)
, m_faceId(faceId)
{
m_linkCost = lc;
}
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Adjacent);
template<ndn::encoding::Tag TAG>
size_t
Adjacent::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
{
size_t totalLength = 0;
totalLength += prependDoubleBlock(encoder, nlsr::tlv::Cost, m_linkCost);
totalLength += prependStringBlock(encoder, nlsr::tlv::Uri, m_faceUri.toString());
totalLength += m_name.wireEncode(encoder);
totalLength += encoder.prependVarNumber(totalLength);
totalLength += encoder.prependVarNumber(nlsr::tlv::Adjacency);
return totalLength;
}
const ndn::Block&
Adjacent::wireEncode() const
{
if (m_wire.hasWire()) {
return m_wire;
}
ndn::EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
ndn::EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
Adjacent::wireDecode(const ndn::Block& wire)
{
m_name.clear();
m_faceUri = ndn::FaceUri();
m_linkCost = 0;
m_wire = wire;
if (m_wire.type() != nlsr::tlv::Adjacency) {
NDN_THROW(Error("Adjacency", m_wire.type()));
}
m_wire.parse();
auto val = m_wire.elements_begin();
if (val != m_wire.elements_end() && val->type() == ndn::tlv::Name) {
m_name.wireDecode(*val);
++val;
}
else {
NDN_THROW(Error("Missing required Name field"));
}
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Uri) {
m_faceUri = ndn::FaceUri(readString(*val));
++val;
}
else {
NDN_THROW(Error("Missing required Uri field"));
}
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Cost) {
m_linkCost = ndn::encoding::readDouble(*val);
++val;
}
else {
NDN_THROW(Error("Missing required Cost field"));
}
}
bool
Adjacent::operator==(const Adjacent& adjacent) const
{
@@ -75,23 +167,20 @@ Adjacent::operator==(const Adjacent& adjacent) const
bool
Adjacent::operator<(const Adjacent& adjacent) const
{
return (m_name < adjacent.getName()) ||
(m_linkCost < adjacent.getLinkCost());
auto linkCost = adjacent.getLinkCost();
return std::tie(m_name, m_linkCost) <
std::tie(adjacent.getName(), linkCost);
}
std::ostream&
operator<<(std::ostream& os, const Adjacent& adjacent)
{
os << "Adjacent: " << adjacent.m_name << "\n Connecting FaceUri: " << adjacent.m_faceUri
<< "\n Link cost: " << adjacent.m_linkCost << "\n Status: " << adjacent.m_status
<< "\n Interest Timed Out: " << adjacent.m_interestTimedOutNo << std::endl;
os << "Adjacent: " << adjacent.m_name
<< "\n\t\tConnecting FaceUri: " << adjacent.m_faceUri
<< "\n\t\tLink cost: " << adjacent.m_linkCost
<< "\n\t\tStatus: " << adjacent.m_status
<< "\n\t\tInterest Timed Out: " << adjacent.m_interestTimedOutNo << std::endl;
return os;
}
void
Adjacent::writeLog()
{
NLSR_LOG_DEBUG(*this);
}
} // namespace nlsr
+52 -25
View File
@@ -1,7 +1,8 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California
/*
* Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
@@ -16,29 +17,41 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include <string>
#include <cmath>
#include <boost/cstdint.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/net/face-uri.hpp>
*/
#ifndef NLSR_ADJACENT_HPP
#define NLSR_ADJACENT_HPP
#include <cmath>
#include <string>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/net/face-uri.hpp>
namespace nlsr {
/*! \brief A neighbor reachable over a Face.
*
* Represents another node that we expect to be running NLSR that we
* should be able to reach over a direct Face connection.
*
* Data abstraction for Adjacent
* Adjacent := ADJACENCY-TYPE TLV-LENGTH
* Name
* FaceUri
* LinkCost
* AdjacencyStatus
* AdjacencyInterestTimedOutNo
*/
class Adjacent
{
public:
class Error : public ndn::tlv::Error
{
public:
using ndn::tlv::Error::Error;
};
enum Status
{
STATUS_UNKNOWN = -1,
@@ -48,6 +61,8 @@ public:
Adjacent();
Adjacent(const ndn::Block& block);
Adjacent(const ndn::Name& an);
Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
@@ -60,9 +75,10 @@ public:
}
void
setName(const ndn::Name& an)
setName(const ndn::Name& name)
{
m_name = an;
m_wire.reset();
m_name = name;
}
const ndn::FaceUri&
@@ -74,21 +90,18 @@ public:
void
setFaceUri(const ndn::FaceUri& faceUri)
{
m_wire.reset();
m_faceUri = faceUri;
}
uint64_t
double
getLinkCost() const
{
uint64_t linkCost = static_cast<uint64_t>(ceil(m_linkCost));
return linkCost;
return ceil(m_linkCost);
}
void
setLinkCost(double lc)
{
m_linkCost = lc;
}
setLinkCost(double lc);
Status
getStatus() const
@@ -99,6 +112,7 @@ public:
void
setStatus(Status s)
{
m_wire.reset();
m_status = s;
}
@@ -111,6 +125,7 @@ public:
void
setInterestTimedOutNo(uint32_t iton)
{
m_wire.reset();
m_interestTimedOutNo = iton;
}
@@ -157,11 +172,19 @@ public:
return m_faceUri == faceUri;
}
template<ndn::encoding::Tag TAG>
size_t
wireEncode(ndn::EncodingImpl<TAG>& block) const;
const ndn::Block&
wireEncode() const;
void
writeLog();
wireDecode(const ndn::Block& wire);
public:
static const float DEFAULT_LINK_COST;
static constexpr double DEFAULT_LINK_COST = 10.0;
static constexpr double NON_ADJACENT_COST = -12345.0;
private:
/*! m_name The NLSR-configured router name of the neighbor */
@@ -171,17 +194,21 @@ private:
/*! m_linkCost The semi-arbitrary cost to traverse the link. */
double m_linkCost;
/*! m_status Whether the neighbor is active or not */
Status m_status;
Status m_status = STATUS_UNKNOWN;
/*! m_interestTimedOutNo How many failed Hello interests we have sent since the last reply */
uint32_t m_interestTimedOutNo;
uint32_t m_interestTimedOutNo = 0;
/*! m_faceId The NFD-assigned ID for the neighbor, used to
* determine whether a Face is available */
uint64_t m_faceId;
mutable ndn::Block m_wire;
friend std::ostream&
operator<<(std::ostream& os, const Adjacent& adjacent);
};
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Adjacent);
std::ostream&
operator<<(std::ostream& os, const Adjacent& adjacent);
+18 -20
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
/*
* Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
@@ -16,44 +16,42 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
**/
/*! \file
* Shared include file to provide a single point-of-entry, and
* hopefully improve compile times.
*/
#ifndef NLSR_COMMON_HPP
#define NLSR_COMMON_HPP
#include <ndn-cxx/common.hpp>
#include <ndn-cxx/util/time.hpp>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iterator>
#include <memory>
#include <type_traits>
#include <utility>
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/util/exception.hpp>
#include <ndn-cxx/util/time.hpp>
namespace nlsr {
using std::bind;
using std::make_shared;
using std::shared_ptr;
using std::function;
using namespace ndn::time_literals;
const ndn::time::seconds TIME_ALLOWED_FOR_CANONIZATION = ndn::time::seconds(4);
constexpr ndn::time::seconds TIME_ALLOWED_FOR_CANONIZATION = 4_s;
template<typename T, typename = void>
struct is_iterator
{
static constexpr bool value = false;
static constexpr bool value = false;
};
/*! Use C++11 iterator_traits to check if some type is an iterator
*/
template<typename T>
struct is_iterator<T, typename std::enable_if<!std::is_same<
typename std::iterator_traits<T>::value_type,
void>::value>::type>
struct is_iterator<T, std::enable_if_t<!std::is_same_v<
typename std::iterator_traits<T>::value_type, void>>>
{
static constexpr bool value = true;
static constexpr bool value = true;
};
} // namespace nlsr
+54 -128
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,109 +17,69 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "sync-logic-handler.hpp"
#include "common.hpp"
#include "conf-parameter.hpp"
#include "lsa.hpp"
#include "utility/name-helper.hpp"
#include "hello-protocol.hpp"
#include "logger.hpp"
#include "utility/name-helper.hpp"
#include <boost/lexical_cast.hpp>
namespace nlsr {
INIT_LOGGER(SyncLogicHandler);
const std::string NLSR_COMPONENT = "NLSR";
const std::string LSA_COMPONENT = "LSA";
const std::string LSA_COMPONENT{"LSA"};
template<class T>
class NullDeleter
{
public:
void
operator()(T*)
{
}
};
SyncLogicHandler::SyncLogicHandler(ndn::Face& face, const IsLsaNew& isLsaNew,
const ConfParameter& conf)
: onNewLsa(ndn::make_unique<OnNewLsa>())
, m_syncFace(face)
, m_isLsaNew(isLsaNew)
SyncLogicHandler::SyncLogicHandler(ndn::Face& face, ndn::KeyChain& keyChain,
IsLsaNew isLsaNew, const ConfParameter& conf)
: m_isLsaNew(std::move(isLsaNew))
, m_confParam(conf)
, m_nameLsaUserPrefix(ndn::Name(m_confParam.getSyncUserPrefix()).append(boost::lexical_cast<std::string>(Lsa::Type::NAME)))
, m_syncLogic(face, keyChain, m_confParam.getSyncProtocol(), m_confParam.getSyncPrefix(),
m_nameLsaUserPrefix, m_confParam.getSyncInterestLifetime(),
std::bind(&SyncLogicHandler::processUpdate, this, _1, _2, _3))
{
m_adjLsaUserPrefix = ndn::Name(m_confParam.getSyncUserPrefix())
.append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
m_coorLsaUserPrefix = ndn::Name(m_confParam.getSyncUserPrefix())
.append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE));
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_ON) {
m_syncLogic.addUserNode(m_adjLsaUserPrefix);
}
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
m_syncLogic.addUserNode(m_coorLsaUserPrefix);
}
}
void
SyncLogicHandler::createSyncSocket(const ndn::Name& syncPrefix, const ndn::time::milliseconds& syncInterestLifetime)
SyncLogicHandler::processUpdate(const ndn::Name& updateName, uint64_t highSeq, uint64_t incomingFaceId)
{
if (m_syncSocket != nullptr) {
NLSR_LOG_WARN("Trying to create Sync socket, but Sync socket already exists");
NLSR_LOG_DEBUG("Update Name: " << updateName << " Seq no: " << highSeq);
int32_t nlsrPosition = util::getNameComponentPosition(updateName, HelloProtocol::NLSR_COMPONENT);
int32_t lsaPosition = util::getNameComponentPosition(updateName, LSA_COMPONENT);
if (nlsrPosition < 0 || lsaPosition < 0) {
NLSR_LOG_WARN("Received malformed sync update");
return;
}
m_syncPrefix = syncPrefix;
ndn::Name networkName = updateName.getSubName(1, nlsrPosition - 1);
ndn::Name routerName = updateName.getSubName(lsaPosition + 1).getPrefix(-1);
ndn::Name originRouter = networkName;
originRouter.append(routerName);
// Build LSA sync update prefix
buildUpdatePrefix();
NLSR_LOG_DEBUG("Creating Sync socket. Sync Prefix: " << m_syncPrefix);
// The face's lifetime is managed in main.cpp; SyncSocket should not manage the memory
// of the object
std::shared_ptr<ndn::Face> facePtr(&m_syncFace, NullDeleter<ndn::Face>());
const auto fixedSession = ndn::name::Component::fromNumber(0);
m_syncSocket = std::make_shared<chronosync::Socket>(m_syncPrefix, m_nameLsaUserPrefix, *facePtr,
std::bind(&SyncLogicHandler::onChronoSyncUpdate, this, _1),
chronosync::Socket::DEFAULT_NAME, chronosync::Socket::DEFAULT_VALIDATOR,
syncInterestLifetime, fixedSession);
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
m_syncSocket->addSyncNode(m_adjLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
}
else if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
m_syncSocket->addSyncNode(m_coorLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
}
else {
m_syncSocket->addSyncNode(m_adjLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
m_syncSocket->addSyncNode(m_coorLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
}
}
void
SyncLogicHandler::onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& v)
{
NLSR_LOG_DEBUG("Received ChronoSync update event");
for (size_t i = 0; i < v.size(); i++){
ndn::Name updateName = v[i].session.getPrefix(-1);
NLSR_LOG_DEBUG("Update Name: " << updateName << " Seq no: " << v[i].high);
int32_t nlsrPosition = util::getNameComponentPosition(updateName, nlsr::NLSR_COMPONENT);
int32_t lsaPosition = util::getNameComponentPosition(updateName, nlsr::LSA_COMPONENT);
if (nlsrPosition < 0 || lsaPosition < 0) {
NLSR_LOG_WARN("Received malformed sync update");
return;
}
ndn::Name networkName = updateName.getSubName(1, nlsrPosition-1);
ndn::Name routerName = updateName.getSubName(lsaPosition + 1).getPrefix(-1);
ndn::Name originRouter = networkName;
originRouter.append(routerName);
processUpdateFromSync(originRouter, updateName, v[i].high);
}
processUpdateFromSync(originRouter, updateName, highSeq, incomingFaceId);
}
void
SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
const ndn::Name& updateName, const uint64_t& seqNo)
const ndn::Name& updateName, uint64_t seqNo,
uint64_t incomingFaceId)
{
NLSR_LOG_DEBUG("Origin Router of update: " << originRouter);
@@ -129,24 +89,25 @@ SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
Lsa::Type lsaType;
std::istringstream(updateName.get(updateName.size()-1).toUri()) >> lsaType;
NLSR_LOG_DEBUG("Received sync update with higher " << lsaType
<< " sequence number than entry in LSDB");
NLSR_LOG_DEBUG("Received sync update with higher " << lsaType <<
" sequence number than entry in LSDB");
if (m_isLsaNew(originRouter, lsaType, seqNo)) {
if (m_isLsaNew(originRouter, lsaType, seqNo, incomingFaceId)) {
if (lsaType == Lsa::Type::ADJACENCY && seqNo != 0 &&
m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
NLSR_LOG_ERROR("Got an update for adjacency LSA when hyperbolic routing"
<< " is enabled. Not going to fetch.");
NLSR_LOG_ERROR("Got an update for adjacency LSA when hyperbolic routing " <<
"is enabled. Not going to fetch.");
return;
}
if (lsaType == Lsa::Type::COORDINATE && seqNo != 0 &&
m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
NLSR_LOG_ERROR("Got an update for coordinate LSA when link-state"
<< " is enabled. Not going to fetch.");
NLSR_LOG_ERROR("Got an update for coordinate LSA when link-state " <<
"is enabled. Not going to fetch.");
return;
}
(*onNewLsa)(updateName, seqNo);
onNewLsa(updateName, seqNo, originRouter, incomingFaceId);
}
}
}
@@ -154,54 +115,19 @@ SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
void
SyncLogicHandler::publishRoutingUpdate(const Lsa::Type& type, const uint64_t& seqNo)
{
if (m_syncSocket == nullptr) {
NLSR_LOG_FATAL("Cannot publish routing update; SyncSocket does not exist");
BOOST_THROW_EXCEPTION(SyncLogicHandler::Error("Cannot publish routing update; SyncSocket does not exist"));
}
switch (type) {
case Lsa::Type::ADJACENCY:
publishSyncUpdate(m_adjLsaUserPrefix, seqNo);
m_syncLogic.publishUpdate(m_adjLsaUserPrefix, seqNo);
break;
case Lsa::Type::COORDINATE:
publishSyncUpdate(m_coorLsaUserPrefix, seqNo);
m_syncLogic.publishUpdate(m_coorLsaUserPrefix, seqNo);
break;
case Lsa::Type::NAME:
publishSyncUpdate(m_nameLsaUserPrefix, seqNo);
m_syncLogic.publishUpdate(m_nameLsaUserPrefix, seqNo);
break;
default:
break;
}
}
void
SyncLogicHandler::buildUpdatePrefix()
{
ndn::Name updatePrefix = m_confParam.getLsaPrefix();
updatePrefix.append(m_confParam.getSiteName());
updatePrefix.append(m_confParam.getRouterName());
m_nameLsaUserPrefix = updatePrefix;
m_nameLsaUserPrefix.append(std::to_string(Lsa::Type::NAME));
m_adjLsaUserPrefix = updatePrefix;
m_adjLsaUserPrefix.append(std::to_string(Lsa::Type::ADJACENCY));
m_coorLsaUserPrefix = updatePrefix;
m_coorLsaUserPrefix.append(std::to_string(Lsa::Type::COORDINATE));
}
void
SyncLogicHandler::publishSyncUpdate(const ndn::Name& updatePrefix, uint64_t seqNo)
{
NLSR_LOG_DEBUG("Publishing Sync Update. Prefix: " << updatePrefix << " Seq No: " << seqNo);
ndn::Name updateName(updatePrefix);
std::string data("NoData");
m_syncSocket->publishData(reinterpret_cast<const uint8_t*>(data.c_str()), data.size(),
ndn::time::milliseconds(1000), seqNo, updateName);
}
} // namespace nlsr
+19 -66
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,63 +17,40 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NLSR_SYNC_LOGIC_HANDLER_HPP
#define NLSR_SYNC_LOGIC_HANDLER_HPP
#include "conf-parameter.hpp"
#include "test-access-control.hpp"
#include "lsa/lsa.hpp"
#include "signals.hpp"
#include "lsa.hpp"
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/util/signal.hpp>
#include <ChronoSync/socket.hpp>
#include <boost/throw_exception.hpp>
class InterestManager;
#include "sync-protocol-adapter.hpp"
#include "test-access-control.hpp"
namespace nlsr {
class ConfParameter;
/*! \brief NLSR-to-ChronoSync interaction point
*
* This class serves as the abstraction for the syncing portion of
* NLSR and its components. NLSR has no particular reliance on
* ChronoSync, except that the NLSR source would need to be modified
* for use with other sync protocols.
*
*/
class SyncLogicHandler
{
public:
using IsLsaNew =
std::function<bool(const ndn::Name&, const Lsa::Type& lsaType, const uint64_t&)>;
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
using std::runtime_error::runtime_error;
};
SyncLogicHandler(ndn::Face& face, const IsLsaNew& isLsaNew, const ConfParameter& conf);
using IsLsaNew =
std::function<bool(const ndn::Name&, const Lsa::Type& lsaType, const uint64_t&, uint64_t/*inFace*/)>;
/*! \brief Hook function to call whenever sync detects new data.
*
* This function packages the sync information into discrete updates
* and passes those off to another function, processUpdateFromSync.
* \sa processUpdateFromSync
*
* \param v A container with the new information sync has received
*/
void
onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& v);
SyncLogicHandler(ndn::Face& face, ndn::KeyChain& keyChain,
IsLsaNew isLsaNew, const ConfParameter& conf);
/*! \brief Instruct ChronoSync to publish an update.
*
@@ -87,25 +64,16 @@ public:
void
publishRoutingUpdate(const Lsa::Type& type, const uint64_t& seqNo);
/*! \brief Create and configure a socket to enable ChronoSync for this NLSR.
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/*! \brief Callback from Sync protocol
*
* In a typical situation this only needs to be called once, when NLSR starts.
* \param syncPrefix The sync prefix you want this ChronoSync to use
* \param syncInterestLifetime ChronoSync sends a periodic sync interest every \p syncInterestLifetime / 2 ms
* \sa Nlsr::initialize
* \param updateName The prefix for which sync reports an update
* \param highSeq The latest sequence number of the update
*/
void
createSyncSocket(const ndn::Name& syncPrefix,
const ndn::time::milliseconds& syncInterestLifetime =
ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT));
processUpdate(const ndn::Name& updateName, uint64_t highSeq, uint64_t incomingFaceId);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/*! \brief Simple function to glue Name components together
*/
void
buildUpdatePrefix();
private:
/*! \brief Determine which kind of LSA was updated and fetch it.
*
* Checks that the received update is not from us, which can happen,
@@ -116,24 +84,12 @@ private:
*/
void
processUpdateFromSync(const ndn::Name& originRouter,
const ndn::Name& updateName, const uint64_t& seqNo);
/*! \brief Instruct ChronoSync, via the sync socket, to publish an update.
*
* Each ChronoSync instance maintains its own PIT for sync
* updates. This function creates a data that satisfies that update,
* so that the interested routers will know new data is available.
*/
void
publishSyncUpdate(const ndn::Name& updatePrefix, uint64_t seqNo);
const ndn::Name& updateName, uint64_t seqNo, uint64_t incomingFaceId);
public:
std::unique_ptr<OnNewLsa> onNewLsa;
OnNewLsa onNewLsa;
private:
ndn::Face& m_syncFace;
std::shared_ptr<chronosync::Socket> m_syncSocket;
ndn::Name m_syncPrefix;
IsLsaNew m_isLsaNew;
const ConfParameter& m_confParam;
@@ -142,10 +98,7 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
ndn::Name m_adjLsaUserPrefix;
ndn::Name m_coorLsaUserPrefix;
private:
static const std::string NLSR_COMPONENT;
static const std::string LSA_COMPONENT;
SyncProtocolAdapter m_syncLogic;
};
} // namespace nlsr
+171
View File
@@ -0,0 +1,171 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sync-protocol-adapter.hpp"
#include "logger.hpp"
namespace nlsr {
INIT_LOGGER(SyncProtocolAdapter);
#ifdef HAVE_CHRONOSYNC
const auto FIXED_SESSION = ndn::name::Component::fromNumber(0);
#endif
SyncProtocolAdapter::SyncProtocolAdapter(ndn::Face& face,
ndn::KeyChain& keyChain,
SyncProtocol syncProtocol,
const ndn::Name& syncPrefix,
const ndn::Name& userPrefix,
ndn::time::milliseconds syncInterestLifetime,
SyncUpdateCallback syncUpdateCallback)
: m_syncProtocol(syncProtocol)
, m_syncUpdateCallback(std::move(syncUpdateCallback))
{
switch (m_syncProtocol) {
#ifdef HAVE_CHRONOSYNC
case SyncProtocol::CHRONOSYNC:
NDN_LOG_DEBUG("Using ChronoSync");
m_chronoSyncLogic = std::make_shared<chronosync::Logic>(face,
syncPrefix,
userPrefix,
[this] (auto&&... args) { onChronoSyncUpdate(std::forward<decltype(args)>(args)...); },
chronosync::Logic::DEFAULT_NAME,
chronosync::Logic::DEFAULT_VALIDATOR,
chronosync::Logic::DEFAULT_RESET_TIMER,
chronosync::Logic::DEFAULT_CANCEL_RESET_TIMER,
chronosync::Logic::DEFAULT_RESET_INTEREST_LIFETIME,
syncInterestLifetime,
chronosync::Logic::DEFAULT_SYNC_REPLY_FRESHNESS,
chronosync::Logic::DEFAULT_RECOVERY_INTEREST_LIFETIME,
FIXED_SESSION);
break;
#endif // HAVE_CHRONOSYNC
#ifdef HAVE_PSYNC
case SyncProtocol::PSYNC:
NDN_LOG_DEBUG("Using PSync");
m_psyncLogic = std::make_shared<psync::FullProducer>(face,
keyChain,
80,
syncPrefix,
userPrefix,
[this] (auto&&... args) { onPSyncUpdate(std::forward<decltype(args)>(args)...); },
syncInterestLifetime);
break;
#endif // HAVE_PSYNC
#ifdef HAVE_SVS
case SyncProtocol::SVS:
NDN_LOG_DEBUG("Using SVS");
m_svsCore = std::make_shared<ndn::svs::SVSyncCore>(face,
syncPrefix,
[this] (auto&&... args) { onSvsUpdate(std::forward<decltype(args)>(args)...); });
break;
#endif // HAVE_SVS
default:
NDN_CXX_UNREACHABLE;
}
}
void
SyncProtocolAdapter::addUserNode(const ndn::Name& userPrefix)
{
switch (m_syncProtocol) {
#ifdef HAVE_CHRONOSYNC
case SyncProtocol::CHRONOSYNC:
m_chronoSyncLogic->addUserNode(userPrefix, chronosync::Logic::DEFAULT_NAME, FIXED_SESSION);
break;
#endif // HAVE_CHRONOSYNC
#ifdef HAVE_PSYNC
case SyncProtocol::PSYNC:
m_psyncLogic->addUserNode(userPrefix);
break;
#endif // HAVE_PSYNC
#ifdef HAVE_SVS
case SyncProtocol::SVS:
break;
#endif // HAVE_SVS
default:
NDN_CXX_UNREACHABLE;
}
}
void
SyncProtocolAdapter::publishUpdate(const ndn::Name& userPrefix, uint64_t seq)
{
switch (m_syncProtocol) {
#ifdef HAVE_CHRONOSYNC
case SyncProtocol::CHRONOSYNC:
m_chronoSyncLogic->updateSeqNo(seq, userPrefix);
break;
#endif // HAVE_CHRONOSYNC
#ifdef HAVE_PSYNC
case SyncProtocol::PSYNC:
m_psyncLogic->publishName(userPrefix, seq);
break;
#endif // HAVE_PSYNC
#ifdef HAVE_SVS
case SyncProtocol::SVS:
m_svsCore->updateSeqNo(seq, userPrefix);
break;
#endif // HAVE_SVS
default:
NDN_CXX_UNREACHABLE;
}
}
#ifdef HAVE_CHRONOSYNC
void
SyncProtocolAdapter::onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates)
{
NLSR_LOG_TRACE("Received ChronoSync update event");
for (const auto& update : updates) {
// Remove FIXED_SESSION
m_syncUpdateCallback(update.session.getPrefix(-1), update.high, 0);
}
}
#endif // HAVE_CHRONOSYNC
#ifdef HAVE_PSYNC
void
SyncProtocolAdapter::onPSyncUpdate(const std::vector<psync::MissingDataInfo>& updates)
{
NLSR_LOG_TRACE("Received PSync update event");
for (const auto& update : updates) {
m_syncUpdateCallback(update.prefix, update.highSeq, update.incomingFace);
}
}
#endif // HAVE_PSYNC
#ifdef HAVE_SVS
void
SyncProtocolAdapter::onSvsUpdate(const std::vector<ndn::svs::MissingDataInfo>& updates)
{
NLSR_LOG_TRACE("Received SVS update event");
for (const auto& update : updates) {
m_syncUpdateCallback(update.nodeId, update.high, update.incomingFace);
}
}
#endif // HAVE_SVS
} // namespace nlsr
+128
View File
@@ -0,0 +1,128 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NLSR_SYNC_PROTOCOL_ADAPTER_HPP
#define NLSR_SYNC_PROTOCOL_ADAPTER_HPP
#include "conf-parameter.hpp"
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#ifdef HAVE_CHRONOSYNC
#include <ChronoSync/logic.hpp>
#endif
#ifdef HAVE_PSYNC
#include <PSync/full-producer.hpp>
#endif
#ifdef HAVE_SVS
#include <ndn-svs/core.hpp>
#endif
namespace nlsr {
using SyncUpdateCallback = std::function<void(const ndn::Name& updateName,
uint64_t seqNo, uint64_t incomingFaceId)>;
class SyncProtocolAdapter
{
public:
SyncProtocolAdapter(ndn::Face& face,
ndn::KeyChain& keyChain,
SyncProtocol syncProtocol,
const ndn::Name& syncPrefix,
const ndn::Name& userPrefix,
ndn::time::milliseconds syncInterestLifetime,
SyncUpdateCallback syncUpdateCallback);
/*! \brief Add user node to Sync
*
* \param userPrefix the Name under which the application will publishData
*/
void
addUserNode(const ndn::Name& userPrefix);
/*! \brief Publish update to Sync
*
* NLSR forces sequences number on the sync protocol
* as it manages is its own sequence number by storing it in a file.
*
* \param userPrefix the Name to be updated
* \param seq the sequence of userPrefix
*/
void
publishUpdate(const ndn::Name& userPrefix, uint64_t seq);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
#ifdef HAVE_CHRONOSYNC
/*! \brief Hook function to call whenever ChronoSync detects new data.
*
* This function packages the sync information into discrete updates
* and passes those off to another function, m_syncUpdateCallback.
*
* \param updates A container with the new information sync has received
*/
void
onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates);
#endif // HAVE_CHRONOSYNC
#ifdef HAVE_PSYNC
/*! \brief Hook function to call whenever PSync detects new data.
*
* This function packages the sync information into discrete updates
* and passes those off to another function, m_syncUpdateCallback.
*
* \param updates A container with the new information sync has received
*/
void
onPSyncUpdate(const std::vector<psync::MissingDataInfo>& updates);
#endif // HAVE_PSYNC
#ifdef HAVE_SVS
/*! \brief Hook function to call whenever SVS detects new data.
*
* This function packages the sync information into discrete updates
* and passes those off to another function, m_syncUpdateCallback.
*
* \param updates A container with the new information sync has received
*/
void
onSvsUpdate(const std::vector<ndn::svs::MissingDataInfo>& updates);
#endif // HAVE_SVS
private:
SyncProtocol m_syncProtocol;
SyncUpdateCallback m_syncUpdateCallback;
#ifdef HAVE_CHRONOSYNC
std::shared_ptr<chronosync::Logic> m_chronoSyncLogic;
#endif
#ifdef HAVE_PSYNC
std::shared_ptr<psync::FullProducer> m_psyncLogic;
#endif
#ifdef HAVE_SVS
std::shared_ptr<ndn::svs::SVSyncCore> m_svsCore;
#endif
};
} // namespace nlsr
#endif // NLSR_SYNC_PROTOCOL_ADAPTER_HPP
+210 -160
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,21 +17,25 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "conf-file-processor.hpp"
#include "conf-parameter.hpp"
#include "adjacent.hpp"
#include "utility/name-helper.hpp"
#include "update/prefix-update-processor.hpp"
#include <boost/cstdint.hpp>
#include "utility/name-helper.hpp"
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/net/face-uri.hpp>
#include <ndn-cxx/util/io.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <iostream>
#include <fstream>
#include <iostream>
namespace bf = boost::filesystem;
namespace nlsr {
@@ -40,7 +44,6 @@ class ConfigurationVariable
{
public:
typedef std::function<void(T)> ConfParameterCallback;
typedef boost::property_tree::ptree ConfigSection;
ConfigurationVariable(const std::string& key, const ConfParameterCallback& setter)
: m_key(key)
@@ -125,8 +128,8 @@ private:
private:
const std::string m_key;
const ConfParameterCallback m_setterCallback;
T m_defaultValue;
T m_defaultValue;
T m_minValue;
T m_maxValue;
@@ -134,79 +137,75 @@ private:
bool m_isRequired;
};
ConfFileProcessor::ConfFileProcessor(ConfParameter& confParam)
: m_confFileName(confParam.getConfFileName())
, m_confParam(confParam)
{
}
bool
ConfFileProcessor::processConfFile()
{
bool ret = true;
std::ifstream inputFile;
inputFile.open(m_confFileName.c_str());
std::ifstream inputFile(m_confFileName);
if (!inputFile.is_open()) {
std::string msg = "Failed to read configuration file: ";
msg += m_confFileName;
std::cerr << msg << std::endl;
std::cerr << "Failed to read configuration file: " << m_confFileName << std::endl;
return false;
}
ret = load(inputFile);
inputFile.close();
return ret;
if (!load(inputFile)) {
return false;
}
m_confParam.buildRouterAndSyncUserPrefix();
m_confParam.writeLog();
return true;
}
bool
ConfFileProcessor::load(std::istream& input)
{
ConfigSection pt;
bool ret = true;
try {
boost::property_tree::read_info(input, pt);
}
catch (const boost::property_tree::info_parser_error& error) {
std::stringstream msg;
std::cerr << "Failed to parse configuration file " << std::endl;
std::cerr << m_confFileName << std::endl;
catch (const boost::property_tree::ptree_error& e) {
std::cerr << "Failed to parse configuration file '" << m_confFileName
<< "': " << e.what() << std::endl;
return false;
}
for (ConfigSection::const_iterator tn = pt.begin();
tn != pt.end(); ++tn) {
ret = processSection(tn->first, tn->second);
if (ret == false) {
break;
for (const auto& tn : pt) {
if (!processSection(tn.first, tn.second)) {
return false;
}
}
return ret;
return true;
}
bool
ConfFileProcessor::processSection(const std::string& sectionName, const ConfigSection& section)
{
bool ret = true;
if (sectionName == "general")
{
if (sectionName == "general") {
ret = processConfSectionGeneral(section);
}
else if (sectionName == "neighbors")
{
else if (sectionName == "neighbors") {
ret = processConfSectionNeighbors(section);
}
else if (sectionName == "hyperbolic")
{
else if (sectionName == "hyperbolic") {
ret = processConfSectionHyperbolic(section);
}
else if (sectionName == "fib")
{
else if (sectionName == "fib") {
ret = processConfSectionFib(section);
}
else if (sectionName == "advertising")
{
else if (sectionName == "advertising") {
ret = processConfSectionAdvertising(section);
}
else if (sectionName == "security")
{
else if (sectionName == "security") {
ret = processConfSectionSecurity(section);
}
else
{
std::cerr << "Wrong configuration section: " << sectionName << std::endl;
else {
std::cerr << "Unknown configuration section: " << sectionName << std::endl;
}
return ret;
}
@@ -214,32 +213,64 @@ ConfFileProcessor::processSection(const std::string& sectionName, const ConfigSe
bool
ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
{
// sync-protocol
std::string syncProtocol = section.get<std::string>("sync-protocol", "psync");
if (syncProtocol == "chronosync") {
#ifdef HAVE_CHRONOSYNC
m_confParam.setSyncProtocol(SyncProtocol::CHRONOSYNC);
#else
std::cerr << "NLSR was compiled without ChronoSync support!\n";
return false;
#endif
}
else if (syncProtocol == "psync") {
#ifdef HAVE_PSYNC
m_confParam.setSyncProtocol(SyncProtocol::PSYNC);
#else
std::cerr << "NLSR was compiled without PSync support!\n";
return false;
#endif
}
else if (syncProtocol == "svs") {
#ifdef HAVE_SVS
m_confParam.setSyncProtocol(SyncProtocol::SVS);
#else
std::cerr << "NLSR was compiled without SVS support!\n";
return false;
#endif
}
else {
std::cerr << "Sync protocol '" << syncProtocol << "' is not supported!\n"
<< "Use 'chronosync' or 'psync' or 'svs'\n";
return false;
}
try {
std::string network = section.get<std::string>("network");
std::string site = section.get<std::string>("site");
std::string router = section.get<std::string>("router");
ndn::Name networkName(network);
if (!networkName.empty()) {
m_nlsr.getConfParameter().setNetwork(networkName);
m_confParam.setNetwork(networkName);
}
else {
std::cerr << " Network can not be null or empty or in bad URI format :(!" << std::endl;
std::cerr << "Network can not be null or empty or in bad URI format" << std::endl;
return false;
}
ndn::Name siteName(site);
if (!siteName.empty()) {
m_nlsr.getConfParameter().setSiteName(siteName);
m_confParam.setSiteName(siteName);
}
else {
std::cerr << "Site can not be null or empty or in bad URI format:( !" << std::endl;
std::cerr << "Site can not be null or empty or in bad URI format" << std::endl;
return false;
}
ndn::Name routerName(router);
if (!routerName.empty()) {
m_nlsr.getConfParameter().setRouterName(routerName);
m_confParam.setRouterName(routerName);
}
else {
std::cerr << " Router name can not be null or empty or in bad URI format:( !" << std::endl;
std::cerr << "Router name can not be null or empty or in bad URI format" << std::endl;
return false;
}
}
@@ -252,21 +283,20 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
uint32_t lsaRefreshTime = section.get<uint32_t>("lsa-refresh-time", LSA_REFRESH_TIME_DEFAULT);
if (lsaRefreshTime >= LSA_REFRESH_TIME_MIN && lsaRefreshTime <= LSA_REFRESH_TIME_MAX) {
m_nlsr.getConfParameter().setLsaRefreshTime(lsaRefreshTime);
m_confParam.setLsaRefreshTime(lsaRefreshTime);
}
else {
std::cerr << "Wrong value for lsa-refresh-time ";
std::cerr << "Allowed value: " << LSA_REFRESH_TIME_MIN << "-";;
std::cerr << LSA_REFRESH_TIME_MAX << std::endl;
std::cerr << "Invalid value for lsa-refresh-time. "
<< "Allowed range: " << LSA_REFRESH_TIME_MIN
<< "-" << LSA_REFRESH_TIME_MAX << std::endl;
return false;
}
// router-dead-interval
uint32_t routerDeadInterval = section.get<uint32_t>("router-dead-interval", (2*lsaRefreshTime));
uint32_t routerDeadInterval = section.get<uint32_t>("router-dead-interval", 2 * lsaRefreshTime);
if (routerDeadInterval > m_nlsr.getConfParameter().getLsaRefreshTime()) {
m_nlsr.getConfParameter().setRouterDeadInterval(routerDeadInterval);
if (routerDeadInterval > m_confParam.getLsaRefreshTime()) {
m_confParam.setRouterDeadInterval(routerDeadInterval);
}
else {
std::cerr << "Value of router-dead-interval must be larger than lsa-refresh-time" << std::endl;
@@ -277,59 +307,85 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
int lifetime = section.get<int>("lsa-interest-lifetime", LSA_INTEREST_LIFETIME_DEFAULT);
if (lifetime >= LSA_INTEREST_LIFETIME_MIN && lifetime <= LSA_INTEREST_LIFETIME_MAX) {
m_nlsr.getConfParameter().setLsaInterestLifetime(ndn::time::seconds(lifetime));
m_confParam.setLsaInterestLifetime(ndn::time::seconds(lifetime));
}
else {
std::cerr << "Wrong value for lsa-interest-timeout. "
<< "Allowed value:" << LSA_INTEREST_LIFETIME_MIN << "-"
<< LSA_INTEREST_LIFETIME_MAX << std::endl;
std::cerr << "Invalid value for lsa-interest-timeout. "
<< "Allowed range: " << LSA_INTEREST_LIFETIME_MIN
<< "-" << LSA_INTEREST_LIFETIME_MAX << std::endl;
return false;
}
uint32_t syncInterestLifetime = section.get<uint32_t>("sync-interest-lifetime", SYNC_INTEREST_LIFETIME_DEFAULT);
// sync-interest-lifetime
uint32_t syncInterestLifetime = section.get<uint32_t>("sync-interest-lifetime",
SYNC_INTEREST_LIFETIME_DEFAULT);
if (syncInterestLifetime >= SYNC_INTEREST_LIFETIME_MIN &&
syncInterestLifetime <= SYNC_INTEREST_LIFETIME_MAX) {
m_nlsr.getConfParameter().setSyncInterestLifetime(syncInterestLifetime);
m_confParam.setSyncInterestLifetime(syncInterestLifetime);
}
else {
std::cerr << "Wrong value for sync-interest-lifetime. "
<< "Allowed value:" << SYNC_INTEREST_LIFETIME_MIN << "-"
<< SYNC_INTEREST_LIFETIME_MAX << std::endl;
std::cerr << "Invalid value for sync-interest-lifetime. "
<< "Allowed range: " << SYNC_INTEREST_LIFETIME_MIN
<< "-" << SYNC_INTEREST_LIFETIME_MAX << std::endl;
return false;
}
try {
std::string seqDir = section.get<std::string>("seq-dir");
if (boost::filesystem::exists(seqDir)) {
if (boost::filesystem::is_directory(seqDir)) {
std::string testFileName=seqDir+"/test.seq";
std::ofstream testOutFile;
testOutFile.open(testFileName.c_str());
if (testOutFile.is_open() && testOutFile.good()) {
m_nlsr.getConfParameter().setSeqFileDir(seqDir);
std::string stateDir = section.get<std::string>("state-dir");
if (bf::exists(stateDir)) {
if (bf::is_directory(stateDir)) {
// copying nlsr.conf file to a user-defined directory for possible modification
std::string conFileDynamic = (bf::path(stateDir) / "nlsr.conf").string();
if (m_confFileName == conFileDynamic) {
std::cerr << "Please use nlsr.conf stored at another location "
<< "or change the state-dir in the configuration." << std::endl;
std::cerr << "The file at " << conFileDynamic <<
" is used as dynamic file for saving NLSR runtime changes." << std::endl;
std::cerr << "The dynamic file can be used for next run "
<< "after copying to another location." << std::endl;
return false;
}
m_confParam.setConfFileNameDynamic(conFileDynamic);
try {
bf::copy_file(m_confFileName, conFileDynamic,
#if BOOST_VERSION >= 107400
bf::copy_options::overwrite_existing
#else
bf::copy_option::overwrite_if_exists
#endif
);
}
catch (const bf::filesystem_error& e) {
std::cerr << "Error copying conf file to the state directory: " << e.what() << std::endl;
return false;
}
std::string testFileName = (bf::path(stateDir) / "test.seq").string();
std::ofstream testOutFile(testFileName);
if (testOutFile) {
m_confParam.setStateFileDir(stateDir);
}
else {
std::cerr << "User does not have read and write permission on the directory";
std::cerr << std::endl;
std::cerr << "NLSR does not have read/write permission on the state directory" << std::endl;
return false;
}
testOutFile.close();
remove(testFileName.c_str());
}
else {
std::cerr << "Provided path is not a directory" << std::endl;
std::cerr << "Provided path '" << stateDir << "' is not a directory" << std::endl;
return false;
}
}
else {
std::cerr << "Provided sequence directory <" << seqDir << "> does not exist" << std::endl;
std::cerr << "Provided state directory '" << stateDir << "' does not exist" << std::endl;
return false;
}
}
catch (const std::exception& ex) {
std::cerr << "You must configure sequence directory" << std::endl;
std::cerr << "You must configure state directory" << std::endl;
std::cerr << ex.what() << std::endl;
return false;
}
@@ -344,13 +400,11 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
int retrials = section.get<int>("hello-retries", HELLO_RETRIES_DEFAULT);
if (retrials >= HELLO_RETRIES_MIN && retrials <= HELLO_RETRIES_MAX) {
m_nlsr.getConfParameter().setInterestRetryNumber(retrials);
m_confParam.setInterestRetryNumber(retrials);
}
else {
std::cerr << "Wrong value for hello-retries." << std::endl;
std::cerr << "Allowed value:" << HELLO_RETRIES_MIN << "-";
std::cerr << HELLO_RETRIES_MAX << std::endl;
std::cerr << "Invalid value for hello-retries. "
<< "Allowed range: " << HELLO_RETRIES_MIN << "-" << HELLO_RETRIES_MAX << std::endl;
return false;
}
@@ -358,13 +412,11 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
uint32_t timeOut = section.get<uint32_t>("hello-timeout", HELLO_TIMEOUT_DEFAULT);
if (timeOut >= HELLO_TIMEOUT_MIN && timeOut <= HELLO_TIMEOUT_MAX) {
m_nlsr.getConfParameter().setInterestResendTime(timeOut);
m_confParam.setInterestResendTime(timeOut);
}
else {
std::cerr << "Wrong value for hello-timeout. ";
std::cerr << "Allowed value:" << HELLO_TIMEOUT_MIN << "-";
std::cerr << HELLO_TIMEOUT_MAX << std::endl;
std::cerr << "Invalid value for hello-timeout. "
<< "Allowed range: " << HELLO_TIMEOUT_MIN << "-" << HELLO_TIMEOUT_MAX << std::endl;
return false;
}
@@ -372,13 +424,11 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
uint32_t interval = section.get<uint32_t>("hello-interval", HELLO_INTERVAL_DEFAULT);
if (interval >= HELLO_INTERVAL_MIN && interval <= HELLO_INTERVAL_MAX) {
m_nlsr.getConfParameter().setInfoInterestInterval(interval);
m_confParam.setInfoInterestInterval(interval);
}
else {
std::cerr << "Wrong value for hello-interval. ";
std::cerr << "Allowed value:" << HELLO_INTERVAL_MIN << "-";
std::cerr << HELLO_INTERVAL_MAX << std::endl;
std::cerr << "Invalid value for hello-interval. "
<< "Allowed range: " << HELLO_INTERVAL_MIN << "-" << HELLO_INTERVAL_MAX << std::endl;
return false;
}
@@ -386,7 +436,7 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
// adj-lsa-build-interval
ConfigurationVariable<uint32_t> adjLsaBuildInterval("adj-lsa-build-interval",
std::bind(&ConfParameter::setAdjLsaBuildInterval,
&m_nlsr.getConfParameter(), _1));
&m_confParam, _1));
adjLsaBuildInterval.setMinAndMaxValue(ADJ_LSA_BUILD_INTERVAL_MIN, ADJ_LSA_BUILD_INTERVAL_MAX);
adjLsaBuildInterval.setOptional(ADJ_LSA_BUILD_INTERVAL_DEFAULT);
@@ -396,8 +446,7 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
// Set the retry count for fetching the FaceStatus dataset
ConfigurationVariable<uint32_t> faceDatasetFetchTries("face-dataset-fetch-tries",
std::bind(&ConfParameter::setFaceDatasetFetchTries,
&m_nlsr.getConfParameter(),
_1));
&m_confParam, _1));
faceDatasetFetchTries.setMinAndMaxValue(FACE_DATASET_FETCH_TRIES_MIN,
FACE_DATASET_FETCH_TRIES_MAX);
@@ -409,9 +458,8 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
// Set the interval between FaceStatus dataset fetch attempts.
ConfigurationVariable<uint32_t> faceDatasetFetchInterval("face-dataset-fetch-interval",
bind(&ConfParameter::setFaceDatasetFetchInterval,
&m_nlsr.getConfParameter(),
_1));
std::bind(&ConfParameter::setFaceDatasetFetchInterval,
&m_confParam, _1));
faceDatasetFetchInterval.setMinAndMaxValue(FACE_DATASET_FETCH_INTERVAL_MIN,
FACE_DATASET_FETCH_INTERVAL_MAX);
@@ -421,38 +469,42 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
return false;
}
// first-hello-interval
ConfigurationVariable<uint32_t> firstHelloInterval("first-hello-interval",
std::bind(&ConfParameter::setFirstHelloInterval,
&m_nlsr.getConfParameter(), _1));
firstHelloInterval.setMinAndMaxValue(FIRST_HELLO_INTERVAL_MIN, FIRST_HELLO_INTERVAL_MAX);
firstHelloInterval.setOptional(FIRST_HELLO_INTERVAL_DEFAULT);
if (!firstHelloInterval.parseFromConfigSection(section)) {
return false;
}
for (ConfigSection::const_iterator tn =
section.begin(); tn != section.end(); ++tn) {
if (tn->first == "neighbor") {
for (const auto& tn : section) {
if (tn.first == "neighbor") {
try {
ConfigSection CommandAttriTree = tn->second;
ConfigSection CommandAttriTree = tn.second;
std::string name = CommandAttriTree.get<std::string>("name");
std::string uriString = CommandAttriTree.get<std::string>("face-uri");
ndn::FaceUri faceUri;
if (! faceUri.parse(uriString)) {
std::cerr << "parsing failed!" << std::endl;
if (!faceUri.parse(uriString)) {
std::cerr << "face-uri parsing failed" << std::endl;
return false;
}
double linkCost = CommandAttriTree.get<double>("link-cost",
Adjacent::DEFAULT_LINK_COST);
bool failedToCanonize = false;
faceUri.canonize([&faceUri] (const auto& canonicalUri) {
faceUri = canonicalUri;
},
[&faceUri, &failedToCanonize] (const auto& reason) {
failedToCanonize = true;
std::cerr << "Could not canonize URI: '" << faceUri
<< "' because: " << reason << std::endl;
},
m_io,
TIME_ALLOWED_FOR_CANONIZATION);
m_io.run();
m_io.restart();
if (failedToCanonize) {
return false;
}
double linkCost = CommandAttriTree.get<double>("link-cost", Adjacent::DEFAULT_LINK_COST);
ndn::Name neighborName(name);
if (!neighborName.empty()) {
Adjacent adj(name, faceUri, linkCost, Adjacent::STATUS_INACTIVE, 0, 0);
m_nlsr.getAdjacencyList().insert(adj);
m_confParam.getAdjacencyList().insert(adj);
}
else {
std::cerr << " Wrong command format ! [name /nbr/name/ \n face-uri /uri\n]";
@@ -475,18 +527,17 @@ ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
std::string state = section.get<std::string>("state", "off");
if (boost::iequals(state, "off")) {
m_nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_OFF);
m_confParam.setHyperbolicState(HYPERBOLIC_STATE_OFF);
}
else if (boost::iequals(state, "on")) {
m_nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_ON);
m_confParam.setHyperbolicState(HYPERBOLIC_STATE_ON);
}
else if (state == "dry-run") {
m_nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
else if (boost::iequals(state, "dry-run")) {
m_confParam.setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
}
else {
std::cerr << "Wrong format for hyperbolic state." << std::endl;
std::cerr << "Allowed value: off, on, dry-run" << std::endl;
std::cerr << "Invalid setting for hyperbolic state. "
<< "Allowed values: off, on, dry-run" << std::endl;
return false;
}
@@ -510,10 +561,10 @@ ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
}
}
if (!m_nlsr.getConfParameter().setCorR(radius)) {
if (!m_confParam.setCorR(radius)) {
return false;
}
m_nlsr.getConfParameter().setCorTheta(angles);
m_confParam.setCorTheta(angles);
}
catch (const std::exception& ex) {
std::cerr << ex.what() << std::endl;
@@ -532,21 +583,20 @@ ConfFileProcessor::processConfSectionFib(const ConfigSection& section)
int maxFacesPerPrefix = section.get<int>("max-faces-per-prefix", MAX_FACES_PER_PREFIX_DEFAULT);
if (maxFacesPerPrefix >= MAX_FACES_PER_PREFIX_MIN &&
maxFacesPerPrefix <= MAX_FACES_PER_PREFIX_MAX)
{
m_nlsr.getConfParameter().setMaxFacesPerPrefix(maxFacesPerPrefix);
maxFacesPerPrefix <= MAX_FACES_PER_PREFIX_MAX) {
m_confParam.setMaxFacesPerPrefix(maxFacesPerPrefix);
}
else {
std::cerr << "Wrong value for max-faces-per-prefix. ";
std::cerr << MAX_FACES_PER_PREFIX_MIN << std::endl;
std::cerr << "Invalid value for max-faces-per-prefix. "
<< "Allowed range: " << MAX_FACES_PER_PREFIX_MIN
<< "-" << MAX_FACES_PER_PREFIX_MAX << std::endl;
return false;
}
// routing-calc-interval
ConfigurationVariable<uint32_t> routingCalcInterval("routing-calc-interval",
std::bind(&ConfParameter::setRoutingCalcInterval,
&m_nlsr.getConfParameter(), _1));
&m_confParam, _1));
routingCalcInterval.setMinAndMaxValue(ROUTING_CALC_INTERVAL_MIN, ROUTING_CALC_INTERVAL_MAX);
routingCalcInterval.setOptional(ROUTING_CALC_INTERVAL_DEFAULT);
@@ -560,14 +610,12 @@ ConfFileProcessor::processConfSectionFib(const ConfigSection& section)
bool
ConfFileProcessor::processConfSectionAdvertising(const ConfigSection& section)
{
for (ConfigSection::const_iterator tn =
section.begin(); tn != section.end(); ++tn) {
if (tn->first == "prefix") {
for (const auto& tn : section) {
if (tn.first == "prefix") {
try {
std::string prefix = tn->second.data();
ndn::Name namePrefix(prefix);
ndn::Name namePrefix(tn.second.data());
if (!namePrefix.empty()) {
m_nlsr.getNamePrefixList().insert(namePrefix);
m_confParam.getNamePrefixList().insert(namePrefix);
}
else {
std::cerr << " Wrong command format ! [prefix /name/prefix] or bad URI" << std::endl;
@@ -586,39 +634,41 @@ ConfFileProcessor::processConfSectionAdvertising(const ConfigSection& section)
bool
ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
{
ConfigSection::const_iterator it = section.begin();
auto it = section.begin();
if (it == section.end() || it->first != "validator") {
std::cerr << "Error: Expect validator section!" << std::endl;
std::cerr << "Error: Expected validator section!" << std::endl;
return false;
}
m_nlsr.loadValidator(it->second, m_confFileName);
m_confParam.getValidator().load(it->second, m_confFileName);
it++;
if (it != section.end() && it->first == "prefix-update-validator") {
m_nlsr.getPrefixUpdateProcessor().loadValidator(it->second, m_confFileName);
m_confParam.getPrefixUpdateValidator().load(it->second, m_confFileName);
it++;
for (; it != section.end(); it++) {
using namespace boost::filesystem;
if (it->first != "cert-to-publish") {
std::cerr << "Error: Expect cert-to-publish!" << std::endl;
std::cerr << "Error: Expected cert-to-publish!" << std::endl;
return false;
}
std::string file = it->second.data();
path certfilePath = absolute(file, path(m_confFileName).parent_path());
std::shared_ptr<ndn::security::v2::Certificate> idCert =
ndn::io::load<ndn::security::v2::Certificate>(certfilePath.string());
bf::path certfilePath = absolute(file, bf::path(m_confFileName).parent_path());
std::ifstream ifs(certfilePath.string());
if (idCert == nullptr) {
std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
ndn::security::Certificate idCert;
try {
idCert = ndn::io::loadTlv<ndn::security::Certificate>(ifs);
}
catch (const std::exception& e) {
std::cerr << "Error: Cannot load cert-to-publish '" << file << "': " << e.what() << std::endl;
return false;
}
m_nlsr.loadCertToPublish(*idCert);
m_confParam.addCertPath(certfilePath.string());
m_confParam.loadCertToValidator(idCert);
}
}
+16 -22
View File
@@ -1,7 +1,8 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
@@ -16,41 +17,33 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NLSR_CONF_FILE_PROCESSOR_HPP
#define NLSR_CONF_FILE_PROCESSOR_HPP
#include "common.hpp"
#include "nlsr.hpp"
#include "conf-parameter.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <boost/filesystem.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/property_tree/ptree.hpp>
namespace nlsr {
using ConfigSection = boost::property_tree::ptree;
/*! \brief A class containing methods to parse an NLSR configuration file
*
* This class contains methods to parse an NLSR configuration file and
* set all the parameters in NLSR to the received values. There are
* defaults for any unconfigured settings.
*
* This is currently called by the wrapper class NlsrRunner to
* populate the NLSR object with its configuration before NLSR is
* started.
*
* \sa nlsr::ConfParameter
* \sa NlsrRunner::run
*/
class ConfFileProcessor
{
public:
ConfFileProcessor(Nlsr& nlsr, const std::string& cfile)
: m_confFileName(cfile)
, m_nlsr(nlsr)
{
}
ConfFileProcessor(ConfParameter& confParam);
/*! \brief Load and parse the configuration file, then populate NLSR.
*
@@ -63,8 +56,6 @@ public:
processConfFile();
private:
typedef boost::property_tree::ptree ConfigSection;
/*! \brief Parse the configuration file into a tree and process the nodes.
*
* Reads the configuration file as a property tree, and then iterates
@@ -125,9 +116,12 @@ private:
private:
/*! m_confFileName The full path of the configuration file to parse. */
std::string m_confFileName;
/*! m_nlsr The NLSR object to configure upon successful parsing. */
Nlsr& m_nlsr;
/*! m_confParam The ConfFileProcessor object to configure as parsing is done. */
ConfParameter& m_confParam;
/*! m_io For canonization of FaceUri. */
boost::asio::io_context m_io;
};
} // namespace nlsr
#endif // NLSR_CONF_FILE_PROCESSOR_HPP
+110 -23
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
@@ -16,20 +16,48 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
* \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
*
**/
*/
#include "conf-parameter.hpp"
#include "logger.hpp"
#include <ndn-cxx/security/signing-helpers.hpp>
namespace nlsr {
INIT_LOGGER(ConfParameter);
// To be changed when breaking changes are made to sync
const uint64_t ConfParameter::SYNC_VERSION = 4;
static std::unique_ptr<ndn::security::CertificateFetcherDirectFetch>
makeCertificateFetcher(ndn::Face& face)
{
auto fetcher = std::make_unique<ndn::security::CertificateFetcherDirectFetch>(face);
fetcher->setSendDirectInterestOnly(true);
return fetcher;
}
ConfParameter::ConfParameter(ndn::Face& face, ndn::KeyChain& keyChain,
const std::string& confFileName)
: m_confFileName(confFileName)
, m_lsaRefreshTime(LSA_REFRESH_TIME_DEFAULT)
, m_adjLsaBuildInterval(ADJ_LSA_BUILD_INTERVAL_DEFAULT)
, m_routingCalcInterval(ROUTING_CALC_INTERVAL_DEFAULT)
, m_faceDatasetFetchInterval(ndn::time::seconds(static_cast<int>(FACE_DATASET_FETCH_INTERVAL_DEFAULT)))
, m_lsaInterestLifetime(ndn::time::seconds(static_cast<int>(LSA_INTEREST_LIFETIME_DEFAULT)))
, m_routerDeadInterval(2 * LSA_REFRESH_TIME_DEFAULT)
, m_interestRetryNumber(HELLO_RETRIES_DEFAULT)
, m_interestResendTime(HELLO_TIMEOUT_DEFAULT)
, m_infoInterestInterval(HELLO_INTERVAL_DEFAULT)
, m_hyperbolicState(HYPERBOLIC_STATE_OFF)
, m_corR(0)
, m_maxFacesPerPrefix(MAX_FACES_PER_PREFIX_MIN)
, m_syncInterestLifetime(ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT))
, m_adjl()
, m_npl()
, m_validator(makeCertificateFetcher(face))
, m_prefixUpdateValidator(std::make_unique<ndn::security::CertificateFetcherDirectFetch>(face))
, m_keyChain(keyChain)
{
}
void
ConfParameter::writeLog()
@@ -38,8 +66,8 @@ ConfParameter::writeLog()
NLSR_LOG_INFO("Site Name: " << m_siteName);
NLSR_LOG_INFO("Network: " << m_network);
NLSR_LOG_INFO("Router Prefix: " << m_routerPrefix);
NLSR_LOG_INFO("ChronoSync sync Prefix: " << m_chronosyncPrefix);
NLSR_LOG_INFO("ChronoSync LSA prefix: " << m_lsaPrefix);
NLSR_LOG_INFO("Sync Prefix: " << m_syncPrefix);
NLSR_LOG_INFO("Sync LSA prefix: " << m_lsaPrefix);
NLSR_LOG_INFO("Hello Interest retry number: " << m_interestRetryNumber);
NLSR_LOG_INFO("Hello Interest resend second: " << m_interestResendTime);
NLSR_LOG_INFO("Info Interest interval: " << m_infoInterestInterval);
@@ -48,17 +76,18 @@ ConfParameter::writeLog()
NLSR_LOG_INFO("LSA Interest lifetime: " << getLsaInterestLifetime());
NLSR_LOG_INFO("Router dead interval: " << getRouterDeadInterval());
NLSR_LOG_INFO("Max Faces Per Prefix: " << m_maxFacesPerPrefix);
NLSR_LOG_INFO("Hyperbolic Routing: " << m_hyperbolicState);
NLSR_LOG_INFO("Hyp R: " << m_corR);
int i=0;
for (auto const& value: m_corTheta) {
NLSR_LOG_INFO("Hyp Angle " << i++ << ": "<< value);
if (m_hyperbolicState == HYPERBOLIC_STATE_ON || m_hyperbolicState == HYPERBOLIC_STATE_DRY_RUN) {
NLSR_LOG_INFO("Hyperbolic Routing: " << m_hyperbolicState);
NLSR_LOG_INFO("Hyp R: " << m_corR);
int i=0;
for (auto const& value: m_corTheta) {
NLSR_LOG_INFO("Hyp Angle " << i++ << ": "<< value);
}
}
NLSR_LOG_INFO("Seq Directory: " << m_seqFileDir);
NLSR_LOG_INFO("State Directory: " << m_stateFileDir);
// Event Intervals
NLSR_LOG_INFO("Adjacency LSA build interval: " << m_adjLsaBuildInterval);
NLSR_LOG_INFO("First Hello Interest interval: " << m_firstHelloInterval);
NLSR_LOG_INFO("Routing calculation interval: " << m_routingCalcInterval);
}
@@ -67,16 +96,74 @@ ConfParameter::setNetwork(const ndn::Name& networkName)
{
m_network = networkName;
m_chronosyncPrefix.append("localhop");
m_chronosyncPrefix.append(m_network);
m_chronosyncPrefix.append("NLSR");
m_chronosyncPrefix.append("sync");
m_chronosyncPrefix.appendVersion(SYNC_VERSION);
if (m_syncProtocol != SyncProtocol::SVS) {
m_syncPrefix.append("localhop");
}
m_syncPrefix.append(m_network);
m_syncPrefix.append("nlsr");
m_syncPrefix.append("sync");
m_syncPrefix.appendVersion(SYNC_VERSION);
m_lsaPrefix.append("localhop");
m_lsaPrefix.append(m_network);
m_lsaPrefix.append("NLSR");
m_lsaPrefix.append("nlsr");
m_lsaPrefix.append("LSA");
}
void
ConfParameter::loadCertToValidator(const ndn::security::Certificate& cert)
{
NLSR_LOG_TRACE("Loading Certificate Name: " << cert.getName());
m_validator.loadAnchor("Authoritative-Certificate", ndn::security::Certificate(cert));
m_prefixUpdateValidator.loadAnchor("Authoritative-Certificate", ndn::security::Certificate(cert));
}
std::optional<ndn::security::Certificate>
ConfParameter::initializeKey()
{
using namespace ndn::security;
NLSR_LOG_DEBUG("Initializing Key ...");
Identity routerIdentity;
try {
routerIdentity = m_keyChain.getPib().getIdentity(m_routerPrefix);
}
catch (const Pib::Error&) {
NLSR_LOG_ERROR("Router identity " << m_routerPrefix << " not found. "
"NLSR is running without security. "
"If security is enabled in the configuration, NLSR will not converge.");
return std::nullopt;
}
catch (const std::invalid_argument& e) {
// This is (probably) needed for the dummy keychain patch.
// https://github.com/named-data/mini-ndn/blob/master/util/patches/ndn-cxx-dummy-keychain.patch
NLSR_LOG_DEBUG(e.what());
}
auto instanceName = ndn::Name(m_routerPrefix).append("nlsr");
try {
m_keyChain.deleteIdentity(m_keyChain.getPib().getIdentity(instanceName));
}
catch (const Pib::Error&) {
// old instance identity does not exist
}
catch (const std::invalid_argument& e) {
// This is needed for the dummy-keychain patch (ref above) to handle the error that it generates.
const std::string exceptionText = e.what();
if (exceptionText.find("does not match identity") == std::string::npos) {
NLSR_LOG_ERROR(exceptionText);
throw;
}
return std::nullopt;
}
auto key = m_keyChain.createIdentity(instanceName).getDefaultKey();
auto cert = m_keyChain.makeCertificate(key, signingByIdentity(routerIdentity));
m_keyChain.setDefaultCertificate(key, cert);
m_signingInfo = signingByCertificate(cert);
loadCertToValidator(cert);
return cert;
}
} // namespace nlsr
+141 -59
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,22 +17,30 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NLSR_CONF_PARAMETER_HPP
#define NLSR_CONF_PARAMETER_HPP
#include "common.hpp"
#include "logger.hpp"
#include "test-access-control.hpp"
#include "adjacency-list.hpp"
#include "name-prefix-list.hpp"
#include <iostream>
#include <boost/cstdint.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/util/time.hpp>
#include <ndn-cxx/security/validator-config.hpp>
#include <ndn-cxx/security/certificate-fetcher-direct-fetch.hpp>
#include <optional>
namespace nlsr {
enum class SyncProtocol {
CHRONOSYNC,
PSYNC,
SVS,
};
enum {
LSA_REFRESH_TIME_MIN = 240,
LSA_REFRESH_TIME_DEFAULT = 1800,
@@ -46,15 +54,9 @@ enum {
};
enum {
ADJ_LSA_BUILD_INTERVAL_MIN = 0,
ADJ_LSA_BUILD_INTERVAL_DEFAULT = 5,
ADJ_LSA_BUILD_INTERVAL_MAX = 5
};
enum {
FIRST_HELLO_INTERVAL_MIN = 0,
FIRST_HELLO_INTERVAL_DEFAULT = 10,
FIRST_HELLO_INTERVAL_MAX = 10
ADJ_LSA_BUILD_INTERVAL_MIN = 5,
ADJ_LSA_BUILD_INTERVAL_DEFAULT = 10,
ADJ_LSA_BUILD_INTERVAL_MAX = 30
};
enum {
@@ -84,7 +86,7 @@ enum {
enum {
HELLO_TIMEOUT_MIN = 1,
HELLO_TIMEOUT_DEFAULT = 3,
HELLO_TIMEOUT_DEFAULT = 1,
HELLO_TIMEOUT_MAX = 15
};
@@ -126,25 +128,14 @@ enum {
*/
class ConfParameter
{
public:
ConfParameter()
: m_lsaRefreshTime(LSA_REFRESH_TIME_DEFAULT)
, m_adjLsaBuildInterval(ADJ_LSA_BUILD_INTERVAL_DEFAULT)
, m_firstHelloInterval(FIRST_HELLO_INTERVAL_DEFAULT)
, m_routingCalcInterval(ROUTING_CALC_INTERVAL_DEFAULT)
, m_faceDatasetFetchInterval(ndn::time::seconds(static_cast<int>(FACE_DATASET_FETCH_INTERVAL_DEFAULT)))
, m_lsaInterestLifetime(ndn::time::seconds(static_cast<int>(LSA_INTEREST_LIFETIME_DEFAULT)))
, m_routerDeadInterval(2 * LSA_REFRESH_TIME_DEFAULT)
, m_logLevel("INFO")
, m_interestRetryNumber(HELLO_RETRIES_DEFAULT)
, m_interestResendTime(HELLO_TIMEOUT_DEFAULT)
, m_infoInterestInterval(HELLO_INTERVAL_DEFAULT)
, m_hyperbolicState(HYPERBOLIC_STATE_OFF)
, m_corR(0)
, m_maxFacesPerPrefix(MAX_FACES_PER_PREFIX_MIN)
, m_syncInterestLifetime(ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT))
ConfParameter(ndn::Face& face, ndn::KeyChain& keyChain,
const std::string& confFileName = "nlsr.conf");
const std::string&
getConfFileName()
{
return m_confFileName;
}
void
@@ -181,11 +172,15 @@ public:
}
void
buildRouterPrefix()
buildRouterAndSyncUserPrefix()
{
m_routerPrefix = m_network;
m_routerPrefix.append(m_siteName);
m_routerPrefix.append(m_routerName);
m_syncUserPrefix = m_lsaPrefix;
m_syncUserPrefix.append(m_siteName);
m_syncUserPrefix.append(m_routerName);
}
const ndn::Name&
@@ -194,11 +189,16 @@ public:
return m_routerPrefix;
}
const ndn::Name&
getSyncUserPrefix() const
{
return m_syncUserPrefix;
}
const ndn::Name&
getChronosyncPrefix() const
getSyncPrefix() const
{
return m_chronosyncPrefix;
return m_syncPrefix;
}
const ndn::Name&
@@ -213,6 +213,18 @@ public:
m_lsaRefreshTime = lrt;
}
SyncProtocol
getSyncProtocol() const
{
return m_syncProtocol;
}
void
setSyncProtocol(SyncProtocol syncProtocol)
{
m_syncProtocol = syncProtocol;
}
uint32_t
getLsaRefreshTime() const
{
@@ -243,18 +255,6 @@ public:
return m_adjLsaBuildInterval;
}
void
setFirstHelloInterval(uint32_t interval)
{
m_firstHelloInterval = interval;
}
uint32_t
getFirstHelloInterval() const
{
return m_firstHelloInterval;
}
void
setRoutingCalcInterval(uint32_t interval)
{
@@ -392,15 +392,27 @@ public:
}
void
setSeqFileDir(const std::string& ssfd)
setStateFileDir(const std::string& ssfd)
{
m_seqFileDir = ssfd;
m_stateFileDir = ssfd;
}
const std::string&
getSeqFileDir() const
getStateFileDir() const
{
return m_seqFileDir;
return m_stateFileDir;
}
void
setConfFileNameDynamic(const std::string& confFileDynamic)
{
m_confFileNameDynamic = confFileDynamic;
}
const std::string&
getConfFileNameDynamic() const
{
return m_confFileNameDynamic;
}
void
@@ -415,24 +427,83 @@ public:
return m_syncInterestLifetime;
}
AdjacencyList&
getAdjacencyList()
{
return m_adjl;
}
NamePrefixList&
getNamePrefixList()
{
return m_npl;
}
ndn::security::ValidatorConfig&
getValidator()
{
return m_validator;
}
ndn::security::ValidatorConfig&
getPrefixUpdateValidator()
{
return m_prefixUpdateValidator;
}
const ndn::security::SigningInfo&
getSigningInfo() const
{
return m_signingInfo;
}
void
addCertPath(const std::string& certPath)
{
m_certs.insert(certPath);
}
const std::unordered_set<std::string>&
getIdCerts() const
{
return m_certs;
}
const ndn::KeyChain&
getKeyChain() const
{
return m_keyChain;
}
std::optional<ndn::security::Certificate>
initializeKey();
void
loadCertToValidator(const ndn::security::Certificate& cert);
/*! \brief Dump the current state of all attributes to the log.
*/
void
writeLog();
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
std::string m_confFileName;
std::string m_confFileNameDynamic;
private:
ndn::Name m_routerName;
ndn::Name m_siteName;
ndn::Name m_network;
ndn::Name m_routerPrefix;
ndn::Name m_lsaRouterPrefix;
ndn::Name m_syncUserPrefix;
ndn::Name m_chronosyncPrefix;
ndn::Name m_syncPrefix;
ndn::Name m_lsaPrefix;
uint32_t m_lsaRefreshTime;
uint32_t m_adjLsaBuildInterval;
uint32_t m_firstHelloInterval;
uint32_t m_routingCalcInterval;
uint32_t m_faceDatasetFetchTries;
@@ -440,7 +511,6 @@ private:
ndn::time::seconds m_lsaInterestLifetime;
uint32_t m_routerDeadInterval;
std::string m_logLevel;
uint32_t m_interestRetryNumber;
uint32_t m_interestResendTime;
@@ -453,11 +523,23 @@ private:
uint32_t m_maxFacesPerPrefix;
std::string m_seqFileDir;
std::string m_stateFileDir;
ndn::time::milliseconds m_syncInterestLifetime;
SyncProtocol m_syncProtocol = SyncProtocol::PSYNC;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
static const uint64_t SYNC_VERSION;
// must be incremented when breaking changes are made to sync
static constexpr uint64_t SYNC_VERSION = 11;
AdjacencyList m_adjl;
NamePrefixList m_npl;
ndn::security::ValidatorConfig m_validator;
ndn::security::ValidatorConfig m_prefixUpdateValidator;
ndn::security::SigningInfo m_signingInfo;
std::unordered_set<std::string> m_certs;
ndn::KeyChain& m_keyChain;
};
} // namespace nlsr
+114 -94
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
@@ -16,76 +16,95 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "hello-protocol.hpp"
*/
#include "hello-protocol.hpp"
#include "nlsr.hpp"
#include "lsdb.hpp"
#include "utility/name-helper.hpp"
#include "logger.hpp"
#include "utility/name-helper.hpp"
#include <ndn-cxx/encoding/nfd-constants.hpp>
namespace nlsr {
INIT_LOGGER(HelloProtocol);
const std::string HelloProtocol::INFO_COMPONENT = "INFO";
const std::string HelloProtocol::NLSR_COMPONENT = "NLSR";
HelloProtocol::HelloProtocol(Nlsr& nlsr, ndn::Scheduler& scheduler)
: m_nlsr(nlsr)
, m_scheduler(scheduler)
HelloProtocol::HelloProtocol(ndn::Face& face, ndn::KeyChain& keyChain,
ConfParameter& confParam, RoutingTable& routingTable,
Lsdb& lsdb)
: m_face(face)
, m_scheduler(m_face.getIoContext())
, m_keyChain(keyChain)
, m_signingInfo(confParam.getSigningInfo())
, m_confParam(confParam)
, m_routingTable(routingTable)
, m_lsdb(lsdb)
, m_adjacencyList(m_confParam.getAdjacencyList())
{
ndn::Name name(m_confParam.getRouterPrefix());
name.append(NLSR_COMPONENT);
name.append(INFO_COMPONENT);
NLSR_LOG_DEBUG("Setting interest filter for Hello interest: " << name);
m_face.setInterestFilter(ndn::InterestFilter(name).allowLoopback(false),
[this] (const auto& name, const auto& interest) {
processInterest(name, interest);
},
[] (const auto& name) {
NLSR_LOG_DEBUG("Successfully registered prefix: " << name);
},
[] (const auto& name, const auto& resp) {
NLSR_LOG_ERROR("Failed to register prefix " << name);
NDN_THROW(std::runtime_error("Failed to register hello prefix: " + resp));
},
m_signingInfo, ndn::nfd::ROUTE_FLAG_CAPTURE);
}
void
HelloProtocol::expressInterest(const ndn::Name& interestName, uint32_t seconds)
{
NLSR_LOG_DEBUG("Expressing Interest :" << interestName);
ndn::Interest i(interestName);
i.setInterestLifetime(ndn::time::seconds(seconds));
i.setMustBeFresh(true);
m_nlsr.getNlsrFace().expressInterest(i,
std::bind(&HelloProtocol::onContent,
this,
_1, _2),
std::bind(&HelloProtocol::processInterestTimedOut, // Nack
this, _1),
std::bind(&HelloProtocol::processInterestTimedOut,
this, _1));
NLSR_LOG_DEBUG("Expressing Interest: " << interestName);
ndn::Interest interest(interestName);
interest.setInterestLifetime(ndn::time::seconds(seconds));
interest.setMustBeFresh(true);
interest.setCanBePrefix(true);
m_face.expressInterest(interest,
std::bind(&HelloProtocol::onContent, this, _1, _2),
[this, seconds] (const auto& interest, const auto& nack) {
NDN_LOG_TRACE("Received Nack with reason: " << nack.getReason());
NDN_LOG_TRACE("Will treat as timeout in " << 2 * seconds << " seconds");
m_scheduler.schedule(ndn::time::seconds(2 * seconds),
[this, interest] { processInterestTimedOut(interest); });
},
std::bind(&HelloProtocol::processInterestTimedOut, this, _1));
// increment SENT_HELLO_INTEREST
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_INTEREST);
}
void
HelloProtocol::sendScheduledInterest(uint32_t seconds)
HelloProtocol::sendHelloInterest(const ndn::Name& neighbor)
{
std::list<Adjacent> adjList = m_nlsr.getAdjacencyList().getAdjList();
for (std::list<Adjacent>::iterator it = adjList.begin(); it != adjList.end();
++it) {
// If this adjacency has a Face, just proceed as usual.
if((*it).getFaceId() != 0) {
// interest name: /<neighbor>/NLSR/INFO/<router>
ndn::Name interestName = (*it).getName() ;
interestName.append(NLSR_COMPONENT);
interestName.append(INFO_COMPONENT);
interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
expressInterest(interestName,
m_nlsr.getConfParameter().getInterestResendTime());
NLSR_LOG_DEBUG("Sending scheduled interest: " << interestName);
}
auto adjacent = m_adjacencyList.findAdjacent(neighbor);
if (adjacent == m_adjacencyList.end()) {
return;
}
scheduleInterest(m_nlsr.getConfParameter().getInfoInterestInterval());
}
void
HelloProtocol::scheduleInterest(uint32_t seconds)
{
NLSR_LOG_DEBUG("Scheduling HELLO Interests in " << ndn::time::seconds(seconds));
// If this adjacency has a Face, just proceed as usual.
if(adjacent->getFaceId() != 0) {
// interest name: /<neighbor>/NLSR/INFO/<router>
ndn::Name interestName = adjacent->getName() ;
interestName.append(NLSR_COMPONENT);
interestName.append(INFO_COMPONENT);
interestName.append(ndn::tlv::GenericNameComponent, m_confParam.getRouterPrefix().wireEncode());
expressInterest(interestName, m_confParam.getInterestResendTime());
NLSR_LOG_DEBUG("Sending HELLO interest: " << interestName);
}
m_scheduler.scheduleEvent(ndn::time::seconds(seconds),
std::bind(&HelloProtocol::sendScheduledInterest, this, seconds));
m_scheduler.schedule(ndn::time::seconds(m_confParam.getInfoInterestInterval()),
[this, neighbor] { sendHelloInterest(neighbor); });
}
void
@@ -98,32 +117,32 @@ HelloProtocol::processInterest(const ndn::Name& name,
// increment RCV_HELLO_INTEREST
hpIncrementSignal(Statistics::PacketType::RCV_HELLO_INTEREST);
NLSR_LOG_DEBUG("Interest Received for Name: " << interestName);
NLSR_LOG_DEBUG("Interest received for Name: " << interestName);
if (interestName.get(-2).toUri() != INFO_COMPONENT) {
NLSR_LOG_DEBUG("INFO_COMPONENT not found or interestName: " << interestName
<< " does not match expression");
NLSR_LOG_DEBUG("INFO_COMPONENT not found or Interest Name " << interestName
<< " does not match expression");
return;
}
ndn::Name neighbor;
neighbor.wireDecode(interestName.get(-1).blockFromValue());
NLSR_LOG_DEBUG("Neighbor: " << neighbor);
if (m_nlsr.getAdjacencyList().isNeighbor(neighbor)) {
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>();
if (m_adjacencyList.isNeighbor(neighbor)) {
auto data = std::make_shared<ndn::Data>();
data->setName(ndn::Name(interest.getName()).appendVersion());
data->setFreshnessPeriod(ndn::time::seconds(10)); // 10 sec
data->setContent(reinterpret_cast<const uint8_t*>(INFO_COMPONENT.c_str()),
INFO_COMPONENT.size());
data->setFreshnessPeriod(10_s);
data->setContent(ndn::make_span(reinterpret_cast<const uint8_t*>(INFO_COMPONENT.data()),
INFO_COMPONENT.size()));
m_nlsr.getKeyChain().sign(*data, m_nlsr.getSigningInfo());
m_keyChain.sign(*data, m_signingInfo);
NLSR_LOG_DEBUG("Sending out data for name: " << interest.getName());
m_nlsr.getNlsrFace().put(*data);
m_face.put(*data);
// increment SENT_HELLO_DATA
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_DATA);
auto adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
auto adjacent = m_adjacencyList.findAdjacent(neighbor);
// If this neighbor was previously inactive, send our own hello interest, too
if (adjacent->getStatus() == Adjacent::STATUS_INACTIVE) {
// We can only do that if the neighbor currently has a face.
@@ -132,9 +151,8 @@ HelloProtocol::processInterest(const ndn::Name& name,
ndn::Name interestName(neighbor);
interestName.append(NLSR_COMPONENT);
interestName.append(INFO_COMPONENT);
interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
expressInterest(interestName,
m_nlsr.getConfParameter().getInterestResendTime());
interestName.append(ndn::tlv::GenericNameComponent, m_confParam.getRouterPrefix().wireEncode());
expressInterest(interestName, m_confParam.getInterestResendTime());
}
}
}
@@ -151,50 +169,51 @@ HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
}
ndn::Name neighbor = interestName.getPrefix(-3);
NLSR_LOG_DEBUG("Neighbor: " << neighbor);
m_nlsr.getAdjacencyList().incrementTimedOutInterestCount(neighbor);
m_adjacencyList.incrementTimedOutInterestCount(neighbor);
Adjacent::Status status = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
Adjacent::Status status = m_adjacencyList.getStatusOfNeighbor(neighbor);
uint32_t infoIntTimedOutCount =
m_nlsr.getAdjacencyList().getTimedOutInterestCount(neighbor);
uint32_t infoIntTimedOutCount = m_adjacencyList.getTimedOutInterestCount(neighbor);
NLSR_LOG_DEBUG("Status: " << status);
NLSR_LOG_DEBUG("Info Interest Timed out: " << infoIntTimedOutCount);
if (infoIntTimedOutCount < m_nlsr.getConfParameter().getInterestRetryNumber()) {
if (infoIntTimedOutCount < m_confParam.getInterestRetryNumber()) {
// interest name: /<neighbor>/NLSR/INFO/<router>
ndn::Name interestName(neighbor);
interestName.append(NLSR_COMPONENT);
interestName.append(INFO_COMPONENT);
interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
interestName.append(ndn::tlv::GenericNameComponent, m_confParam.getRouterPrefix().wireEncode());
NLSR_LOG_DEBUG("Resending interest: " << interestName);
expressInterest(interestName,
m_nlsr.getConfParameter().getInterestResendTime());
expressInterest(interestName, m_confParam.getInterestResendTime());
}
else if ((status == Adjacent::STATUS_ACTIVE) &&
(infoIntTimedOutCount == m_nlsr.getConfParameter().getInterestRetryNumber())) {
m_nlsr.getAdjacencyList().setStatusOfNeighbor(neighbor, Adjacent::STATUS_INACTIVE);
else if (status == Adjacent::STATUS_ACTIVE) {
m_adjacencyList.setStatusOfNeighbor(neighbor, Adjacent::STATUS_INACTIVE);
NLSR_LOG_DEBUG("Neighbor: " << neighbor << " status changed to INACTIVE");
m_nlsr.getLsdb().scheduleAdjLsaBuild();
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
m_routingTable.scheduleRoutingTableCalculation();
}
else {
m_lsdb.scheduleAdjLsaBuild();
}
}
}
// This is the first function that incoming Hello data will
// see. This checks if the data appears to be signed, and passes it
// on to validate the content of the data.
// This is the first function that incoming Hello data will
// see. This checks if the data appears to be signed, and passes it
// on to validate the content of the data.
void
HelloProtocol::onContent(const ndn::Interest& interest, const ndn::Data& data)
{
NLSR_LOG_DEBUG("Received data for INFO(name): " << data.getName());
if (data.getSignature().hasKeyLocator()) {
if (data.getSignature().getKeyLocator().getType() == ndn::KeyLocator::KeyLocator_Name) {
NLSR_LOG_DEBUG("Data signed with: " << data.getSignature().getKeyLocator().getName());
}
auto kl = data.getKeyLocator();
if (kl && kl->getType() == ndn::tlv::Name) {
NLSR_LOG_DEBUG("Data signed with: " << kl->getName());
}
m_nlsr.getValidator().validate(data,
std::bind(&HelloProtocol::onContentValidated, this, _1),
std::bind(&HelloProtocol::onContentValidationFailed,
this, _1, _2));
m_confParam.getValidator().validate(data,
std::bind(&HelloProtocol::onContentValidated, this, _1),
std::bind(&HelloProtocol::onContentValidationFailed,
this, _1, _2));
}
void
@@ -207,21 +226,22 @@ HelloProtocol::onContentValidated(const ndn::Data& data)
if (dataName.get(-3).toUri() == INFO_COMPONENT) {
ndn::Name neighbor = dataName.getPrefix(-4);
Adjacent::Status oldStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
m_nlsr.getAdjacencyList().setStatusOfNeighbor(neighbor, Adjacent::STATUS_ACTIVE);
m_nlsr.getAdjacencyList().setTimedOutInterestCount(neighbor, 0);
Adjacent::Status newStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
Adjacent::Status oldStatus = m_adjacencyList.getStatusOfNeighbor(neighbor);
m_adjacencyList.setStatusOfNeighbor(neighbor, Adjacent::STATUS_ACTIVE);
m_adjacencyList.setTimedOutInterestCount(neighbor, 0);
Adjacent::Status newStatus = m_adjacencyList.getStatusOfNeighbor(neighbor);
NLSR_LOG_DEBUG("Neighbor : " << neighbor);
NLSR_LOG_DEBUG("Old Status: " << oldStatus << " New Status: " << newStatus);
NLSR_LOG_DEBUG("Neighbor: " << neighbor);
NLSR_LOG_DEBUG("Old Status: " << oldStatus << ", New Status: " << newStatus);
// change in Adjacency list
if ((oldStatus - newStatus) != 0) {
if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
m_routingTable.scheduleRoutingTableCalculation();
}
else {
m_nlsr.getLsdb().scheduleAdjLsaBuild();
m_lsdb.scheduleAdjLsaBuild();
}
onInitialHelloDataValidated(neighbor);
}
}
// increment RCV_HELLO_DATA
@@ -230,9 +250,9 @@ HelloProtocol::onContentValidated(const ndn::Data& data)
void
HelloProtocol::onContentValidationFailed(const ndn::Data& data,
const ndn::security::v2::ValidationError& ve)
const ndn::security::ValidationError& ve)
{
NLSR_LOG_DEBUG("Validation Error: " << ve);
NLSR_LOG_DEBUG("Validation error: " << ve);
}
} // namespace nlsr
+28 -68
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,41 +17,29 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NLSR_HELLO_PROTOCOL_HPP
#define NLSR_HELLO_PROTOCOL_HPP
#include "conf-parameter.hpp"
#include "lsdb.hpp"
#include "route/routing-table.hpp"
#include "statistics.hpp"
#include "test-access-control.hpp"
#include <ndn-cxx/util/signal.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
#include <ndn-cxx/security/validation-error.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <ndn-cxx/security/v2/validation-error.hpp>
#include <ndn-cxx/util/signal.hpp>
namespace nlsr {
class Nlsr;
class HelloProtocol
{
public:
HelloProtocol(Nlsr& nlsr, ndn::Scheduler& scheduler);
/*! \brief Schedules a Hello Interest event.
*
* This function serves as the Hello Interest loop, and must be
* explicitly called to start the Hello cycle. This is done at
* NLSR's initialization.
*
* \sa Nlsr::initialize
* \param seconds The number of seconds to wait before calling the event.
*/
void
scheduleInterest(uint32_t seconds);
HelloProtocol(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam,
RoutingTable& routingTable, Lsdb& lsdb);
/*! \brief Sends a Hello Interest packet.
*
@@ -68,19 +56,15 @@ public:
expressInterest(const ndn::Name& interestNamePrefix, uint32_t seconds);
/*! \brief Sends Hello Interests to all neighbors
*
* \param seconds (ignored)
*
* This function is called as part of a schedule to regularly
* determine the adjacency status of neighbors. This function
* creates and sends a Hello Interest to each neighbor in
* Nlsr::m_adjacencyList. If the neighbor has not been contacted
* before and curerntly has no Face in NFD, this method will call a
* different pipeline that creates the Face first, then registers
* prefixes.
* creates and sends a Hello Interest to the given adjacent.
*
* \param neighbor the name of the neighbor
*/
void
sendScheduledInterest(uint32_t seconds);
sendHelloInterest(const ndn::Name& neighbor);
/*! \brief Processes a Hello Interest from a neighbor.
*
@@ -99,7 +83,7 @@ public:
void
processInterest(const ndn::Name& name, const ndn::Interest& interest);
ndn::util::signal::Signal<HelloProtocol, Statistics::PacketType> hpIncrementSignal;
ndn::signal::Signal<HelloProtocol, Statistics::PacketType> hpIncrementSignal;
private:
/*! \brief Try to contact a neighbor via Hello protocol again
@@ -136,47 +120,23 @@ private:
*/
void
onContentValidationFailed(const ndn::Data& data,
const ndn::security::v2::ValidationError& ve);
const ndn::security::ValidationError& ve);
/*! \brief Treat a failed Face registration as an INACTIVE neighbor.
*
* If NLSR fails to register a Face when contacting a neighbor, it
* will instantly toggle that neighbor to INACTIVE. This is
* necessary because NLSR will put off building its own adjacency
* LSA until the status of each neighbor is definitively
* known. Without this, NLSR might have to wait many scheduled Hello
* intervals to finish building an adjacency LSA.
*/
void
onRegistrationFailure(const ndn::nfd::ControlResponse& response,
const ndn::Name& name);
public:
static inline const std::string INFO_COMPONENT{"INFO"};
static inline const std::string NLSR_COMPONENT{"nlsr"};
/*! \brief Set up a Face for NLSR use.
*
* When NLSR receives a Hello Interest from a neighbor that it has
* not seen before, it may need to create a Face for that
* neighbor. After doing so, it will be necessary to inform NFD
* about the standard prefixes that NLSR needs a node to have in
* order to conduct normal operations. This function accomplishes
* that, and then sends its own Hello Interest to confirm the
* contact.
*/
void
onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
const ndn::Name& neighbor, const ndn::time::milliseconds& timeout);
ndn::signal::Signal<HelloProtocol, const ndn::Name&> onInitialHelloDataValidated;
/*! \brief Create a Face for an adjacency
* \sa HelloProtocol::onRegistrationSuccess
*/
void
registerPrefixes(const ndn::Name& adjName, const std::string& faceUri,
double linkCost, const ndn::time::milliseconds& timeout);
private:
Nlsr& m_nlsr;
ndn::Scheduler& m_scheduler;
static const std::string INFO_COMPONENT;
static const std::string NLSR_COMPONENT;
ndn::Face& m_face;
ndn::Scheduler m_scheduler;
ndn::security::KeyChain& m_keyChain;
const ndn::security::SigningInfo& m_signingInfo;
ConfParameter& m_confParam;
RoutingTable& m_routingTable;
Lsdb& m_lsdb;
AdjacencyList& m_adjacencyList;
};
} // namespace nlsr
-145
View File
@@ -1,145 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "lsa-segment-storage.hpp"
#include "logger.hpp"
#include "lsa.hpp"
#include "utility/name-helper.hpp"
namespace nlsr {
INIT_LOGGER(LsaSegmentStorage);
LsaSegmentStorage::LsaSegmentStorage(ndn::Scheduler& scheduler,
const ndn::time::seconds lsaDeletionTimepoint)
: m_scheduler(scheduler)
, m_lsaDeletionTimepoint(lsaDeletionTimepoint)
{
}
void
LsaSegmentStorage::connectToFetcher(ndn::util::SegmentFetcher& fetcher)
{
fetcher.afterSegmentValidated.connect(std::bind(&LsaSegmentStorage::afterFetcherSignalEmitted,
this, _1));
}
const ndn::Data*
LsaSegmentStorage::getLsaSegment(const ndn::Interest& interest)
{
ndn::Name lsaSegmentsKey = interest.getName();
// If this is the first interest then it does not contain the segment number,
// so need to append zero segment component at the end to match with the data
if (lsaSegmentsKey.size() > 0) {
if (!lsaSegmentsKey.get(-1).isSegment()) {
lsaSegmentsKey.appendSegment(0);
}
auto it = m_lsaSegments.find(lsaSegmentsKey);
if (it == m_lsaSegments.end()) {
NLSR_LOG_TRACE("Data for interest: " << interest.getName() << " cannot be found in the lsa storage");
return nullptr;
}
else {
NLSR_LOG_TRACE("Data for interest: " << interest.getName() << " is in the storage.");
return &(it->second);
}
}
else {
NLSR_LOG_ERROR("Received interest has empty name.");
return nullptr;
}
}
void
LsaSegmentStorage::afterFetcherSignalEmitted(const ndn::Data& lsaSegment)
{
NLSR_LOG_TRACE("Received a LSA segment: " << lsaSegment.getName());
// lsaSegmentName is /<router-prefix>/<LS type>/<sequence no.>/<version no.>/<segment no.>
auto lsaSegmentName = lsaSegment.getName();
if (lsaSegmentName.size() > 0) {
// lsaSegmentsKey is /<router-prefix>/<LS type>/<sequence no.>/<segment no.>
ndn::Name lsaSegmentsKey(lsaSegmentName.getPrefix(lsaSegmentName.size() - 2));
lsaSegmentsKey.append(lsaSegmentName.get(-1));
// No need to store same LSA multiple time
if (m_lsaSegments.find(lsaSegmentsKey) == m_lsaSegments.end()) {
NLSR_LOG_TRACE("Received LSA segment is new. Storing it in the storage.\n"
<< " LSA data name: " << lsaSegmentName);
// Delete the same LSA with lower sequence number
deleteOldLsas(lsaSegmentName);
m_lsaSegments[lsaSegmentsKey] = lsaSegment;
}
else {
NLSR_LOG_TRACE("The received segment is already in the storage.");
}
// schedule the segment deletion
scheduleLsaSegmentDeletion(lsaSegmentsKey);
}
else {
NLSR_LOG_ERROR("The received LSA segment has empty name.");
}
}
void
LsaSegmentStorage::deleteOldLsas(const ndn::Name& newLsaName)
{
auto newLsaKey = newLsaName.getPrefix(newLsaName.size() - 3);
auto newSeqNo = newLsaName.get(-3).toNumber();
std::vector<decltype(m_lsaSegments)::key_type> lsaToDelete;
for (auto& segment : m_lsaSegments) {
ndn::Name segmentKey = segment.first;
auto oldSeqNo = segmentKey.get(-2).toNumber();
auto existingLsaKey = segmentKey.getPrefix(segmentKey.size() - 2);
if (newLsaKey == existingLsaKey) {
if (newSeqNo > oldSeqNo) { // in the key the second last component is the sequence number
NLSR_LOG_TRACE("Outdated LSA: " << segmentKey << " with seq no: " <<
oldSeqNo << " is deleted.");
lsaToDelete.push_back(segmentKey);
}
}
}
for (auto& segmentKey : lsaToDelete) {
m_lsaSegments.erase(segmentKey);
}
}
void
LsaSegmentStorage::scheduleLsaSegmentDeletion(const ndn::Name& lsaSegmentsKey)
{
m_scheduler.scheduleEvent(m_lsaDeletionTimepoint,
[&, this] {
m_lsaSegments.erase(lsaSegmentsKey);
});
}
} // namespace nlsr
-88
View File
@@ -1,88 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NLSR_LSA_SEGMENT_STORAGE_HPP
#define NLSR_LSA_SEGMENT_STORAGE_HPP
#include "test-access-control.hpp"
#include <ndn-cxx/util/segment-fetcher.hpp>
#include <ndn-cxx/util/signal.hpp>
#include <ndn-cxx/util/time.hpp>
#include <vector>
#include <tuple>
namespace nlsr {
class LsaSegmentStorage
{
public:
LsaSegmentStorage(ndn::Scheduler& scheduler,
const ndn::time::seconds lsaDeletionTimepoint);
/*! \brief Get connected to the signal emitted by SegmentFetcher
* \param fetcher The SegmentFetcher to whose signal LsaSegmentStorage will subscribe to.
*/
void
connectToFetcher(ndn::util::SegmentFetcher& fetcher);
/*! \brief Returns an LSA segment for an interest from LsaSegmentStorage
* \param interest Interest corresponding to the returned LSA segment.
*/
const ndn::Data*
getLsaSegment(const ndn::Interest& interest);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/*! \brief Callback when SegmentFetcher retrieves a segment.
*/
void
afterFetcherSignalEmitted(const ndn::Data& lsaSegment);
private:
/*! \brief Given an LSA name check whether Data for the same name exists in the
* LsaSegmentStorage. If the matched LSA data are of a lower sequence number,
* then remove them from LsaSegmentStorage.
* \param newLsaName Name of the LSA that will be matched against
*/
void
deleteOldLsas(const ndn::Name& newLsaName);
/*! \brief Schedules the deletion of a LSA data given the segmentKey
*/
void
scheduleLsaSegmentDeletion(const ndn::Name& segmentKey);
private:
ndn::Scheduler& m_scheduler;
// Key: /<router-prefix>/<LS type>/<sequence no.>/<segment no.>
// Value: corresponding LSA data packet
// Data name: /<router-prefix>/<LS type>/<sequence no.>/<version no.>/<segment no.>
std::unordered_map<ndn::Name, ndn::Data> m_lsaSegments;
const ndn::time::seconds m_lsaDeletionTimepoint;
};
} // namespace nlsr
#endif // NLSR_LSA_SEGMENT_STORAGE_HPP
-394
View File
@@ -1,394 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "lsa.hpp"
#include "nlsr.hpp"
#include "name-prefix-list.hpp"
#include "adjacent.hpp"
#include "logger.hpp"
#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <limits>
#include <boost/algorithm/string.hpp>
namespace nlsr {
INIT_LOGGER(Lsa);
std::string
Lsa::getData() const
{
std::ostringstream os;
os << m_origRouter << "|" << getType() << "|" << m_lsSeqNo << "|"
<< ndn::time::toIsoString(m_expirationTimePoint) << "|";
return os.str();
}
const ndn::Name
Lsa::getKey() const
{
return ndn::Name(m_origRouter).append(std::to_string(getType()));
}
bool
Lsa::deserializeCommon(boost::tokenizer<boost::char_separator<char>>::iterator& iterator)
{
m_origRouter = ndn::Name(*iterator++);
if (m_origRouter.size() <= 0)
return false;
if (*iterator++ != std::to_string(getType()))
return false;
m_lsSeqNo = boost::lexical_cast<uint32_t>(*iterator++);
m_expirationTimePoint = ndn::time::fromIsoString(*iterator++);
return true;
}
NameLsa::NameLsa(const ndn::Name& origR, uint32_t lsn,
const ndn::time::system_clock::TimePoint& lt,
NamePrefixList& npl)
{
m_origRouter = origR;
m_lsSeqNo = lsn;
m_expirationTimePoint = lt;
for (const auto& name : npl.getNames()) {
addName(name);
}
}
std::string
NameLsa::serialize() const
{
std::ostringstream os;
os << getData() << m_npl.size();
for (const auto& name : m_npl.getNames()) {
os << "|" << name;
}
os << "|";
return os.str();
}
bool
NameLsa::deserialize(const std::string& content) noexcept
{
uint32_t numName = 0;
boost::char_separator<char> sep("|");
boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
tokens.begin();
try {
if (!deserializeCommon(tok_iter))
return false;
numName = boost::lexical_cast<uint32_t>(*tok_iter++);
for (uint32_t i = 0; i < numName; i++) {
ndn::Name name(*tok_iter++);
addName(name);
}
}
catch (const std::exception& e) {
NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
return false;
}
return true;
}
bool
NameLsa::isEqualContent(const NameLsa& other) const
{
return m_npl == other.getNpl();
}
void
NameLsa::writeLog() const
{
NLSR_LOG_DEBUG(*this);
}
CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
const ndn::time::system_clock::TimePoint& lt,
double r, std::vector<double> theta)
{
m_origRouter = origR;
m_lsSeqNo = lsn;
m_expirationTimePoint = lt;
m_corRad = r;
m_angles = theta;
}
bool
CoordinateLsa::isEqualContent(const CoordinateLsa& clsa)
{
if (clsa.getCorTheta().size() != m_angles.size()) {
return false;
}
std::vector<double> m_angles2 = clsa.getCorTheta();
for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
if (std::abs(m_angles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
return false;
}
}
return (std::abs(m_corRad - clsa.getCorRadius()) <
std::numeric_limits<double>::epsilon());
}
std::string
CoordinateLsa::serialize() const
{
std::ostringstream os;
os << getData() << m_corRad << "|" << m_angles.size() << "|";
for (const auto& angle: m_angles) {
os << angle << "|";
}
return os.str();
}
bool
CoordinateLsa::deserialize(const std::string& content) noexcept
{
boost::char_separator<char> sep("|");
boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
tokens.begin();
try {
if (!deserializeCommon(tok_iter))
return false;
m_corRad = boost::lexical_cast<double>(*tok_iter++);
int numAngles = boost::lexical_cast<uint32_t>(*tok_iter++);
for (int i = 0; i < numAngles; i++) {
m_angles.push_back(boost::lexical_cast<double>(*tok_iter++));
}
}
catch (const std::exception& e) {
NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
return false;
}
return true;
}
void
CoordinateLsa::writeLog() const
{
NLSR_LOG_DEBUG(*this);
}
AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
const ndn::time::system_clock::TimePoint& lt,
uint32_t nl , AdjacencyList& adl)
{
m_origRouter = origR;
m_lsSeqNo = lsn;
m_expirationTimePoint = lt;
m_noLink = nl;
std::list<Adjacent> al = adl.getAdjList();
for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
addAdjacent((*it));
}
}
}
bool
AdjLsa::isEqualContent(AdjLsa& alsa)
{
return m_adl == alsa.getAdl();
}
std::string
AdjLsa::serialize() const
{
std::ostringstream os;
os << getData() << m_adl.size();
for (const auto& adjacent : m_adl.getAdjList()) {
os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
<< "|" << adjacent.getLinkCost();
}
os << "|";
return os.str();
}
bool
AdjLsa::deserialize(const std::string& content) noexcept
{
uint32_t numLink = 0;
boost::char_separator<char> sep("|");
boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
tokens.begin();
try {
if (!deserializeCommon(tok_iter))
return false;
numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
for (uint32_t i = 0; i < numLink; i++) {
ndn::Name adjName(*tok_iter++);
std::string connectingFaceUri(*tok_iter++);
double linkCost = boost::lexical_cast<double>(*tok_iter++);
Adjacent adjacent(adjName, ndn::FaceUri(connectingFaceUri), linkCost,
Adjacent::STATUS_INACTIVE, 0, 0);
addAdjacent(adjacent);
}
}
catch (const std::exception& e) {
NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
return false;
}
return true;
}
void
AdjLsa::addNptEntries(Nlsr& pnlsr)
{
// Only add NPT entries if this is an adj LSA from another router.
if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
// Pass the originating router as both the name to register and
// where it came from.
pnlsr.getNamePrefixTable().addEntry(getOrigRouter(), getOrigRouter());
}
}
void
AdjLsa::removeNptEntries(Nlsr& pnlsr)
{
if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
pnlsr.getNamePrefixTable().removeEntry(getOrigRouter(), getOrigRouter());
}
}
void
AdjLsa::writeLog() const
{
NLSR_LOG_DEBUG(*this);
}
std::ostream&
operator<<(std::ostream& os, const AdjLsa& lsa)
{
os << lsa.toString();
os << "-Adjacents:";
int adjacencyIndex = 1;
for (const Adjacent& adjacency : lsa.m_adl) {
os << "--Adjacent" << adjacencyIndex++ << ":\n"
<< "---Adjacent Name: " << adjacency.getName() << "\n"
<< "---Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
<< "---Link Cost: " << adjacency.getLinkCost() << "\n";
}
os << "adj_lsa_end";
return os;
}
std::ostream&
operator<<(std::ostream& os, const CoordinateLsa& lsa)
{
os << lsa.toString();
os << "--Hyperbolic Radius: " << lsa.m_corRad << "\n";
int i = 0;
for (const auto& value : lsa.m_angles) {
os << "---Hyperbolic Theta: " << i++ << ": " << value << "\n";
}
os << "cor_lsa_end";
return os;
}
std::ostream&
operator<<(std::ostream& os, const NameLsa& lsa)
{
os << lsa.toString();
os << "--Names:\n";
int i = 0;
auto names = lsa.m_npl.getNames();
for (const auto& name : names) {
os << "---Name " << i++ << ": " << name << "\n";
}
os << "name_lsa_end";
return os;
}
std::ostream&
operator<<(std::ostream& os, const Lsa::Type& type)
{
os << std::to_string(type);
return os;
}
std::istream&
operator>>(std::istream& is, Lsa::Type& type)
{
std::string typeString;
is >> typeString;
if (typeString == "ADJACENCY") {
type = Lsa::Type::ADJACENCY;
}
else if (typeString == "COORDINATE") {
type = Lsa::Type::COORDINATE;
}
else if (typeString == "NAME") {
type = Lsa::Type::NAME;
}
else {
type = Lsa::Type::BASE;
}
return is;
}
std::string
Lsa::toString() const
{
std::ostringstream os;
os << "LSA of type " << getType() << ":\n-Origin Router: " << getOrigRouter()
<< "\n-Sequence Number: " << getLsSeqNo() << "\n-Expiration Point: "
<< getExpirationTimePoint() << "\n";
return os.str();
}
} // namespace nlsr
namespace std {
std::string
to_string(const nlsr::Lsa::Type& type)
{
switch (type) {
case nlsr::Lsa::Type::ADJACENCY:
return "ADJACENCY";
case nlsr::Lsa::Type::COORDINATE:
return "COORDINATE";
case nlsr::Lsa::Type::NAME:
return "NAME";
case nlsr::Lsa::Type::MOCK:
return "MOCK";
default:
return "BASE";
}
}
} // namespace std
-427
View File
@@ -1,427 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NLSR_LSA_HPP
#define NLSR_LSA_HPP
#include "name-prefix-list.hpp"
#include "adjacent.hpp"
#include "adjacency-list.hpp"
#include <boost/cstdint.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <ndn-cxx/util/time.hpp>
#include <boost/tokenizer.hpp>
namespace nlsr {
class Nlsr;
class Lsa
{
public:
enum class Type {
ADJACENCY,
COORDINATE,
NAME,
BASE,
MOCK
};
Lsa()
: m_origRouter()
, m_lsSeqNo()
, m_expirationTimePoint()
, m_expiringEventId()
{
}
virtual Type
getType() const
{
return Type::BASE;
}
void
setLsSeqNo(uint32_t lsn)
{
m_lsSeqNo = lsn;
}
uint32_t
getLsSeqNo() const
{
return m_lsSeqNo;
}
const ndn::Name&
getOrigRouter() const
{
return m_origRouter;
}
void
setOrigRouter(const ndn::Name& org)
{
m_origRouter = org;
}
const ndn::time::system_clock::TimePoint&
getExpirationTimePoint() const
{
return m_expirationTimePoint;
}
void
setExpirationTimePoint(const ndn::time::system_clock::TimePoint& lt)
{
m_expirationTimePoint = lt;
}
void
setExpiringEventId(const ndn::EventId leei)
{
m_expiringEventId = leei;
}
ndn::EventId
getExpiringEventId() const
{
return m_expiringEventId;
}
/*! \brief Return the data that this LSA represents.
*/
virtual std::string
serialize() const = 0;
/*! \brief Gets the key for this LSA.
Format is: \<router name\>/\<LSA type>\
*/
const ndn::Name
getKey() const;
/*! \brief Populate this LSA with content from the string "content".
\param content The string containing a valid serialization of LSA content.
This method populates "this" LSA with data from the string.
*/
virtual bool
deserialize(const std::string& content) noexcept = 0;
virtual void
writeLog() const = 0;
protected:
/*! Get data common to all LSA types.
This method should be called by all LSA classes in their
serialize() method.
*/
std::string
getData() const;
/*! Print data common to all LSA types.
*/
std::string
toString() const;
bool
deserializeCommon(boost::tokenizer<boost::char_separator<char>>::iterator& iterator);
protected:
ndn::Name m_origRouter;
uint32_t m_lsSeqNo;
ndn::time::system_clock::TimePoint m_expirationTimePoint;
ndn::EventId m_expiringEventId;
};
class NameLsa: public Lsa
{
public:
NameLsa()
{
}
NameLsa(const ndn::Name& origR, uint32_t lsn,
const ndn::time::system_clock::TimePoint& lt,
NamePrefixList& npl);
Lsa::Type
getType() const override
{
return Lsa::Type::NAME;
}
NamePrefixList&
getNpl()
{
return m_npl;
}
const NamePrefixList&
getNpl() const
{
return m_npl;
}
void
addName(const ndn::Name& name)
{
m_npl.insert(name);
}
void
removeName(const ndn::Name& name)
{
m_npl.remove(name);
}
/*! \brief Initializes this LSA object with content's data.
\param content The data (e.g. name prefixes) to initialize this LSA with.
This function initializes this object to represent the data
contained in content. The format for this is the same as for
getData(); getData() returns data of this format, in other words.
*/
bool
deserialize(const std::string& content) noexcept override;
bool
isEqualContent(const NameLsa& other) const;
void
writeLog() const override;
/*! \brief Returns the data that this name LSA has.
Format is: \<original router
prefix\>|name|\<seq. no.\>|\<exp. time\>|\<prefix 1\>|\<prefix
2\>|...|\<prefix n\>|
*/
std::string
serialize() const override;
private:
NamePrefixList m_npl;
friend std::ostream&
operator<<(std::ostream& os, const NameLsa& lsa);
};
class AdjLsa: public Lsa
{
public:
typedef AdjacencyList::const_iterator const_iterator;
AdjLsa()
{
}
AdjLsa(const ndn::Name& origR, uint32_t lsn,
const ndn::time::system_clock::TimePoint& lt,
uint32_t nl , AdjacencyList& adl);
Lsa::Type
getType() const override
{
return Lsa::Type::ADJACENCY;
}
AdjacencyList&
getAdl()
{
return m_adl;
}
const AdjacencyList&
getAdl() const
{
return m_adl;
}
void
addAdjacent(Adjacent adj)
{
m_adl.insert(adj);
}
/*! \brief Initializes this adj. LSA from the supplied content.
\param content The content that this LSA is to have, formatted
according to getData().
*/
bool
deserialize(const std::string& content) noexcept override;
uint32_t
getNoLink()
{
return m_noLink;
}
bool
isEqualContent(AdjLsa& alsa);
/*! \brief Installs this LSA's name prefixes into the NPT.
\param pnlsr The NLSR top-level whose NPT you want to install the
entries into.
*/
void
addNptEntries(Nlsr& pnlsr);
void
removeNptEntries(Nlsr& pnlsr);
void
writeLog() const override;
const_iterator
begin() const
{
return m_adl.begin();
}
const_iterator
end() const
{
return m_adl.end();
}
/*! \brief Returns the data this adjacency LSA has.
The format is: \<original
router\>|adjacency|\<seq. no.\>|\<exp. time\>|\<size\>|\<adjacency prefix
1\>|\<face uri 1\>|\<cost 1\>|...|\<adjacency prefix n\>|\<face uri
n\>|\<cost n\>|
*/
std::string
serialize() const override;
private:
uint32_t m_noLink;
AdjacencyList m_adl;
friend std::ostream&
operator<<(std::ostream& os, const AdjLsa& lsa);
};
class CoordinateLsa: public Lsa
{
public:
CoordinateLsa()
: m_corRad(0)
{
}
CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
const ndn::time::system_clock::TimePoint& lt,
double r, std::vector<double> theta);
Lsa::Type
getType() const override
{
return Lsa::Type::COORDINATE;
}
/*! \brief Initializes this coordinate LSA with the data in content.
\param content The string content that is used to build the LSA.
This function initializes this LSA object to represent the data
specified by the parameter. The format that it is expecting is the
same as for getData();
*/
bool
deserialize(const std::string& content) noexcept override;
double
getCorRadius() const
{
return m_corRad;
}
void
setCorRadius(double cr)
{
m_corRad = cr;
}
const std::vector<double>
getCorTheta() const
{
return m_angles;
}
void
setCorTheta(std::vector<double> ct)
{
m_angles = ct;
}
bool
isEqualContent(const CoordinateLsa& clsa);
void
writeLog() const override;
/*! \brief Returns the data that this coordinate LSA represents.
The format is: \<original
router\>|coordinate|\<seq. no.\>|\<exp. time\>|\<radians\>|\<theta\>|
*/
std::string
serialize() const override;
private:
double m_corRad;
std::vector<double> m_angles;
friend std::ostream&
operator<<(std::ostream& os, const CoordinateLsa& lsa);
};
std::ostream&
operator<<(std::ostream& os, const AdjLsa& lsa);
std::ostream&
operator<<(std::ostream& os, const CoordinateLsa& lsa);
std::ostream&
operator<<(std::ostream& os, const NameLsa& lsa);
std::ostream&
operator<<(std::ostream& os, const Lsa::Type& type);
std::istream&
operator>>(std::istream& is, Lsa::Type& type);
} // namespace nlsr
namespace std {
std::string
to_string(const nlsr::Lsa::Type& type);
} // namespace std
#endif // NLSR_LSA_HPP
+162
View File
@@ -0,0 +1,162 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "adj-lsa.hpp"
#include "tlv-nlsr.hpp"
namespace nlsr {
AdjLsa::AdjLsa(const ndn::Name& originRouter, uint64_t seqNo,
const ndn::time::system_clock::time_point& timepoint,
uint32_t noLink, AdjacencyList& adl)
: Lsa(originRouter, seqNo, timepoint)
, m_noLink(noLink)
{
for (const auto& adjacent : adl.getAdjList()) {
if (adjacent.getStatus() == Adjacent::STATUS_ACTIVE) {
addAdjacent(adjacent);
}
}
}
AdjLsa::AdjLsa(const ndn::Block& block)
{
wireDecode(block);
}
bool
AdjLsa::isEqualContent(const AdjLsa& alsa) const
{
return m_adl == alsa.getAdl();
}
template<ndn::encoding::Tag TAG>
size_t
AdjLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
{
size_t totalLength = 0;
auto list = m_adl.getAdjList();
for (auto it = list.rbegin(); it != list.rend(); ++it) {
totalLength += it->wireEncode(block);
}
totalLength += Lsa::wireEncode(block);
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(nlsr::tlv::AdjacencyLsa);
return totalLength;
}
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(AdjLsa);
const ndn::Block&
AdjLsa::wireEncode() const
{
if (m_wire.hasWire()) {
return m_wire;
}
ndn::EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
ndn::EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
AdjLsa::wireDecode(const ndn::Block& wire)
{
m_wire = wire;
if (m_wire.type() != nlsr::tlv::AdjacencyLsa) {
NDN_THROW(Error("AdjacencyLsa", m_wire.type()));
}
m_wire.parse();
auto val = m_wire.elements_begin();
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Lsa) {
Lsa::wireDecode(*val);
++val;
}
else {
NDN_THROW(Error("Missing required Lsa field"));
}
AdjacencyList adl;
for (; val != m_wire.elements_end(); ++val) {
if (val->type() == nlsr::tlv::Adjacency) {
adl.insert(Adjacent(*val));
}
else {
NDN_THROW(Error("Adjacency", val->type()));
}
}
m_adl = adl;
}
std::string
AdjLsa::toString() const
{
std::ostringstream os;
os << getString();
os << " Adjacent(s):\n";
int adjacencyIndex = 0;
for (const auto& adjacency : m_adl) {
os << " Adjacent " << adjacencyIndex++
<< ": (name=" << adjacency.getName()
<< ", uri=" << adjacency.getFaceUri()
<< ", cost=" << adjacency.getLinkCost() << ")\n";
}
return os.str();
}
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
AdjLsa::update(const std::shared_ptr<Lsa>& lsa)
{
auto alsa = std::static_pointer_cast<AdjLsa>(lsa);
if (!isEqualContent(*alsa)) {
resetAdl();
for (const auto& adjacent : alsa->getAdl()) {
addAdjacent(adjacent);
}
return {true, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
}
return {false, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
}
std::ostream&
operator<<(std::ostream& os, const AdjLsa& lsa)
{
return os << lsa.toString();
}
} // namespace nlsr
+134
View File
@@ -0,0 +1,134 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NLSR_LSA_ADJ_LSA_HPP
#define NLSR_LSA_ADJ_LSA_HPP
#include "lsa.hpp"
#include "adjacent.hpp"
#include "adjacency-list.hpp"
namespace nlsr {
/*!
\brief Data abstraction for AdjLsa
AdjacencyLsa := ADJACENCY-LSA-TYPE TLV-LENGTH
Lsa
Adjacency*
*/
class AdjLsa : public Lsa
{
public:
typedef AdjacencyList::const_iterator const_iterator;
AdjLsa() = default;
AdjLsa(const ndn::Name& originR, uint64_t seqNo,
const ndn::time::system_clock::time_point& timepoint,
uint32_t noLink, AdjacencyList& adl);
AdjLsa(const ndn::Block& block);
Lsa::Type
getType() const override
{
return type();
}
static constexpr Lsa::Type
type()
{
return Lsa::Type::ADJACENCY;
}
const AdjacencyList&
getAdl() const
{
return m_adl;
}
void
resetAdl()
{
m_wire.reset();
m_adl.reset();
}
void
addAdjacent(Adjacent adj)
{
m_wire.reset();
m_adl.insert(adj);
}
uint32_t
getNoLink()
{
return m_noLink;
}
bool
isEqualContent(const AdjLsa& alsa) const;
const_iterator
begin() const
{
return m_adl.begin();
}
const_iterator
end() const
{
return m_adl.end();
}
template<ndn::encoding::Tag TAG>
size_t
wireEncode(ndn::EncodingImpl<TAG>& block) const;
const ndn::Block&
wireEncode() const override;
void
wireDecode(const ndn::Block& wire);
std::string
toString() const override;
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
update(const std::shared_ptr<Lsa>& lsa) override;
private:
uint32_t m_noLink;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
AdjacencyList m_adl;
};
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(AdjLsa);
std::ostream&
operator<<(std::ostream& os, const AdjLsa& lsa);
} // namespace nlsr
#endif // NLSR_LSA_ADJ_LSA_HPP
+175
View File
@@ -0,0 +1,175 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "coordinate-lsa.hpp"
#include "tlv-nlsr.hpp"
namespace nlsr {
CoordinateLsa::CoordinateLsa(const ndn::Name& originRouter, uint64_t seqNo,
const ndn::time::system_clock::time_point& timepoint,
double radius, std::vector<double> angles)
: Lsa(originRouter, seqNo, timepoint)
, m_hyperbolicRadius(radius)
, m_hyperbolicAngles(angles)
{
}
CoordinateLsa::CoordinateLsa(const ndn::Block& block)
{
wireDecode(block);
}
bool
CoordinateLsa::isEqualContent(const CoordinateLsa& clsa) const
{
if (clsa.getCorTheta().size() != m_hyperbolicAngles.size()) {
return false;
}
std::vector<double> m_angles2 = clsa.getCorTheta();
for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
if (std::abs(m_hyperbolicAngles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
return false;
}
}
return (std::abs(m_hyperbolicRadius - clsa.getCorRadius()) <
std::numeric_limits<double>::epsilon());
}
template<ndn::encoding::Tag TAG>
size_t
CoordinateLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
{
size_t totalLength = 0;
for (auto it = m_hyperbolicAngles.rbegin(); it != m_hyperbolicAngles.rend(); ++it) {
totalLength += ndn::encoding::prependDoubleBlock(block, nlsr::tlv::HyperbolicAngle, *it);
}
totalLength += ndn::encoding::prependDoubleBlock(block, nlsr::tlv::HyperbolicRadius, m_hyperbolicRadius);
totalLength += Lsa::wireEncode(block);
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(nlsr::tlv::CoordinateLsa);
return totalLength;
}
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(CoordinateLsa);
const ndn::Block&
CoordinateLsa::wireEncode() const
{
if (m_wire.hasWire()) {
return m_wire;
}
ndn::EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
ndn::EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
CoordinateLsa::wireDecode(const ndn::Block& wire)
{
m_wire = wire;
if (m_wire.type() != nlsr::tlv::CoordinateLsa) {
NDN_THROW(Error("CoordinateLsa", m_wire.type()));
}
m_wire.parse();
auto val = m_wire.elements_begin();
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Lsa) {
Lsa::wireDecode(*val);
++val;
}
else {
NDN_THROW(Error("Missing required Lsa field"));
}
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::HyperbolicRadius) {
m_hyperbolicRadius = ndn::encoding::readDouble(*val);
++val;
}
else {
NDN_THROW(Error("Missing required HyperbolicRadius field"));
}
std::vector<double> angles;
for (; val != m_wire.elements_end(); ++val) {
if (val->type() == nlsr::tlv::HyperbolicAngle) {
angles.push_back(ndn::encoding::readDouble(*val));
}
else {
NDN_THROW(Error("Missing required HyperbolicAngle field"));
}
}
m_hyperbolicAngles = angles;
}
std::string
CoordinateLsa::toString() const
{
std::ostringstream os;
os << getString();
os << " Hyperbolic Radius : " << m_hyperbolicRadius << "\n";
int i = 0;
for (const auto& value : m_hyperbolicAngles) {
os << " Hyperbolic Theta " << i++ << " : " << value << "\n";
}
return os.str();
}
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
CoordinateLsa::update(const std::shared_ptr<Lsa>& lsa)
{
auto clsa = std::static_pointer_cast<CoordinateLsa>(lsa);
if (!isEqualContent(*clsa)) {
m_hyperbolicRadius = clsa->getCorRadius();
m_hyperbolicAngles.clear();
for (const auto& angle : clsa->getCorTheta()) {
m_hyperbolicAngles.push_back(angle);
}
return {true, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
}
return {false, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
}
std::ostream&
operator<<(std::ostream& os, const CoordinateLsa& lsa)
{
return os << lsa.toString();
}
} // namespace nlsr
+116
View File
@@ -0,0 +1,116 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NLSR_LSA_COORDINATE_LSA_HPP
#define NLSR_LSA_COORDINATE_LSA_HPP
#include "lsa.hpp"
namespace nlsr {
/*!
\brief Data abstraction for CoordinateLsa
CoordinateLsa := COORDINATE-LSA-TYPE TLV-LENGTH
Lsa
HyperbolicRadius
HyperbolicAngle+
*/
class CoordinateLsa : public Lsa
{
public:
CoordinateLsa() = default;
CoordinateLsa(const ndn::Name& originRouter, uint64_t seqNo,
const ndn::time::system_clock::time_point& timepoint,
double radius, std::vector<double> angles);
CoordinateLsa(const ndn::Block& block);
Lsa::Type
getType() const override
{
return type();
}
static constexpr Lsa::Type
type()
{
return Lsa::Type::COORDINATE;
}
double
getCorRadius() const
{
return m_hyperbolicRadius;
}
void
setCorRadius(double cr)
{
m_wire.reset();
m_hyperbolicRadius = cr;
}
const std::vector<double>
getCorTheta() const
{
return m_hyperbolicAngles;
}
void
setCorTheta(std::vector<double> ct)
{
m_wire.reset();
m_hyperbolicAngles = ct;
}
bool
isEqualContent(const CoordinateLsa& clsa) const;
template<ndn::encoding::Tag TAG>
size_t
wireEncode(ndn::EncodingImpl<TAG>& block) const;
const ndn::Block&
wireEncode() const override;
void
wireDecode(const ndn::Block& wire);
std::string
toString() const override;
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
update(const std::shared_ptr<Lsa>& lsa) override;
private:
double m_hyperbolicRadius = 0.0;
std::vector<double> m_hyperbolicAngles;
};
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(CoordinateLsa);
std::ostream&
operator<<(std::ostream& os, const CoordinateLsa& lsa);
} // namespace nlsr
#endif // NLSR_LSA_COORDINATE_LSA_HPP
+153
View File
@@ -0,0 +1,153 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "lsa.hpp"
#include "tlv-nlsr.hpp"
namespace nlsr {
Lsa::Lsa(const ndn::Name& originRouter, uint64_t seqNo,
ndn::time::system_clock::time_point expirationTimePoint)
: m_originRouter(originRouter)
, m_seqNo(seqNo)
, m_expirationTimePoint(expirationTimePoint)
{
}
Lsa::Lsa(const Lsa& lsa)
: m_originRouter(lsa.getOriginRouter())
, m_seqNo(lsa.getSeqNo())
, m_expirationTimePoint(lsa.getExpirationTimePoint())
{
}
template<ndn::encoding::Tag TAG>
size_t
Lsa::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
{
size_t totalLength = 0;
totalLength += prependStringBlock(encoder,
nlsr::tlv::ExpirationTime,
ndn::time::toString(m_expirationTimePoint));
totalLength += prependNonNegativeIntegerBlock(encoder, nlsr::tlv::SequenceNumber, m_seqNo);
totalLength += m_originRouter.wireEncode(encoder);
totalLength += encoder.prependVarNumber(totalLength);
totalLength += encoder.prependVarNumber(nlsr::tlv::Lsa);
return totalLength;
}
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
void
Lsa::wireDecode(const ndn::Block& wire)
{
m_originRouter.clear();
m_seqNo = 0;
ndn::Block baseWire = wire;
baseWire.parse();
auto val = baseWire.elements_begin();
if (val != baseWire.elements_end() && val->type() == ndn::tlv::Name) {
m_originRouter.wireDecode(*val);
}
else {
NDN_THROW(Error("OriginRouter: Missing required Name field"));
}
++val;
if (val != baseWire.elements_end() && val->type() == nlsr::tlv::SequenceNumber) {
m_seqNo = ndn::readNonNegativeInteger(*val);
++val;
}
else {
NDN_THROW(Error("Missing required SequenceNumber field"));
}
if (val != baseWire.elements_end() && val->type() == nlsr::tlv::ExpirationTime) {
m_expirationTimePoint = ndn::time::fromString(readString(*val));
}
else {
NDN_THROW(Error("Missing required ExpirationTime field"));
}
}
std::ostream&
operator<<(std::ostream& os, const Lsa::Type& type)
{
switch (type) {
case Lsa::Type::ADJACENCY:
os << "ADJACENCY";
break;
case Lsa::Type::COORDINATE:
os << "COORDINATE";
break;
case Lsa::Type::NAME:
os << "NAME";
break;
default:
os << "BASE";
break;
}
return os;
}
std::istream&
operator>>(std::istream& is, Lsa::Type& type)
{
std::string typeString;
is >> typeString;
if (typeString == "ADJACENCY") {
type = Lsa::Type::ADJACENCY;
}
else if (typeString == "COORDINATE") {
type = Lsa::Type::COORDINATE;
}
else if (typeString == "NAME") {
type = Lsa::Type::NAME;
}
else {
type = Lsa::Type::BASE;
}
return is;
}
std::string
Lsa::getString() const
{
std::ostringstream os;
auto duration = m_expirationTimePoint - ndn::time::system_clock::now();
os << " " << getType() << " LSA:\n"
<< " Origin Router : " << m_originRouter << "\n"
<< " Sequence Number : " << m_seqNo << "\n"
<< " Expires in : " << ndn::time::duration_cast<ndn::time::milliseconds>(duration)
<< "\n";
return os.str();
}
} // namespace nlsr
+157
View File
@@ -0,0 +1,157 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NLSR_LSA_LSA_HPP
#define NLSR_LSA_LSA_HPP
#include "common.hpp"
#include "test-access-control.hpp"
#include <ndn-cxx/util/scheduler.hpp>
#include <list>
namespace nlsr {
/*!
\brief Data abstraction for Lsa
Lsa := LSA-TYPE TLV-LENGTH
Name
SequenceNumber
ExpirationTimePoint
*/
class Lsa
{
public:
class Error : public ndn::tlv::Error
{
public:
using ndn::tlv::Error::Error;
};
enum class Type {
ADJACENCY,
COORDINATE,
NAME,
BASE
};
protected:
Lsa(const ndn::Name& originRouter, uint64_t seqNo,
ndn::time::system_clock::time_point expirationTimePoint);
Lsa() = default;
Lsa(const Lsa& lsa);
public:
virtual
~Lsa() = default;
virtual Type
getType() const = 0;
void
setSeqNo(uint64_t seqNo)
{
m_seqNo = seqNo;
m_wire.reset();
}
uint64_t
getSeqNo() const
{
return m_seqNo;
}
const ndn::Name&
getOriginRouter() const
{
return m_originRouter;
}
ndn::Name
getOriginRouterCopy() const
{
return m_originRouter;
}
const ndn::time::system_clock::time_point&
getExpirationTimePoint() const
{
return m_expirationTimePoint;
}
void
setExpirationTimePoint(const ndn::time::system_clock::time_point& lt)
{
m_expirationTimePoint = lt;
m_wire.reset();
}
void
setExpiringEventId(ndn::scheduler::EventId eid)
{
m_expiringEventId = eid;
}
/*! Get data common to all LSA types for printing purposes.
*/
virtual std::string
toString() const = 0;
virtual std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
update(const std::shared_ptr<Lsa>& lsa) = 0;
virtual const ndn::Block&
wireEncode() const = 0;
protected:
template<ndn::encoding::Tag TAG>
size_t
wireEncode(ndn::EncodingImpl<TAG>& block) const;
void
wireDecode(const ndn::Block& wire);
std::string
getString() const;
PUBLIC_WITH_TESTS_ELSE_PROTECTED:
ndn::Name m_originRouter;
uint64_t m_seqNo = 0;
ndn::time::system_clock::time_point m_expirationTimePoint;
ndn::scheduler::ScopedEventId m_expiringEventId;
mutable ndn::Block m_wire;
};
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
std::ostream&
operator<<(std::ostream& os, const Lsa::Type& type);
std::istream&
operator>>(std::istream& is, Lsa::Type& type);
} // namespace nlsr
#endif // NLSR_LSA_LSA_HPP
+165
View File
@@ -0,0 +1,165 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "name-lsa.hpp"
#include "tlv-nlsr.hpp"
namespace nlsr {
NameLsa::NameLsa(const ndn::Name& originRouter, uint64_t seqNo,
const ndn::time::system_clock::time_point& timepoint,
const NamePrefixList& npl)
: Lsa(originRouter, seqNo, timepoint)
{
for (const auto& name : npl.getNames()) {
addName(name);
}
}
NameLsa::NameLsa(const ndn::Block& block)
{
wireDecode(block);
}
template<ndn::encoding::Tag TAG>
size_t
NameLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
{
size_t totalLength = 0;
auto names = m_npl.getNames();
for (auto it = names.rbegin(); it != names.rend(); ++it) {
totalLength += it->wireEncode(block);
}
totalLength += Lsa::wireEncode(block);
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(nlsr::tlv::NameLsa);
return totalLength;
}
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(NameLsa);
const ndn::Block&
NameLsa::wireEncode() const
{
if (m_wire.hasWire()) {
return m_wire;
}
ndn::EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
ndn::EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
NameLsa::wireDecode(const ndn::Block& wire)
{
m_wire = wire;
if (m_wire.type() != nlsr::tlv::NameLsa) {
NDN_THROW(Error("NameLsa", m_wire.type()));
}
m_wire.parse();
auto val = m_wire.elements_begin();
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Lsa) {
Lsa::wireDecode(*val);
++val;
}
else {
NDN_THROW(Error("Missing required Lsa field"));
}
NamePrefixList npl;
for (; val != m_wire.elements_end(); ++val) {
if (val->type() == ndn::tlv::Name) {
npl.insert(ndn::Name(*val));
}
else {
NDN_THROW(Error("Name", val->type()));
}
}
m_npl = npl;
}
std::string
NameLsa::toString() const
{
std::ostringstream os;
os << getString();
os << " Names:\n";
int i = 0;
for (const auto& name : m_npl.getNames()) {
os << " Name " << i++ << ": " << name << "\n";
}
return os.str();
}
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
NameLsa::update(const std::shared_ptr<Lsa>& lsa)
{
auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
bool updated = false;
// Obtain the set difference of the current and the incoming
// name prefix sets, and add those.
std::list<ndn::Name> newNames = nlsa->getNpl().getNames();
std::list<ndn::Name> oldNames = m_npl.getNames();
std::list<ndn::Name> namesToAdd;
std::set_difference(newNames.begin(), newNames.end(), oldNames.begin(), oldNames.end(),
std::inserter(namesToAdd, namesToAdd.begin()));
for (const auto& name : namesToAdd) {
addName(name);
updated = true;
}
// Also remove any names that are no longer being advertised.
std::list<ndn::Name> namesToRemove;
std::set_difference(oldNames.begin(), oldNames.end(), newNames.begin(), newNames.end(),
std::inserter(namesToRemove, namesToRemove.begin()));
for (const auto& name : namesToRemove) {
removeName(name);
updated = true;
}
return {updated, namesToAdd, namesToRemove};
}
std::ostream&
operator<<(std::ostream& os, const NameLsa& lsa)
{
return os << lsa.toString();
}
} // namespace nlsr
+125
View File
@@ -0,0 +1,125 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NLSR_LSA_NAME_LSA_HPP
#define NLSR_LSA_NAME_LSA_HPP
#include "lsa.hpp"
#include "name-prefix-list.hpp"
#include <boost/operators.hpp>
namespace nlsr {
/*!
\brief Data abstraction for NameLsa
NameLsa := NAME-LSA-TYPE TLV-LENGTH
Lsa
Name+
*/
class NameLsa : public Lsa, private boost::equality_comparable<NameLsa>
{
public:
NameLsa() = default;
NameLsa(const ndn::Name& originRouter, uint64_t seqNo,
const ndn::time::system_clock::time_point& timepoint,
const NamePrefixList& npl);
NameLsa(const ndn::Block& block);
Lsa::Type
getType() const override
{
return type();
}
static constexpr Lsa::Type
type()
{
return Lsa::Type::NAME;
}
NamePrefixList&
getNpl()
{
return m_npl;
}
const NamePrefixList&
getNpl() const
{
return m_npl;
}
void
addName(const ndn::Name& name)
{
m_wire.reset();
m_npl.insert(name);
}
void
removeName(const ndn::Name& name)
{
m_wire.reset();
m_npl.erase(name);
}
template<ndn::encoding::Tag TAG>
size_t
wireEncode(ndn::EncodingImpl<TAG>& block) const;
const ndn::Block&
wireEncode() const override;
void
wireDecode(const ndn::Block& wire);
std::string
toString() const override;
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
update(const std::shared_ptr<Lsa>& lsa) override;
private: // non-member operators
// NOTE: the following "hidden friend" operators are available via
// argument-dependent lookup only and must be defined inline.
// boost::equality_comparable provides != operator.
friend bool
operator==(const NameLsa& lhs, const NameLsa& rhs)
{
return lhs.m_npl == rhs.m_npl;
}
private:
NamePrefixList m_npl;
};
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(NameLsa);
std::ostream&
operator<<(std::ostream& os, const NameLsa& lsa);
} // namespace nlsr
#endif // NLSR_LSA_NAME_LSA_HPP
+372 -1179
View File
File diff suppressed because it is too large. Load diff
+245 -296
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,231 +17,232 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NLSR_LSDB_HPP
#define NLSR_LSDB_HPP
#include "conf-parameter.hpp"
#include "lsa.hpp"
#include "lsa-segment-storage.hpp"
#include "sequencing-manager.hpp"
#include "test-access-control.hpp"
#include "communication/sync-logic-handler.hpp"
#include "conf-parameter.hpp"
#include "lsa/lsa.hpp"
#include "lsa/name-lsa.hpp"
#include "lsa/coordinate-lsa.hpp"
#include "lsa/adj-lsa.hpp"
#include "sequencing-manager.hpp"
#include "statistics.hpp"
#include "test-access-control.hpp"
#include <ndn-cxx/ims/in-memory-storage-fifo.hpp>
#include <ndn-cxx/ims/in-memory-storage-persistent.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/util/segmenter.hpp>
#include <ndn-cxx/util/segment-fetcher.hpp>
#include <ndn-cxx/util/signal.hpp>
#include <ndn-cxx/util/time.hpp>
#include <utility>
#include <boost/cstdint.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/hashed_index.hpp>
namespace nlsr {
class Nlsr;
namespace bmi = boost::multi_index;
inline constexpr ndn::time::seconds GRACE_PERIOD = 10_s;
enum class LsdbUpdate {
INSTALLED,
UPDATED,
REMOVED
};
class Lsdb
{
public:
Lsdb(Nlsr& nlsr, ndn::Scheduler& scheduler);
Lsdb(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam);
SyncLogicHandler&
getSyncLogicHandler()
~Lsdb();
/*! \brief Returns whether the LSDB contains some LSA.
*/
bool
doesLsaExist(const ndn::Name& router, Lsa::Type lsaType)
{
return m_sync;
return m_lsdb.get<byName>().find(std::make_tuple(router, lsaType)) != m_lsdb.end();
}
bool
isLsaNew(const ndn::Name& routerName, const Lsa::Type& lsaType, const uint64_t& sequenceNumber);
bool
doesLsaExist(const ndn::Name& key, const Lsa::Type& lsType);
/*! \brief Builds a name LSA for this router and then installs it
into the LSDB.
*/
bool
void
buildAndInstallOwnNameLsa();
/*! \brief Returns the name LSA with the given key.
\param key The name of the router that the desired LSA comes from.
*/
NameLsa*
findNameLsa(const ndn::Name& key);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/*! \brief Builds a cor. LSA for this router and installs it into the LSDB. */
void
buildAndInstallOwnCoordinateLsa();
/*! \brief Installs a name LSA into the LSDB
\param nlsa The name LSA to install into the LSDB.
public:
/*! \brief Schedules a build of this router's LSA. */
void
scheduleAdjLsaBuild();
void
writeLog() const;
/* \brief Process interest which can be either:
* 1) Discovery interest from segment fetcher:
* /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>
* 2) Interest containing segment number:
* /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>/<version>/<segmentNo>
*/
void
processInterest(const ndn::Name& name, const ndn::Interest& interest);
bool
getIsBuildAdjLsaScheduled() const
{
return m_isBuildAdjLsaScheduled;
}
SyncLogicHandler&
getSync()
{
return m_sync;
}
template<typename T>
std::shared_ptr<T>
findLsa(const ndn::Name& router) const
{
return std::static_pointer_cast<T>(findLsa(router, T::type()));
}
struct name_hash {
int
operator()(const ndn::Name& name) const {
return std::hash<ndn::Name>{}(name);
}
};
struct enum_class_hash {
template<typename T>
int
operator()(T t) const {
return static_cast<int>(t);
}
};
struct byName{};
struct byType{};
using LsaContainer = boost::multi_index_container<
std::shared_ptr<Lsa>,
bmi::indexed_by<
bmi::hashed_unique<
bmi::tag<byName>,
bmi::composite_key<
Lsa,
bmi::const_mem_fun<Lsa, ndn::Name, &Lsa::getOriginRouterCopy>,
bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>
>,
bmi::composite_key_hash<name_hash, enum_class_hash>
>,
bmi::hashed_non_unique<
bmi::tag<byType>,
bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>,
enum_class_hash
>
>
>;
template<typename T>
std::pair<LsaContainer::index<Lsdb::byType>::type::iterator,
LsaContainer::index<Lsdb::byType>::type::iterator>
getLsdbIterator() const
{
return m_lsdb.get<byType>().equal_range(T::type());
}
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
std::shared_ptr<Lsa>
findLsa(const ndn::Name& router, Lsa::Type lsaType) const
{
auto it = m_lsdb.get<byName>().find(std::make_tuple(router, lsaType));
return it != m_lsdb.end() ? *it : nullptr;
}
void
incrementDataSentStats(Lsa::Type lsaType)
{
if (lsaType == Lsa::Type::NAME) {
lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_DATA);
}
else if (lsaType == Lsa::Type::ADJACENCY) {
lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_DATA);
}
else if (lsaType == Lsa::Type::COORDINATE) {
lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_DATA);
}
}
void
incrementInterestRcvdStats(Lsa::Type lsaType)
{
if (lsaType == Lsa::Type::NAME) {
lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_INTEREST);
}
else if (lsaType == Lsa::Type::ADJACENCY) {
lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_INTEREST);
}
else if (lsaType == Lsa::Type::COORDINATE) {
lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_INTEREST);
}
}
void
incrementInterestSentStats(Lsa::Type lsaType)
{
if (lsaType == Lsa::Type::NAME) {
lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_INTEREST);
}
else if (lsaType == Lsa::Type::ADJACENCY) {
lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_INTEREST);
}
else if (lsaType == Lsa::Type::COORDINATE) {
lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_INTEREST);
}
}
/*! Returns whether a seq. no. from a certain router signals a new LSA.
\param originRouter The name of the originating router.
\param lsaType The type of the LSA.
\param seqNo The sequence number to check.
*/
bool
installNameLsa(NameLsa& nlsa);
isLsaNew(const ndn::Name& originRouter, const Lsa::Type& lsaType, uint64_t seqNo) const
{
// Is the name in the LSDB and the supplied seq no is the highest so far
auto lsaPtr = findLsa(originRouter, lsaType);
return lsaPtr ? lsaPtr->getSeqNo() < seqNo : true;
}
void
installLsa(std::shared_ptr<Lsa> lsa);
/*! \brief Remove a name LSA from the LSDB.
\param key The name of the router that published the LSA to remove.
\param router The name of the router that published the LSA to remove.
\param lsaType The type of the LSA.
This function will remove a name LSA from the LSDB by finding an
LSA whose name matches key. This removal also causes the NPT to
remove those name prefixes if no more LSAs advertise them.
*/
bool
removeNameLsa(const ndn::Name& key);
/*! Returns whether a seq. no. from a certain router signals a new LSA.
\param key The name of the originating router.
\param seqNo The sequence number to check.
*/
bool
isNameLsaNew(const ndn::Name& key, uint64_t seqNo);
void
removeLsa(const ndn::Name& router, Lsa::Type lsaType);
void
writeNameLsdbLog();
const std::list<NameLsa>&
getNameLsdb() const;
/*! \brief Builds a cor. LSA for this router and installs it into the LSDB. */
bool
buildAndInstallOwnCoordinateLsa();
/*! \brief Finds a cor. LSA in the LSDB.
\param key The name of the originating router that published the LSA.
*/
CoordinateLsa*
findCoordinateLsa(const ndn::Name& key);
/*! \brief Installs a cor. LSA into the LSDB.
\param clsa The cor. LSA to install.
*/
bool
installCoordinateLsa(CoordinateLsa& clsa);
/*! \brief Removes a cor. LSA from the LSDB.
\param key The name of the router that published the LSA to remove.
Removes the coordinate LSA whose origin router name matches that
given by key. Additionally, ask the NPT to remove the prefix,
which will occur if no other LSAs point there.
*/
bool
removeCoordinateLsa(const ndn::Name& key);
/*! \brief Returns whether a cor. LSA from a router is new or not.
\param key The name prefix of the originating router.
\param seqNo The sequence number of the candidate LSA.
*/
bool
isCoordinateLsaNew(const ndn::Name& key, uint64_t seqNo);
void
writeCorLsdbLog();
const std::list<CoordinateLsa>&
getCoordinateLsdb() const;
//function related to Adj LSDB
/*! \brief Schedules a build of this router's LSA. */
void
scheduleAdjLsaBuild();
/*! \brief Wrapper event to build and install an adj. LSA for this router. */
bool
buildAndInstallOwnAdjLsa();
/*! \brief Removes an adj. LSA from the LSDB.
\param key The name of the publishing router whose LSA to remove.
*/
bool
removeAdjLsa(const ndn::Name& key);
/*! \brief Returns whether an LSA is new.
\param key The name of the publishing router.
\param seqNo The seq. no. of the candidate LSA.
This function determines whether the LSA with the name key and
seq. no. seqNo would be new to this LSDB.
*/
bool
isAdjLsaNew(const ndn::Name& key, uint64_t seqNo);
/*! \brief Installs an adj. LSA into the LSDB.
\param alsa The adj. LSA to add to the LSDB.
*/
bool
installAdjLsa(AdjLsa& alsa);
/*! \brief Finds an adj. LSA in the LSDB.
\param key The name of the publishing router whose LSA to find.
*/
AdjLsa*
findAdjLsa(const ndn::Name& key);
const std::list<AdjLsa>&
getAdjLsdb() const;
void
setAdjLsaBuildInterval(uint32_t interval)
{
m_adjLsaBuildInterval = ndn::time::seconds(interval);
}
const ndn::time::seconds&
getAdjLsaBuildInterval() const
{
return m_adjLsaBuildInterval;
}
SequencingManager&
getSequencingManager()
{
return m_sequencingManager;
}
LsaSegmentStorage&
getLsaStorage()
{
return m_lsaStorage;
}
void
writeAdjLsdbLog();
void
setLsaRefreshTime(const ndn::time::seconds& lsaRefreshTime);
void
setThisRouterPrefix(std::string trp);
void
expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
ndn::time::steady_clock::TimePoint deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
void
processInterest(const ndn::Name& name, const ndn::Interest& interest);
private:
/* \brief Add a name LSA to the LSDB if it isn't already there.
\param nlsa The candidade name LSA.
*/
bool
addNameLsa(NameLsa& nlsa);
/*! \brief Returns whether the LSDB contains some LSA.
\param key The name of the publishing router whose LSA to check for.
*/
bool
doesNameLsaExist(const ndn::Name& key);
/*! \brief Adds a cor. LSA to the LSDB if it isn't already there.
\param clsa The candidate cor. LSA.
*/
bool
addCoordinateLsa(CoordinateLsa& clsa);
/*! \brief Returns whether a cor. LSA is in the LSDB.
\param key The name of the router that published the queried LSA.
*/
bool
doesCoordinateLsaExist(const ndn::Name& key);
removeLsa(const LsaContainer::index<Lsdb::byName>::type::iterator& lsaIt);
/*! \brief Attempts to construct an adj. LSA.
@@ -253,92 +254,31 @@ private:
void
buildAdjLsa();
/*! \brief Adds an adj. LSA to the LSDB if it isn't already there.
\param alsa The candidate adj. LSA to add to the LSDB.
*/
bool
addAdjLsa(AdjLsa& alsa);
/*! \brief Returns whether the LSDB contains an LSA.
\param key The name of a router whose LSA to check for in the LSDB.
*/
bool
doesAdjLsaExist(const ndn::Name& key);
/*! \brief Wrapper event to build and install an adj. LSA for this router. */
void
buildAndInstallOwnAdjLsa();
/*! \brief Schedules a refresh/expire event in the scheduler.
\param key The name of the router that published the LSA.
\param seqNo The seq. no. associated with the LSA.
\param lsa The LSA.
\param expTime How many seconds to wait before triggering the event.
*/
ndn::EventId
scheduleNameLsaExpiration(const ndn::Name& key, int seqNo,
const ndn::time::seconds& expTime);
ndn::scheduler::EventId
scheduleLsaExpiration(std::shared_ptr<Lsa> lsa, ndn::time::seconds expTime);
/*! \brief Either allow to expire, or refresh a name LSA.
\param lsaKey The name of the router that published the LSA.
\param seqNo The seq. no. of the LSA to check.
\param lsa The LSA.
*/
void
expireOrRefreshNameLsa(const ndn::Name& lsaKey, uint64_t seqNo);
expireOrRefreshLsa(std::shared_ptr<Lsa> lsa);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/*! \brief Schedules an expire/refresh event in the LSA.
\param key The name of the router whose LSA is in question.
\param seqNo The sequence number of the LSA to check.
\param expTime The number of seconds to wait before triggering the event.
*/
ndn::EventId
scheduleAdjLsaExpiration(const ndn::Name& key, int seqNo,
const ndn::time::seconds& expTime);
private:
bool
processInterestForLsa(const ndn::Interest& interest, const ndn::Name& originRouter,
Lsa::Type lsaType, uint64_t seqNo);
void
expireOrRefreshAdjLsa(const ndn::Name& lsaKey, uint64_t seqNo);
expressInterest(const ndn::Name& interestName, uint32_t timeoutCount, uint64_t incomingFaceId,
ndn::time::steady_clock::time_point deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
ndn::EventId
scheduleCoordinateLsaExpiration(const ndn::Name& key, int seqNo,
const ndn::time::seconds& expTime);
void
expireOrRefreshCoordinateLsa(const ndn::Name& lsaKey,
uint64_t seqNo);
private:
void
putLsaData(const ndn::Interest& interest, const std::string& content);
void
processInterestForNameLsa(const ndn::Interest& interest,
const ndn::Name& lsaKey,
uint64_t seqNo);
void
processInterestForAdjacencyLsa(const ndn::Interest& interest,
const ndn::Name& lsaKey,
uint64_t seqNo);
void
processInterestForCoordinateLsa(const ndn::Interest& interest,
const ndn::Name& lsaKey,
uint64_t seqNo);
void
onContentValidated(const std::shared_ptr<const ndn::Data>& data);
void
processContentNameLsa(const ndn::Name& lsaKey,
uint64_t lsSeqNo, std::string& dataContent);
void
processContentAdjacencyLsa(const ndn::Name& lsaKey,
uint64_t lsSeqNo, std::string& dataContent);
void
processContentCoordinateLsa(const ndn::Name& lsaKey,
uint64_t lsSeqNo, std::string& dataContent);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/*!
\brief Error callback when SegmentFetcher fails to return an LSA
@@ -354,13 +294,10 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
is reached.
*/
void
onFetchLsaError(uint32_t errorCode,
const std::string& msg,
ndn::Name& interestName,
uint32_t retransmitNo,
const ndn::time::steady_clock::TimePoint& deadline,
ndn::Name lsaName,
uint64_t seqNo);
onFetchLsaError(uint32_t errorCode, const std::string& msg,
const ndn::Name& interestName, uint32_t retransmitNo,
const ndn::time::steady_clock::time_point& deadline,
ndn::Name lsaName, uint64_t seqNo);
/*!
\brief Success callback when SegmentFetcher returns a valid LSA
@@ -369,48 +306,60 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/<network>/NLSR/LSA/<site>/%C1.Router/<router>/<lsa-type>/<seqNo>
*/
void
afterFetchLsa(const ndn::ConstBufferPtr& data, ndn::Name& interestName);
afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, const ndn::Name& interestName);
private:
ndn::time::system_clock::TimePoint
getLsaExpirationTimePoint();
/*! \brief Cancels an event in the event scheduler. */
void
cancelScheduleLsaExpiringEvent(ndn::EventId eid);
emitSegmentValidatedSignal(const ndn::Data& data)
{
afterSegmentValidatedSignal(data);
}
ndn::time::system_clock::time_point
getLsaExpirationTimePoint() const
{
return ndn::time::system_clock::now() + ndn::time::seconds(m_confParam.getRouterDeadInterval());
}
public:
static const ndn::Name::Component NAME_COMPONENT;
ndn::signal::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
ndn::signal::Signal<Lsdb, ndn::Data> afterSegmentValidatedSignal;
using AfterLsdbModified = ndn::signal::Signal<Lsdb, std::shared_ptr<Lsa>, LsdbUpdate,
std::list<ndn::Name>, std::list<ndn::Name>>;
AfterLsdbModified onLsdbModified;
ndn::util::signal::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
ndn::Face& m_face;
ndn::Scheduler m_scheduler;
ConfParameter& m_confParam;
private:
Nlsr& m_nlsr;
ndn::Scheduler& m_scheduler;
SyncLogicHandler m_sync;
LsaSegmentStorage m_lsaStorage;
std::list<NameLsa> m_nameLsdb;
std::list<AdjLsa> m_adjLsdb;
std::list<CoordinateLsa> m_corLsdb;
LsaContainer m_lsdb;
ndn::time::seconds m_lsaRefreshTime;
std::string m_thisRouterPrefix;
typedef std::map<ndn::Name, uint64_t> SequenceNumberMap;
ndn::time::seconds m_adjLsaBuildInterval;
const ndn::Name& m_thisRouterPrefix;
// Maps the name of an LSA to its highest known sequence number from sync;
// Used to stop NLSR from trying to fetch outdated LSAs
SequenceNumberMap m_highestSeqNo;
static const ndn::time::seconds GRACE_PERIOD;
static const ndn::time::steady_clock::TimePoint DEFAULT_LSA_RETRIEVAL_DEADLINE;
ndn::time::seconds m_adjLsaBuildInterval;
std::map<ndn::Name, uint64_t> m_highestSeqNo;
SequencingManager m_sequencingManager;
ndn::util::signal::ScopedConnection m_onNewLsaConnection;
ndn::signal::ScopedConnection m_onNewLsaConnection;
std::set<std::shared_ptr<ndn::SegmentFetcher>> m_fetchers;
ndn::Segmenter m_segmenter;
ndn::InMemoryStorageFifo m_segmentFifo;
bool m_isBuildAdjLsaScheduled;
int64_t m_adjBuildCount;
ndn::scheduler::ScopedEventId m_scheduledAdjLsaBuild;
ndn::InMemoryStoragePersistent m_lsaStorage;
static inline const ndn::time::steady_clock::time_point DEFAULT_LSA_RETRIEVAL_DEADLINE =
ndn::time::steady_clock::time_point::min();
};
} // namespace nlsr
+57 -46
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -19,68 +19,79 @@
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "nlsr-runner.hpp"
#include "conf-file-processor.hpp"
#include "nlsr.hpp"
#include "security/certificate-store.hpp"
#include "version.hpp"
#include <boost/exception/get_error_info.hpp>
#include <sstream>
#include <boost/exception/diagnostic_information.hpp>
#include <iostream>
template<typename E>
std::string
getExtendedErrorMessage(const E& exception)
static void
printUsage(std::ostream& os, const std::string& programName)
{
std::ostringstream errorMessage;
errorMessage << exception.what();
const char* const* file = boost::get_error_info<boost::throw_file>(exception);
const int* line = boost::get_error_info<boost::throw_line>(exception);
const char* const* func = boost::get_error_info<boost::throw_function>(exception);
if (file && line) {
errorMessage << " [from " << *file << ":" << *line;
if (func) {
errorMessage << " in " << *func;
}
errorMessage << "]";
}
return errorMessage.str();
os << "Usage: " << programName << " [OPTIONS...]\n"
<< "\n"
<< "Options:\n"
<< " -f <FILE> Path to configuration file\n"
<< " -h Display this help message\n"
<< " -V Display version information\n"
<< std::endl;
}
int
main(int32_t argc, char** argv)
main(int argc, char** argv)
{
using namespace nlsr;
std::string programName(argv[0]);
std::string configFileName("nlsr.conf");
std::string configFileName = "nlsr.conf";
int32_t opt;
while ((opt = getopt(argc, argv, "df:hV")) != -1) {
int opt;
while ((opt = getopt(argc, argv, "hf:V")) != -1) {
switch (opt) {
case 'f':
configFileName = optarg;
break;
case 'V':
std::cout << NLSR_VERSION_BUILD_STRING << std::endl;
return EXIT_SUCCESS;
break;
case 'h':
default:
NlsrRunner::printUsage(programName);
return EXIT_FAILURE;
case 'h':
printUsage(std::cout, programName);
return 0;
case 'f':
configFileName = optarg;
break;
case 'V':
std::cout << NLSR_VERSION_BUILD_STRING << std::endl;
return 0;
default:
printUsage(std::cerr, programName);
return 2;
}
}
NlsrRunner runner(configFileName);
ndn::KeyChain keyChain;
ndn::Face face(nullptr, keyChain);
nlsr::ConfParameter confParam(face, keyChain, configFileName);
nlsr::ConfFileProcessor configProcessor(confParam);
if (!configProcessor.processConfFile()) {
std::cerr << "Error in configuration file processing" << std::endl;
return 2;
}
// Since confParam is already populated, key is initialized here before
// and independent of the NLSR class
auto certificate = confParam.initializeKey();
nlsr::Nlsr nlsr(face, keyChain, confParam);
nlsr::security::CertificateStore certStore(face, confParam, nlsr.getLsdb());
if (certificate) {
certStore.insert(*certificate);
}
try {
runner.run();
face.processEvents();
}
catch (const std::exception& e) {
std::cerr << getExtendedErrorMessage(e) << std::endl;
return EXIT_FAILURE;
nlsr.getFib().clean();
std::cerr << "FATAL: " << boost::diagnostic_information(e) << std::endl;
return 1;
}
return EXIT_SUCCESS;
return 0;
}
+32 -102
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,144 +17,74 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "name-prefix-list.hpp"
#include "common.hpp"
#include <iostream>
#include <algorithm>
namespace nlsr {
NamePrefixList::NamePrefixList() = default;
NamePrefixList::NamePrefixList(const std::initializer_list<ndn::Name>& names)
NamePrefixList::NamePrefixList(std::initializer_list<ndn::Name> names)
{
std::vector<NamePrefixList::NamePair> namePairs;
std::transform(names.begin(), names.end(), std::back_inserter(namePairs),
[] (const ndn::Name& name) {
return NamePrefixList::NamePair{name, {""}};
});
m_names = std::move(namePairs);
}
NamePrefixList::NamePrefixList(const std::initializer_list<NamePrefixList::NamePair>& namesAndSources)
: m_names(namesAndSources)
{
}
NamePrefixList::~NamePrefixList()
{
}
std::vector<NamePrefixList::NamePair>::iterator
NamePrefixList::get(const ndn::Name& name)
{
return std::find_if(m_names.begin(), m_names.end(),
[&] (const NamePrefixList::NamePair& pair) {
return name == std::get<NamePrefixList::NamePairIndex::NAME>(pair);
});
}
std::vector<std::string>::iterator
NamePrefixList::getSource(const std::string& source, std::vector<NamePair>::iterator& entry)
{
return std::find_if(std::get<NamePairIndex::SOURCES>(*entry).begin(),
std::get<NamePairIndex::SOURCES>(*entry).end(),
[&] (const std::string& containerSource) {
return source == containerSource;
});
for (const auto& name : names) {
insert(name);
}
}
bool
NamePrefixList::insert(const ndn::Name& name, const std::string& source)
{
auto pairItr = get(name);
if (pairItr == m_names.end()) {
std::vector<std::string> sources{source};
m_names.push_back(std::tie(name, sources));
return true;
}
else {
std::vector<std::string>& sources = std::get<NamePrefixList::NamePairIndex::SOURCES>(*pairItr);
auto sourceItr = getSource(source, pairItr);
if (sourceItr == sources.end()) {
sources.push_back(source);
return true;
}
}
return false;
auto& sources = m_namesSources[name];
return sources.insert(source).second;
}
bool
NamePrefixList::remove(const ndn::Name& name, const std::string& source)
NamePrefixList::erase(const ndn::Name& name, const std::string& source)
{
auto pairItr = get(name);
if (pairItr != m_names.end()) {
std::vector<std::string>& sources = std::get<NamePrefixList::NamePairIndex::SOURCES>(*pairItr);
auto sourceItr = getSource(source, pairItr);
if (sourceItr != sources.end()) {
sources.erase(sourceItr);
if (sources.size() == 0) {
m_names.erase(pairItr);
}
return true;
}
auto it = m_namesSources.find(name);
if (it == m_namesSources.end()) {
return false;
}
return false;
}
bool
NamePrefixList::operator==(const NamePrefixList& other) const
{
return m_names == other.m_names;
}
void
NamePrefixList::sort()
{
std::sort(m_names.begin(), m_names.end());
bool isRemoved = it->second.erase(source);
if (it->second.empty()) {
m_namesSources.erase(it);
}
return isRemoved;
}
std::list<ndn::Name>
NamePrefixList::getNames() const
{
std::list<ndn::Name> names;
for (const auto& namePair : m_names) {
names.push_back(std::get<NamePrefixList::NamePairIndex::NAME>(namePair));
for (const auto& [name, sources] : m_namesSources) {
names.push_back(name);
}
return names;
}
uint32_t
NamePrefixList::countSources(const ndn::Name& name) const
{
return getSources(name).size();
}
#ifdef WITH_TESTS
const std::vector<std::string>
std::set<std::string>
NamePrefixList::getSources(const ndn::Name& name) const
{
auto it = std::find_if(m_names.begin(), m_names.end(),
[&] (const NamePrefixList::NamePair& pair) {
return name == std::get<NamePrefixList::NamePairIndex::NAME>(pair);
});
if (it != m_names.end()) {
return std::get<NamePrefixList::NamePairIndex::SOURCES>(*it);
}
else {
return std::vector<std::string>{};
if (auto it = m_namesSources.find(name); it != m_namesSources.end()) {
return it->second;
}
return {};
}
#endif
std::ostream&
operator<<(std::ostream& os, const NamePrefixList& list) {
operator<<(std::ostream& os, const NamePrefixList& list)
{
os << "Name prefix list: {\n";
for (const auto& name : list.getNames()) {
os << name << "\n"
<< "Sources:\n";
for (const auto& source : list.getSources(name)) {
for (const auto& [name, sources] : list.m_namesSources) {
os << name << "\nSources:\n";
for (const auto& source : sources) {
os << " " << source << "\n";
}
}
+48 -67
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,107 +17,88 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NLSR_NAME_PREFIX_LIST_HPP
#define NLSR_NAME_PREFIX_LIST_HPP
#include <list>
#include <string>
#include <boost/cstdint.hpp>
#include "test-access-control.hpp"
#include <ndn-cxx/name.hpp>
#include <boost/operators.hpp>
#include <initializer_list>
#include <list>
#include <map>
#include <set>
#include <string>
namespace nlsr {
class NamePrefixList
class NamePrefixList : private boost::equality_comparable<NamePrefixList>
{
public:
using NamePair = std::tuple<ndn::Name, std::vector<std::string>>;
enum NamePairIndex {
NAME,
SOURCES
};
NamePrefixList();
NamePrefixList(const std::initializer_list<ndn::Name>& names);
explicit
NamePrefixList(std::initializer_list<ndn::Name> names);
NamePrefixList(const std::initializer_list<NamePrefixList::NamePair>& namesAndSources);
template<class ContainerType>
NamePrefixList(const ContainerType& names)
{
for (const auto& elem : names) {
m_names.push_back(NamePair{elem, {""}});
}
}
~NamePrefixList();
/*! \brief inserts name into NamePrefixList
\retval true If the name was successfully inserted.
\retval false If the name could not be inserted.
/*! \brief Inserts name and source combination.
\retval true Name and source combination is inserted.
\retval false Name and source combination already exists.
*/
bool
insert(const ndn::Name& name, const std::string& source = "");
/*! \brief removes name from NamePrefixList
\retval true If the name is removed
\retval false If the name failed to be removed.
/*! \brief Deletes name and source combination
\retval true Name and source combination is deleted.
\retval false Name and source combination does not exist.
*/
bool
remove(const ndn::Name& name, const std::string& source = "");
void
sort();
erase(const ndn::Name& name, const std::string& source = "");
size_t
size() const
{
return m_names.size();
return m_namesSources.size();
}
std::list<ndn::Name>
getNames() const;
bool
operator==(const NamePrefixList& other) const;
/*! Returns how many unique sources this name has.
\retval 0 if the name is not in the list, else the number of sources.
*/
uint32_t
countSources(const ndn::Name& name) const;
#ifdef WITH_TESTS
/*! Returns the sources that this name has.
\retval an empty vector if the name is not in the list, else a
vector containing the sources.
If the name does not exist, returns an empty container.
*/
const std::vector<std::string>
std::set<std::string>
getSources(const ndn::Name& name) const;
#endif
void
clear()
{
m_namesSources.clear();
}
private: // non-member operators
// NOTE: the following "hidden friend" operators are available via
// argument-dependent lookup only and must be defined inline.
// boost::equality_comparable provides != operators.
friend bool
operator==(const NamePrefixList& lhs, const NamePrefixList& rhs)
{
return lhs.getNames() == rhs.getNames();
}
private:
/*! Obtain an iterator to the entry matching name.
std::map<ndn::Name, std::set<std::string>> m_namesSources;
\note We could do this quite easily inline with a lambda, but this
is slightly more efficient.
*/
std::vector<NamePair>::iterator
get(const ndn::Name& name);
/*! Obtain an iterator to a specific source in an entry
*/
std::vector<std::string>::iterator
getSource(const std::string& source, std::vector<NamePair>::iterator& entry);
std::vector<NamePair> m_names;
friend std::ostream&
operator<<(std::ostream& os, const NamePrefixList& list);
};
std::ostream&
operator<<(std::ostream& os, const NamePrefixList& list);
} // namespace nlsr
#endif // NLSR_NAME_PREFIX_LIST_HPP
-81
View File
@@ -1,81 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "nlsr-runner.hpp"
#include "conf-file-processor.hpp"
#include "logger.hpp"
namespace nlsr {
INIT_LOGGER(NlsrRunner);
NlsrRunner::NlsrRunner(std::string& configFileName)
: m_scheduler(m_ioService)
, m_face(m_ioService)
, m_nlsr(m_ioService, m_scheduler, m_face, m_keyChain)
{
m_nlsr.setConfFileName(configFileName);
}
void
NlsrRunner::run()
{
ConfFileProcessor configProcessor(m_nlsr, m_nlsr.getConfFileName());
if (!configProcessor.processConfFile()) {
BOOST_THROW_EXCEPTION(Error("Error in configuration file processing! Exiting from NLSR"));
}
/** Because URI canonization needs to occur before initialization,
we have to pass initialize as the finally() in neighbor
canonization.
*/
m_nlsr.canonizeNeighborUris(m_nlsr.getAdjacencyList().getAdjList().begin(),
[this] (std::list<Adjacent>::iterator iterator) {
m_nlsr.canonizeContinuation(iterator, [this] {
m_nlsr.initialize();
});
},
[this] {
m_nlsr.initialize();
});
try {
m_nlsr.startEventLoop();
}
catch (const std::exception& e) {
NLSR_LOG_FATAL("ERROR: " << e.what());
std::cerr << "ERROR: " << e.what() << std::endl;
m_nlsr.getFib().clean();
}
}
void
NlsrRunner::printUsage(const std::string& programName)
{
std::cout << "Usage: " << programName << " [OPTIONS...]" << std::endl;
std::cout << " NDN routing...." << std::endl;
std::cout << " -f <FILE> Specify configuration file name" << std::endl;
std::cout << " -V Display version information" << std::endl;
std::cout << " -h Display this help message" << std::endl;
}
} // namespace nlsr
-88
View File
@@ -1,88 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NLSR_NLSR_RUNNER_HPP
#define NLSR_NLSR_RUNNER_HPP
#include "nlsr.hpp"
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/util/scheduler.hpp>
// boost needs to be included after ndn-cxx, otherwise there will be conflict with _1, _2, ...
#include <boost/asio.hpp>
namespace nlsr {
/*! \brief A wrapper class to instantiate and configure an NLSR object.
*
* As its name suggests, this class is responsible for running
* NLSR. It creates an nlsr::ConfFileProcessor to read a configuration
* file and uses that to configure and then start an NLSR process.
* This class only exists to provide this functionality, and there is
* no special reliance of NLSR on this class.
*/
class NlsrRunner
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
explicit
NlsrRunner(std::string& configFileName);
/*! \brief Instantiate, configure, and start the NLSR process.
*
* Each NlsrRunner is uniquely paired to the Face it's instantiated
* with. This is *not* a factory-type class, but a one-to-one
* relationship. If one wants to create multiple NLSR classes,
* multiple NLSR runners need to be created, too.
*
* \throws Error If the configuration file cannot be processed. NLSR
* is not started.
*
* \sa Nlsr::canonizeNeighborUris
*/
void
run();
static void
printUsage(const std::string& programName);
private:
boost::asio::io_service m_ioService;
ndn::Scheduler m_scheduler;
ndn::Face m_face;
ndn::KeyChain m_keyChain;
Nlsr m_nlsr;
};
} // namespace nlsr
#endif // NLSR_NLSR_RUNNER_HPP
+139 -456
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,450 +17,162 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "nlsr.hpp"
#include "adjacent.hpp"
#include "logger.hpp"
#include <cstdlib>
#include <string>
#include <sstream>
#include <cstdio>
#include <unistd.h>
#include <vector>
#include <ndn-cxx/mgmt/nfd/status-dataset.hpp>
#include <ndn-cxx/net/face-uri.hpp>
#include <ndn-cxx/signature.hpp>
namespace nlsr {
INIT_LOGGER(Nlsr);
const ndn::Name Nlsr::LOCALHOST_PREFIX = ndn::Name("/localhost/nlsr");
Nlsr::Nlsr(boost::asio::io_service& ioService, ndn::Scheduler& scheduler, ndn::Face& face, ndn::KeyChain& keyChain)
: m_nlsrFace(face)
, m_scheduler(scheduler)
, m_keyChain(keyChain)
, m_confParam()
, m_adjacencyList()
, m_namePrefixList()
, m_configFileName("nlsr.conf")
, m_nlsrLsdb(*this, scheduler)
, m_adjBuildCount(0)
, m_isBuildAdjLsaSheduled(false)
, m_isRouteCalculationScheduled(false)
, m_isRoutingTableCalculating(false)
, m_routingTable(scheduler)
, m_fib(m_nlsrFace, scheduler, m_adjacencyList, m_confParam, m_keyChain)
, m_namePrefixTable(*this, m_routingTable.afterRoutingChange)
, m_dispatcher(m_nlsrFace, m_keyChain)
, m_datasetHandler(m_nlsrLsdb,
m_routingTable,
m_dispatcher,
m_nlsrFace,
m_keyChain)
, m_helloProtocol(*this, scheduler)
, m_validator(ndn::make_unique<ndn::security::v2::CertificateFetcherDirectFetch>(m_nlsrFace))
, m_controller(m_nlsrFace, m_keyChain)
, m_faceDatasetController(m_nlsrFace, m_keyChain)
Nlsr::Nlsr(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam)
: m_face(face)
, m_scheduler(face.getIoContext())
, m_confParam(confParam)
, m_adjacencyList(confParam.getAdjacencyList())
, m_namePrefixList(confParam.getNamePrefixList())
, m_fib(m_face, m_scheduler, m_adjacencyList, m_confParam, keyChain)
, m_lsdb(m_face, keyChain, m_confParam)
, m_routingTable(m_scheduler, m_lsdb, m_confParam)
, m_namePrefixTable(confParam.getRouterPrefix(), m_fib, m_routingTable,
m_routingTable.afterRoutingChange, m_lsdb.onLsdbModified)
, m_helloProtocol(m_face, keyChain, confParam, m_routingTable, m_lsdb)
, m_onNewLsaConnection(m_lsdb.getSync().onNewLsa.connect(
[this] (const ndn::Name& updateName, uint64_t sequenceNumber,
const ndn::Name& originRouter, uint64_t incomingFaceId) {
registerStrategyForCerts(originRouter);
}))
, m_onPrefixRegistrationSuccess(m_fib.onPrefixRegistrationSuccess.connect(
[this] (const ndn::Name& name) {
m_helloProtocol.sendHelloInterest(name);
}))
, m_onInitialHelloDataValidated(m_helloProtocol.onInitialHelloDataValidated.connect(
[this] (const ndn::Name& neighbor) {
auto it = m_adjacencyList.findAdjacent(neighbor);
if (it != m_adjacencyList.end()) {
m_fib.registerPrefix(m_confParam.getSyncPrefix(), it->getFaceUri(), it->getLinkCost(),
ndn::time::milliseconds::max(), ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
}
}))
, m_dispatcher(m_face, keyChain)
, m_datasetHandler(m_dispatcher, m_lsdb, m_routingTable)
, m_controller(m_face, keyChain)
, m_faceDatasetController(m_face, keyChain)
, m_prefixUpdateProcessor(m_dispatcher,
m_nlsrFace,
m_namePrefixList,
m_nlsrLsdb)
m_confParam.getPrefixUpdateValidator(),
m_namePrefixList,
m_lsdb,
m_confParam.getConfFileNameDynamic())
, m_nfdRibCommandProcessor(m_dispatcher,
m_namePrefixList,
m_nlsrLsdb)
, m_statsCollector(m_nlsrLsdb, m_helloProtocol)
, m_faceMonitor(m_nlsrFace)
, m_firstHelloInterval(FIRST_HELLO_INTERVAL_DEFAULT)
{
m_faceMonitor.onNotification.connect(std::bind(&Nlsr::onFaceEventNotification, this, _1));
m_faceMonitor.start();
}
void
Nlsr::registrationFailed(const ndn::Name& name)
{
NLSR_LOG_ERROR("ERROR: Failed to register prefix in local hub's daemon");
BOOST_THROW_EXCEPTION(Error("Error: Prefix registration failed"));
}
void
Nlsr::onRegistrationSuccess(const ndn::Name& name)
{
NLSR_LOG_DEBUG("Successfully registered prefix: " << name);
}
void
Nlsr::setInfoInterestFilter()
{
ndn::Name name(m_confParam.getRouterPrefix());
name.append("NLSR");
name.append("INFO");
NLSR_LOG_DEBUG("Setting interest filter for Hello interest: " << name);
getNlsrFace().setInterestFilter(name,
std::bind(&HelloProtocol::processInterest,
&m_helloProtocol, _1, _2),
std::bind(&Nlsr::onRegistrationSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1),
m_signingInfo,
ndn::nfd::ROUTE_FLAG_CAPTURE);
}
void
Nlsr::setLsaInterestFilter()
{
ndn::Name name = m_confParam.getLsaPrefix();
NLSR_LOG_DEBUG("Setting interest filter for LsaPrefix: " << name);
getNlsrFace().setInterestFilter(name,
std::bind(&Lsdb::processInterest,
&m_nlsrLsdb, _1, _2),
std::bind(&Nlsr::onRegistrationSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1),
m_signingInfo,
ndn::nfd::ROUTE_FLAG_CAPTURE);
}
void
Nlsr::addDispatcherTopPrefix(const ndn::Name& topPrefix)
{
try {
m_dispatcher.addTopPrefix(topPrefix, false, m_signingInfo);
}
catch (const std::exception& e) {
NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what() << "\n");
}
}
void
Nlsr::setStrategies()
{
const std::string strategy("ndn:/localhost/nfd/strategy/multicast");
m_fib.setStrategy(m_confParam.getLsaPrefix(), strategy, 0);
m_fib.setStrategy(m_confParam.getChronosyncPrefix(), strategy, 0);
}
void
Nlsr::canonizeContinuation(std::list<Adjacent>::iterator iterator,
std::function<void(void)> finally)
{
canonizeNeighborUris(iterator, [this, finally] (std::list<Adjacent>::iterator iterator) {
canonizeContinuation(iterator, finally);
},
finally);
}
void
Nlsr::canonizeNeighborUris(std::list<Adjacent>::iterator currentNeighbor,
std::function<void(std::list<Adjacent>::iterator)> then,
std::function<void(void)> finally)
{
if (currentNeighbor != m_adjacencyList.getAdjList().end()) {
ndn::FaceUri uri(currentNeighbor->getFaceUri());
uri.canonize([this, then, currentNeighbor] (ndn::FaceUri canonicalUri) {
NLSR_LOG_DEBUG("Canonized URI: " << currentNeighbor->getFaceUri()
<< " to: " << canonicalUri);
currentNeighbor->setFaceUri(canonicalUri);
then(std::next(currentNeighbor));
},
[this, then, currentNeighbor] (const std::string& reason) {
NLSR_LOG_ERROR("Could not canonize URI: " << currentNeighbor->getFaceUri()
<< " because: " << reason);
then(std::next(currentNeighbor));
},
m_nlsrFace.getIoService(),
TIME_ALLOWED_FOR_CANONIZATION);
}
// We have finished canonizing all neighbors, so call finally()
else {
finally();
}
}
void
Nlsr::loadCertToPublish(const ndn::security::v2::Certificate& certificate)
{
NLSR_LOG_TRACE("Loading cert to publish.");
m_certStore.insert(certificate);
m_validator.loadAnchor("Authoritative-Certificate",
ndn::security::v2::Certificate(certificate));
m_prefixUpdateProcessor.getValidator().
loadAnchor("Authoritative-Certificate",
ndn::security::v2::Certificate(certificate));
}
void
Nlsr::connectToFetcher(ndn::util::SegmentFetcher& fetcher)
{
NLSR_LOG_TRACE("NLSR: Connect to SegmentFetcher.");
fetcher.afterSegmentValidated.connect(std::bind(&Nlsr::afterFetcherSignalEmitted,
this, _1));
}
void
Nlsr::afterFetcherSignalEmitted(const ndn::Data& lsaSegment)
{
NLSR_LOG_TRACE("SegmentFetcher fetched a data segment. Start inserting cert to own cert store.");
ndn::Name keyName = lsaSegment.getSignature().getKeyLocator().getName();
if (getCertificate(keyName) == nullptr) {
publishCertFromCache(keyName);
}
else {
NLSR_LOG_TRACE("Certificate is already in the store: " << keyName);
}
}
void
Nlsr::publishCertFromCache(const ndn::Name& keyName)
{
const ndn::security::v2::Certificate* cert = m_validator.getUnverifiedCertCache()
.find(keyName);
if (cert != nullptr) {
m_certStore.insert(*cert);
NLSR_LOG_TRACE(*cert);
NLSR_LOG_TRACE("Setting interest filter for: "
<< ndn::security::v2::extractKeyNameFromCertName(cert->getName()));
m_nlsrFace.setInterestFilter(ndn::security::v2::extractKeyNameFromCertName(cert->getName()),
std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1),
m_signingInfo,
ndn::nfd::ROUTE_FLAG_CAPTURE);
if (!cert->getKeyName().equals(cert->getSignature().getKeyLocator().getName())) {
publishCertFromCache(cert->getSignature().getKeyLocator().getName());
}
}
else {
NLSR_LOG_TRACE("Cert for " << keyName << " was not found in the Validator's cache. ");
}
}
void
Nlsr::initialize()
m_namePrefixList,
m_lsdb)
, m_statsCollector(m_lsdb, m_helloProtocol)
, m_faceMonitor(m_face)
{
NLSR_LOG_DEBUG("Initializing Nlsr");
m_confParam.buildRouterPrefix();
m_datasetHandler.setRouterNameCommandPrefix(m_confParam.getRouterPrefix());
m_nlsrLsdb.setLsaRefreshTime(ndn::time::seconds(m_confParam.getLsaRefreshTime()));
m_nlsrLsdb.setThisRouterPrefix(m_confParam.getRouterPrefix().toUri());
m_fib.setEntryRefreshTime(2 * m_confParam.getLsaRefreshTime());
m_nlsrLsdb.getSequencingManager().setSeqFileDirectory(m_confParam.getSeqFileDir());
m_nlsrLsdb.getSequencingManager().initiateSeqNoFromFile(m_confParam.getHyperbolicState());
m_faceMonitor.onNotification.connect(std::bind(&Nlsr::onFaceEventNotification, this, _1));
m_faceMonitor.start();
m_nlsrLsdb.getSyncLogicHandler().createSyncSocket(m_confParam.getChronosyncPrefix(),
m_confParam.getSyncInterestLifetime());
m_fib.setStrategy(m_confParam.getLsaPrefix(), Fib::MULTICAST_STRATEGY, 0);
m_fib.setStrategy(m_confParam.getSyncPrefix(), Fib::MULTICAST_STRATEGY, 0);
// Logging start
m_confParam.writeLog();
m_adjacencyList.writeLog();
NLSR_LOG_DEBUG(m_namePrefixList);
// Logging end
NLSR_LOG_DEBUG("Default NLSR identity: " << m_confParam.getSigningInfo().getSignerName());
initializeKey();
setStrategies();
NLSR_LOG_DEBUG("Default NLSR identity: " << m_signingInfo.getSignerName());
setInfoInterestFilter();
setLsaInterestFilter();
// add top-level prefixes: router and localhost prefix
addDispatcherTopPrefix(m_confParam.getRouterPrefix());
// Add top-level prefixes: router and localhost prefix
addDispatcherTopPrefix(ndn::Name(m_confParam.getRouterPrefix()).append("nlsr"));
addDispatcherTopPrefix(LOCALHOST_PREFIX);
enableIncomingFaceIdIndication();
initializeFaces(std::bind(&Nlsr::processFaceDataset, this, _1),
std::bind(&Nlsr::onFaceDatasetFetchTimeout, this, _1, _2, 0));
enableIncomingFaceIdIndication();
// Set event intervals
setFirstHelloInterval(m_confParam.getFirstHelloInterval());
m_nlsrLsdb.setAdjLsaBuildInterval(m_confParam.getAdjLsaBuildInterval());
m_routingTable.setRoutingCalcInterval(m_confParam.getRoutingCalcInterval());
m_nlsrLsdb.buildAndInstallOwnNameLsa();
// Install coordinate LSAs if using HR or dry-run HR.
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
m_nlsrLsdb.buildAndInstallOwnCoordinateLsa();
}
registerKeyPrefix();
registerLocalhostPrefix();
m_helloProtocol.scheduleInterest(m_firstHelloInterval);
m_adjacencyList.writeLog();
NLSR_LOG_DEBUG(m_namePrefixList);
// Need to set direct neighbors' costs to 0 for hyperbolic routing
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
std::list<Adjacent>& neighbors = m_adjacencyList.getAdjList();
for (std::list<Adjacent>::iterator it = neighbors.begin(); it != neighbors.end(); ++it) {
it->setLinkCost(0);
for (auto&& neighbor : m_adjacencyList.getAdjList()) {
neighbor.setLinkCost(0);
}
}
}
void
Nlsr::initializeKey()
Nlsr::registerStrategyForCerts(const ndn::Name& originRouter)
{
NLSR_LOG_DEBUG("Initializing Key ...");
ndn::Name nlsrInstanceName = m_confParam.getRouterPrefix();
nlsrInstanceName.append("NLSR");
try {
m_keyChain.deleteIdentity(m_keyChain.getPib().getIdentity(nlsrInstanceName));
} catch (const std::exception& e) {
NLSR_LOG_WARN(e.what());
for (const ndn::Name& router : m_strategySetOnRouters) {
if (router == originRouter) {
// Have already set strategy for this router's certs once
return;
}
}
auto nlsrInstanceIdentity = m_keyChain.createIdentity(nlsrInstanceName);
auto nlsrInstanceKey = nlsrInstanceIdentity.getDefaultKey();
m_strategySetOnRouters.push_back(originRouter);
ndn::security::v2::Certificate certificate;
ndn::Name routerKey(originRouter);
routerKey.append(ndn::security::Certificate::KEY_COMPONENT);
ndn::Name instanceKey(originRouter);
instanceKey.append("nlsr").append(ndn::security::Certificate::KEY_COMPONENT);
ndn::Name certificateName = nlsrInstanceKey.getName();
certificateName.append("NA");
certificateName.appendVersion();
certificate.setName(certificateName);
m_fib.setStrategy(routerKey, Fib::BEST_ROUTE_STRATEGY, 0);
m_fib.setStrategy(instanceKey, Fib::BEST_ROUTE_STRATEGY, 0);
// set metainfo
certificate.setContentType(ndn::tlv::ContentType_Key);
certificate.setFreshnessPeriod(ndn::time::days(365));
ndn::Name siteKey;
for (size_t i = 0; i < originRouter.size(); ++i) {
if (originRouter[i].toUri() == "%C1.Router") {
break;
}
siteKey.append(originRouter[i]);
}
ndn::Name opPrefix(siteKey);
siteKey.append(ndn::security::Certificate::KEY_COMPONENT);
m_fib.setStrategy(siteKey, Fib::BEST_ROUTE_STRATEGY, 0);
// set content
certificate.setContent(nlsrInstanceKey.getPublicKey().data(), nlsrInstanceKey.getPublicKey().size());
opPrefix.append(std::string("%C1.Operator"));
m_fib.setStrategy(opPrefix, Fib::BEST_ROUTE_STRATEGY, 0);
}
// set signature-info
ndn::SignatureInfo signatureInfo;
signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(ndn::time::system_clock::TimePoint(),
ndn::time::system_clock::now()
+ ndn::time::days(365)));
void
Nlsr::addDispatcherTopPrefix(const ndn::Name& topPrefix)
{
registerPrefix(topPrefix);
try {
m_keyChain.sign(certificate,
ndn::security::SigningInfo(m_keyChain.getPib().getIdentity(m_confParam.getRouterPrefix()))
.setSignatureInfo(signatureInfo));
// false since we want to have control over the registration process
m_dispatcher.addTopPrefix(topPrefix, false, m_confParam.getSigningInfo());
}
catch (const std::exception& e) {
NLSR_LOG_WARN("ERROR: Router's " << e.what()
<< "NLSR is running without security."
<< " If security is enabled NLSR will not converge.");
std::cerr << "Router's " << e.what() << ". NLSR is running without security "
<< "(Only for testing, should not be used in production.)"
<< " If security is enabled NLSR will not converge." << std::endl;
NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what());
}
m_signingInfo = ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID,
nlsrInstanceName);
loadCertToPublish(certificate);
m_defaultCertName = certificate.getName();
}
void
Nlsr::registerKeyPrefix()
Nlsr::registerPrefix(const ndn::Name& prefix)
{
// Start listening for the interest of this router's NLSR certificate
ndn::Name nlsrKeyPrefix = getConfParameter().getRouterPrefix();
nlsrKeyPrefix.append("NLSR");
nlsrKeyPrefix.append("KEY");
m_nlsrFace.setInterestFilter(nlsrKeyPrefix,
std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1),
m_signingInfo,
ndn::nfd::ROUTE_FLAG_CAPTURE);
// Start listening for the interest of this router's certificate
ndn::Name routerKeyPrefix = getConfParameter().getRouterPrefix();
routerKeyPrefix.append("KEY");
m_nlsrFace.setInterestFilter(routerKeyPrefix,
std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1),
m_signingInfo,
ndn::nfd::ROUTE_FLAG_CAPTURE);
// Start listening for the interest of this router's operator's certificate
ndn::Name operatorKeyPrefix = getConfParameter().getNetwork();
operatorKeyPrefix.append(getConfParameter().getSiteName());
operatorKeyPrefix.append(std::string("%C1.Operator"));
m_nlsrFace.setInterestFilter(operatorKeyPrefix,
std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1),
m_signingInfo,
ndn::nfd::ROUTE_FLAG_CAPTURE);
// Start listening for the interest of this router's site's certificate
ndn::Name siteKeyPrefix = getConfParameter().getNetwork();
siteKeyPrefix.append(getConfParameter().getSiteName());
siteKeyPrefix.append("KEY");
m_nlsrFace.setInterestFilter(siteKeyPrefix,
std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1),
m_signingInfo,
ndn::nfd::ROUTE_FLAG_CAPTURE);
}
void
Nlsr::registerLocalhostPrefix()
{
m_nlsrFace.registerPrefix(LOCALHOST_PREFIX,
std::bind(&Nlsr::onRegistrationSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1));
}
void
Nlsr::onKeyInterest(const ndn::Name& name, const ndn::Interest& interest)
{
NLSR_LOG_DEBUG("Got interest for certificate. Interest: " << interest.getName());
const ndn::Name& interestName = interest.getName();
const ndn::security::v2::Certificate* cert = getCertificate(interestName);
if (cert == nullptr) {
NLSR_LOG_DEBUG("Certificate is not found for: " << interest);
return; // cert is not found
}
m_nlsrFace.put(*cert);
}
void
Nlsr::onKeyPrefixRegSuccess(const ndn::Name& name)
{
NLSR_LOG_DEBUG("KEY prefix: " << name << " registration is successful.");
m_face.registerPrefix(prefix,
[] (const ndn::Name& name) {
NLSR_LOG_DEBUG("Successfully registered prefix: " << name);
},
[] (const ndn::Name& name, const std::string& reason) {
NLSR_LOG_ERROR("ERROR: Failed to register prefix " << name << " in local hub's daemon");
NDN_THROW(Error("Error: Prefix registration failed: " + reason));
});
}
void
Nlsr::onFaceEventNotification(const ndn::nfd::FaceEventNotification& faceEventNotification)
{
NLSR_LOG_TRACE("Nlsr::onFaceEventNotification called");
NLSR_LOG_TRACE("onFaceEventNotification called");
switch (faceEventNotification.getKind()) {
case ndn::nfd::FACE_EVENT_DESTROYED: {
@@ -495,11 +207,13 @@ Nlsr::onFaceEventNotification(const ndn::nfd::FaceEventNotification& faceEventNo
// has met the HELLO retry threshold
adjacent->setInterestTimedOutNo(m_confParam.getInterestRetryNumber());
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
getRoutingTable().scheduleRoutingTableCalculation(*this);
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
m_routingTable.scheduleRoutingTableCalculation();
}
else {
m_nlsrLsdb.scheduleAdjLsaBuild();
// Will call scheduleRoutingTableCalculation internally
// if needed in case of LS or DRY_RUN
m_lsdb.scheduleAdjLsaBuild();
}
}
}
@@ -516,23 +230,23 @@ Nlsr::onFaceEventNotification(const ndn::nfd::FaceEventNotification& faceEventNo
return;
}
auto adjacent = m_adjacencyList.findAdjacent(faceUri);
uint64_t faceId = faceEventNotification.getFaceId();
// If we have a neighbor by that FaceUri and it has no FaceId, we
// have a match.
if (adjacent != m_adjacencyList.end()) {
// If we have a neighbor by that FaceUri and it has no FaceId or
// the FaceId is different from ours, we have a match.
if (adjacent != m_adjacencyList.end() &&
(adjacent->getFaceId() == 0 || adjacent->getFaceId() != faceId))
{
NLSR_LOG_DEBUG("Face creation event matches neighbor: " << adjacent->getName()
<< ". New Face ID: " << faceEventNotification.getFaceId()
<< ". Registering prefixes.");
adjacent->setFaceId(faceEventNotification.getFaceId());
<< ". New Face ID: " << faceId << ". Registering prefixes.");
adjacent->setFaceId(faceId);
registerAdjacencyPrefixes(*adjacent, ndn::time::milliseconds::max());
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
getRoutingTable().scheduleRoutingTableCalculation(*this);
}
else {
m_nlsrLsdb.scheduleAdjLsaBuild();
}
// We should not do scheduleRoutingTableCalculation or scheduleAdjLsaBuild here
// because once the prefixes are registered, we send a HelloInterest
// to the prefix (see NLSR ctor). HelloProtocol will call these functions
// once HelloData is received and validated.
}
break;
}
@@ -545,10 +259,8 @@ void
Nlsr::initializeFaces(const FetchDatasetCallback& onFetchSuccess,
const FetchDatasetTimeoutCallback& onFetchFailure)
{
NLSR_LOG_TRACE("Initializing Faces...");
NLSR_LOG_TRACE("Initializing faces");
m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(onFetchSuccess, onFetchFailure);
}
void
@@ -557,11 +269,11 @@ Nlsr::processFaceDataset(const std::vector<ndn::nfd::FaceStatus>& faces)
NLSR_LOG_DEBUG("Processing face dataset");
// Iterate over each neighbor listed in nlsr.conf
for (auto& adjacent : m_adjacencyList.getAdjList()) {
for (auto&& adjacent : m_adjacencyList.getAdjList()) {
const std::string faceUriString = adjacent.getFaceUri().toString();
const std::string& faceUriString = adjacent.getFaceUri().toString();
// Check the list of FaceStatus objects we got for a match
for (const ndn::nfd::FaceStatus& faceStatus : faces) {
for (const auto& faceStatus : faces) {
// Set the adjacency FaceID if we find a URI match and it was
// previously unset. Change the boolean to true.
if (adjacent.getFaceId() == 0 && faceUriString == faceStatus.getRemoteUri()) {
@@ -586,8 +298,7 @@ Nlsr::processFaceDataset(const std::vector<ndn::nfd::FaceStatus>& faces)
}
void
Nlsr::registerAdjacencyPrefixes(const Adjacent& adj,
const ndn::time::milliseconds& timeout)
Nlsr::registerAdjacencyPrefixes(const Adjacent& adj, ndn::time::milliseconds timeout)
{
ndn::FaceUri faceUri = adj.getFaceUri();
double linkCost = adj.getLinkCost();
@@ -596,10 +307,6 @@ Nlsr::registerAdjacencyPrefixes(const Adjacent& adj,
m_fib.registerPrefix(adjName, faceUri, linkCost,
timeout, ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
m_fib.registerPrefix(m_confParam.getChronosyncPrefix(),
faceUri, linkCost, timeout,
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
m_fib.registerPrefix(m_confParam.getLsaPrefix(),
faceUri, linkCost, timeout,
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
@@ -610,14 +317,12 @@ Nlsr::onFaceDatasetFetchTimeout(uint32_t code,
const std::string& msg,
uint32_t nRetriesSoFar)
{
NLSR_LOG_DEBUG("onFaceDatasetFetchTimeout");
// If we have exceeded the maximum attempt count, do not try again.
if (nRetriesSoFar++ < m_confParam.getFaceDatasetFetchTries()) {
NLSR_LOG_DEBUG("Failed to fetch dataset: " << msg << ". Attempting retry #" << nRetriesSoFar);
m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(std::bind(&Nlsr::processFaceDataset,
this, _1),
std::bind(&Nlsr::onFaceDatasetFetchTimeout,
this, _1, _2, nRetriesSoFar));
m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(std::bind(&Nlsr::processFaceDataset, this, _1),
std::bind(&Nlsr::onFaceDatasetFetchTimeout,
this, _1, _2, nRetriesSoFar));
}
else {
NLSR_LOG_ERROR("Failed to fetch dataset: " << msg << ". Exceeded limit of " <<
@@ -632,17 +337,12 @@ Nlsr::onFaceDatasetFetchTimeout(uint32_t code,
void
Nlsr::scheduleDatasetFetch()
{
NLSR_LOG_DEBUG("Scheduling Dataset Fetch in " << m_confParam.getFaceDatasetFetchInterval());
NLSR_LOG_DEBUG("Scheduling dataset fetch in " << m_confParam.getFaceDatasetFetchInterval());
m_scheduler.scheduleEvent(m_confParam.getFaceDatasetFetchInterval(),
[this] {
this->initializeFaces(
[this] (const std::vector<ndn::nfd::FaceStatus>& faces) {
this->processFaceDataset(faces);
},
[this] (uint32_t code, const std::string& msg) {
this->onFaceDatasetFetchTimeout(code, msg, 0);
});
m_scheduler.schedule(m_confParam.getFaceDatasetFetchInterval(), [this] {
initializeFaces(
[this] (const auto& faces) { processFaceDataset(faces); },
[this] (uint32_t code, const std::string& msg) { onFaceDatasetFetchTimeout(code, msg, 0); });
});
}
@@ -654,31 +354,14 @@ Nlsr::enableIncomingFaceIdIndication()
m_controller.start<ndn::nfd::FaceUpdateCommand>(
ndn::nfd::ControlParameters()
.setFlagBit(ndn::nfd::FaceFlagBit::BIT_LOCAL_FIELDS_ENABLED, true),
bind(&Nlsr::onFaceIdIndicationSuccess, this, _1),
bind(&Nlsr::onFaceIdIndicationFailure, this, _1));
}
void
Nlsr::onFaceIdIndicationSuccess(const ndn::nfd::ControlParameters& cp)
{
NLSR_LOG_DEBUG("Successfully enabled incoming face id indication"
<< "for face id " << cp.getFaceId());
}
void
Nlsr::onFaceIdIndicationFailure(const ndn::nfd::ControlResponse& cr)
{
std::ostringstream os;
os << "Failed to enable incoming face id indication feature: " <<
"(code: " << cr.getCode() << ", reason: " << cr.getText() << ")";
NLSR_LOG_DEBUG(os.str());
}
void
Nlsr::startEventLoop()
{
m_nlsrFace.processEvents();
[] (const ndn::nfd::ControlParameters& cp) {
NLSR_LOG_DEBUG("Successfully enabled incoming face id indication"
<< "for face id " << cp.getFaceId());
},
[] (const ndn::nfd::ControlResponse& cr) {
NLSR_LOG_WARN("Failed to enable incoming face id indication feature: " <<
"(code: " << cr.getCode() << ", reason: " << cr.getText() << ")");
});
}
} // namespace nlsr
+49 -384
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,13 +17,12 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#ifndef NLSR_NLSR_HPP
#define NLSR_NLSR_HPP
#include "adjacency-list.hpp"
#include "common.hpp"
#include "conf-parameter.hpp"
#include "hello-protocol.hpp"
#include "lsdb.hpp"
@@ -33,37 +32,24 @@
#include "route/fib.hpp"
#include "route/name-prefix-table.hpp"
#include "route/routing-table.hpp"
#include "security/certificate-store.hpp"
#include "update/prefix-update-processor.hpp"
#include "update/nfd-rib-command-processor.hpp"
#include "utility/name-helper.hpp"
#include "stats-collector.hpp"
#include <boost/cstdint.hpp>
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/validator-config.hpp>
#include <ndn-cxx/security/v2/certificate-fetcher-direct-fetch.hpp>
#include <ndn-cxx/security/signing-helpers.hpp>
#include <ndn-cxx/security/signing-info.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <ndn-cxx/encoding/nfd-constants.hpp>
#include <ndn-cxx/mgmt/dispatcher.hpp>
#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
#include <ndn-cxx/mgmt/nfd/face-monitor.hpp>
#include <ndn-cxx/mgmt/dispatcher.hpp>
#include <ndn-cxx/mgmt/nfd/face-status.hpp>
#include <ndn-cxx/data.hpp>
#include <ndn-cxx/encoding/block.hpp>
#include <ndn-cxx/encoding/nfd-constants.hpp>
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/util/scheduler.hpp>
namespace nlsr {
static ndn::Name DEFAULT_BROADCAST_PREFIX("/ndn/broadcast");
class Nlsr
{
public:
@@ -73,26 +59,26 @@ public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
using std::runtime_error::runtime_error;
};
Nlsr(boost::asio::io_service& ioService, ndn::Scheduler& scheduler, ndn::Face& face, ndn::KeyChain& keyChain);
Nlsr(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam);
void
registrationFailed(const ndn::Name& name);
Lsdb&
getLsdb()
{
return m_lsdb;
}
void
onRegistrationSuccess(const ndn::Name& name);
Fib&
getFib()
{
return m_fib;
}
private:
void
setInfoInterestFilter();
void
setLsaInterestFilter();
registerStrategyForCerts(const ndn::Name& originRouter);
/*! \brief Add top level prefixes for Dispatcher
*
@@ -102,150 +88,7 @@ public:
void
addDispatcherTopPrefix(const ndn::Name& topPrefix);
void
startEventLoop();
std::string
getConfFileName() const
{
return m_configFileName;
}
void
setConfFileName(const std::string& fileName)
{
m_configFileName = fileName;
}
ConfParameter&
getConfParameter()
{
return m_confParam;
}
const ConfParameter&
getConfParameter() const
{
return m_confParam;
}
AdjacencyList&
getAdjacencyList()
{
return m_adjacencyList;
}
const AdjacencyList&
getAdjacencyList() const
{
return m_adjacencyList;
}
NamePrefixList&
getNamePrefixList()
{
return m_namePrefixList;
}
const NamePrefixList&
getNamePrefixList() const
{
return m_namePrefixList;
}
ndn::Face&
getNlsrFace()
{
return m_nlsrFace;
}
Lsdb&
getLsdb()
{
return m_nlsrLsdb;
}
RoutingTable&
getRoutingTable()
{
return m_routingTable;
}
NamePrefixTable&
getNamePrefixTable()
{
return m_namePrefixTable;
}
Fib&
getFib()
{
return m_fib;
}
long int
getAdjBuildCount()
{
return m_adjBuildCount;
}
void
incrementAdjBuildCount()
{
m_adjBuildCount++;
}
void
setAdjBuildCount(int64_t abc)
{
m_adjBuildCount = abc;
}
bool
getIsBuildAdjLsaSheduled()
{
return m_isBuildAdjLsaSheduled;
}
void
setIsBuildAdjLsaSheduled(bool iabls)
{
m_isBuildAdjLsaSheduled = iabls;
}
bool
getIsRoutingTableCalculating()
{
return m_isRoutingTableCalculating;
}
void
setIsRoutingTableCalculating(bool irtc)
{
m_isRoutingTableCalculating = irtc;
}
bool
getIsRouteCalculationScheduled()
{
return m_isRouteCalculationScheduled;
}
void
setIsRouteCalculationScheduled(bool ircs)
{
m_isRouteCalculationScheduled = ircs;
}
DatasetInterestHandler&
getDatasetHandler()
{
return m_datasetHandler;
}
void
initialize();
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/*! \brief Initializes neighbors' Faces using information from NFD.
* \sa Nlsr::initialize()
* \sa Nlsr::processFaceDataset()
@@ -278,6 +121,7 @@ public:
void
processFaceDataset(const std::vector<ndn::nfd::FaceStatus>& faces);
private:
/*! \brief Registers NLSR-specific prefixes for a neighbor (Adjacent)
* \sa Nlsr::initializeFaces
* \param adj A reference to the neighbor to register prefixes for
@@ -288,186 +132,18 @@ public:
* *each* registration request that is made.
*/
void
registerAdjacencyPrefixes(const Adjacent& adj,
const ndn::time::milliseconds& timeout);
registerAdjacencyPrefixes(const Adjacent& adj, ndn::time::milliseconds timeout);
/*! \brief Add a certificate NLSR claims to be authoritative for to the certificate store.
*
* \sa CertificateStore
/*! \brief Registers the prefix
*/
void
loadCertToPublish(const ndn::security::v2::Certificate& certificate);
void
connectToFetcher(ndn::util::SegmentFetcher& fetcher);
/*! \brief Callback when SegmentFetcher retrieves a segment.
*/
void
afterFetcherSignalEmitted(const ndn::Data& lsaSegment);
/*! \brief Retrieves the chain of certificates from Validator's cache and
* store them in Nlsr's own CertificateStore.
* \param keyName Name of the first key in the certificate chain.
*/
void
publishCertFromCache(const ndn::Name& keyName);
void
initializeKey();
void
loadValidator(boost::property_tree::ptree section,
const std::string& filename)
{
m_validator.load(section, filename);
}
ndn::security::ValidatorConfig&
getValidator()
{
return m_validator;
}
/*! \brief Find a certificate
*
* Find a certificate that NLSR has. First it checks against the
* certificates this NLSR claims to be authoritative for, usually
* something like this specific router's certificate, and then
* checks the cache of certficates it has already fetched. If none
* can be found, it will return an empty pointer.
*/
const ndn::security::v2::Certificate*
getCertificate(const ndn::Name& certificateKeyName)
{
const ndn::security::v2::Certificate* cert =
m_certStore.find(certificateKeyName);
return cert;
}
ndn::security::v2::KeyChain&
getKeyChain()
{
return m_keyChain;
}
const ndn::Name&
getDefaultCertName()
{
return m_defaultCertName;
}
const ndn::security::SigningInfo&
getSigningInfo()
{
return m_signingInfo;
}
update::PrefixUpdateProcessor&
getPrefixUpdateProcessor()
{
return m_prefixUpdateProcessor;
}
update::NfdRibCommandProcessor&
getNfdRibCommandProcessor()
{
return m_nfdRibCommandProcessor;
}
ndn::mgmt::Dispatcher&
getDispatcher()
{
return m_dispatcher;
}
void
setStrategies();
uint32_t
getFirstHelloInterval() const
{
return m_firstHelloInterval;
}
/*! \brief Canonize the URI for this and all proceeding neighbors in a list.
*
* This function canonizes the URI of the Adjacent object pointed to
* by currentNeighbor. It then executes the then callback, providing
* the next iterator in the list to the callback. A standard
* invocation would be to pass the begin() iterator of NLSR's
* adjacency list, and to provide Nlsr::canonizeContinuation as the
* callback. Because every URI must be canonical before we begin
* operations, the canonize function provides a finally() function
* to resume whatever needs to occur.
*
* \sa Nlsr::canonizeContinuation
* \sa Nlsr::initialize
* \sa NlsrRunner::run
*/
void
canonizeNeighborUris(std::list<Adjacent>::iterator currentNeighbor,
std::function<void(std::list<Adjacent>::iterator)> then,
std::function<void(void)> finally);
StatsCollector&
getStatsCollector()
{
return m_statsCollector;
}
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
security::CertificateStore&
getCertificateStore()
{
return m_certStore;
}
private:
/*! \brief Registers the prefix that NLSR will use for key/certificate interests.
*/
void
registerKeyPrefix();
/*! \brief Registers the prefix that NLSR will consider to be the machine-local, secure prefix.
*/
void
registerLocalhostPrefix();
/*! \brief Attempts to satisfy an Interest for a certificate, and send it back.
*/
void
onKeyInterest(const ndn::Name& name, const ndn::Interest& interest);
/*! \brief Do nothing.
*/
void
onKeyPrefixRegSuccess(const ndn::Name& name);
registerPrefix(const ndn::Name& prefix);
/*! \brief Do nothing.
*/
void
onFaceEventNotification(const ndn::nfd::FaceEventNotification& faceEventNotification);
void
setFirstHelloInterval(uint32_t interval)
{
m_firstHelloInterval = interval;
}
/*! \brief Continues canonizing neighbor URIs.
*
* For testability reasons, we want what each instance of
* canonization does after completion to be controllable. The best
* way to do this is to control that by simply passing a
* continuation function.
*/
void
canonizeContinuation(std::list<Adjacent>::iterator iterator,
std::function<void(void)> finally);
void
scheduleDatasetFetch();
@@ -481,60 +157,49 @@ private:
void
enableIncomingFaceIdIndication();
void
onFaceIdIndicationSuccess(const ndn::nfd::ControlParameters& cp);
void
onFaceIdIndicationFailure(const ndn::nfd::ControlResponse& cr);
public:
static const ndn::Name LOCALHOST_PREFIX;
static inline const ndn::Name LOCALHOST_PREFIX{"/localhost/nlsr"};
private:
ndn::Face& m_nlsrFace;
ndn::Scheduler& m_scheduler;
ndn::security::v2::KeyChain& m_keyChain;
ConfParameter m_confParam;
AdjacencyList m_adjacencyList;
NamePrefixList m_namePrefixList;
std::string m_configFileName;
Lsdb m_nlsrLsdb;
int64_t m_adjBuildCount;
bool m_isBuildAdjLsaSheduled;
bool m_isRouteCalculationScheduled;
bool m_isRoutingTableCalculating;
RoutingTable m_routingTable;
Fib m_fib;
NamePrefixTable m_namePrefixTable;
ndn::mgmt::Dispatcher m_dispatcher;
DatasetInterestHandler m_datasetHandler;
ndn::Face& m_face;
ndn::Scheduler m_scheduler;
ConfParameter& m_confParam;
AdjacencyList& m_adjacencyList;
NamePrefixList& m_namePrefixList;
std::vector<ndn::Name> m_strategySetOnRouters;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Fib m_fib;
Lsdb m_lsdb;
RoutingTable m_routingTable;
NamePrefixTable m_namePrefixTable;
HelloProtocol m_helloProtocol;
ndn::security::ValidatorConfig m_validator;
private:
ndn::signal::ScopedConnection m_onNewLsaConnection;
ndn::signal::ScopedConnection m_onPrefixRegistrationSuccess;
ndn::signal::ScopedConnection m_onInitialHelloDataValidated;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
ndn::mgmt::Dispatcher m_dispatcher;
DatasetInterestHandler m_datasetHandler;
private:
/*! \brief Where NLSR stores certificates it claims to be
* authoritative for. Usually the router certificate.
*/
security::CertificateStore m_certStore;
ndn::nfd::Controller m_controller;
ndn::nfd::Controller m_faceDatasetController;
ndn::security::SigningInfo m_signingInfo;
ndn::Name m_defaultCertName;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
update::PrefixUpdateProcessor m_prefixUpdateProcessor;
update::NfdRibCommandProcessor m_nfdRibCommandProcessor;
StatsCollector m_statsCollector;
private:
ndn::nfd::FaceMonitor m_faceMonitor;
uint32_t m_firstHelloInterval;
friend class NlsrRunner;
};
} // namespace nlsr
+22 -210
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,11 +17,10 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "dataset-interest-handler.hpp"
#include "nlsr.hpp"
#include "tlv/lsdb-status.hpp"
#include "logger.hpp"
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
@@ -31,238 +30,51 @@ namespace nlsr {
INIT_LOGGER(DatasetInterestHandler);
const ndn::PartialName ADJACENCIES_DATASET = ndn::PartialName("lsdb/adjacencies");
const ndn::PartialName COORDINATES_DATASET = ndn::PartialName("lsdb/coordinates");
const ndn::PartialName NAMES_DATASET = ndn::PartialName("lsdb/names");
const ndn::PartialName RT_DATASET = ndn::PartialName("routing-table");
const ndn::PartialName ADJACENCIES_DATASET{"lsdb/adjacencies"};
const ndn::PartialName COORDINATES_DATASET{"lsdb/coordinates"};
const ndn::PartialName NAMES_DATASET{"lsdb/names"};
const ndn::PartialName RT_DATASET{"routing-table"};
DatasetInterestHandler::DatasetInterestHandler(const Lsdb& lsdb,
const RoutingTable& rt,
ndn::mgmt::Dispatcher& dispatcher,
const ndn::Face& face,
const ndn::KeyChain& keyChain)
DatasetInterestHandler::DatasetInterestHandler(ndn::mgmt::Dispatcher& dispatcher,
const Lsdb& lsdb,
const RoutingTable& rt)
: m_lsdb(lsdb)
, m_dispatcher(dispatcher)
, m_routingTableEntries(rt.getRoutingTableEntry())
, m_dryRoutingTableEntries(rt.getDryRoutingTableEntry())
{
setDispatcher(m_dispatcher);
}
void
DatasetInterestHandler::setDispatcher(ndn::mgmt::Dispatcher& dispatcher)
, m_routingTable(rt)
{
dispatcher.addStatusDataset(ADJACENCIES_DATASET,
ndn::mgmt::makeAcceptAllAuthorization(),
std::bind(&DatasetInterestHandler::publishAdjStatus, this, _1, _2, _3));
std::bind(&DatasetInterestHandler::publishLsaStatus<AdjLsa>, this, _1, _2, _3));
dispatcher.addStatusDataset(COORDINATES_DATASET,
ndn::mgmt::makeAcceptAllAuthorization(),
std::bind(&DatasetInterestHandler::publishCoordinateStatus, this, _1, _2, _3));
std::bind(&DatasetInterestHandler::publishLsaStatus<CoordinateLsa>, this, _1, _2, _3));
dispatcher.addStatusDataset(NAMES_DATASET,
ndn::mgmt::makeAcceptAllAuthorization(),
std::bind(&DatasetInterestHandler::publishNameStatus, this, _1, _2, _3));
std::bind(&DatasetInterestHandler::publishLsaStatus<NameLsa>, this, _1, _2, _3));
dispatcher.addStatusDataset(RT_DATASET,
ndn::mgmt::makeAcceptAllAuthorization(),
std::bind(&DatasetInterestHandler::publishRtStatus, this, _1, _2, _3));
}
template <typename T>
void
DatasetInterestHandler::publishAdjStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
DatasetInterestHandler::publishLsaStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
ndn::mgmt::StatusDatasetContext& context)
{
NLSR_LOG_DEBUG("Received interest: " << interest);
auto lsaRange = std::make_pair<std::list<AdjLsa>::const_iterator,
std::list<AdjLsa>::const_iterator>(
m_lsdb.getAdjLsdb().cbegin(), m_lsdb.getAdjLsdb().cend());
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
tlv::AdjacencyLsa tlvLsa;
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
tlvLsa.setLsaInfo(*tlvLsaInfo);
for (const Adjacent& adj : lsa->getAdl().getAdjList()) {
tlv::Adjacency tlvAdj;
tlvAdj.setName(adj.getName());
tlvAdj.setUri(adj.getFaceUri().toString());
tlvAdj.setCost(adj.getLinkCost());
tlvLsa.addAdjacency(tlvAdj);
}
const ndn::Block& wire = tlvLsa.wireEncode();
context.append(wire);
NLSR_LOG_TRACE("Received interest: " << interest);
auto lsaRange = m_lsdb.getLsdbIterator<T>();
for (auto lsaIt = lsaRange.first; lsaIt != lsaRange.second; ++lsaIt) {
context.append((*lsaIt)->wireEncode());
}
context.end();
}
void
DatasetInterestHandler::publishCoordinateStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
ndn::mgmt::StatusDatasetContext& context)
{
auto lsaRange = std::make_pair<std::list<CoordinateLsa>::const_iterator,
std::list<CoordinateLsa>::const_iterator>(
m_lsdb.getCoordinateLsdb().cbegin(), m_lsdb.getCoordinateLsdb().cend());
NLSR_LOG_DEBUG("Received interest: " << interest);
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
tlv::CoordinateLsa tlvLsa;
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
tlvLsa.setLsaInfo(*tlvLsaInfo);
tlvLsa.setHyperbolicRadius(lsa->getCorRadius());
tlvLsa.setHyperbolicAngle(lsa->getCorTheta());
const ndn::Block& wire = tlvLsa.wireEncode();
context.append(wire);
}
context.end();
}
void
DatasetInterestHandler::publishNameStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
ndn::mgmt::StatusDatasetContext& context)
{
auto lsaRange = std::make_pair<std::list<NameLsa>::const_iterator, std::list<NameLsa>::const_iterator>(
m_lsdb.getNameLsdb().cbegin(), m_lsdb.getNameLsdb().cend());
NLSR_LOG_DEBUG("Received interest: " << interest);
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
tlv::NameLsa tlvLsa;
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
tlvLsa.setLsaInfo(*tlvLsaInfo);
for (const ndn::Name& name : lsa->getNpl().getNames()) {
tlvLsa.addName(name);
}
const ndn::Block& wire = tlvLsa.wireEncode();
context.append(wire);
}
context.end();
}
std::vector<tlv::RoutingTable>
DatasetInterestHandler::getTlvRTEntries()
{
std::vector<tlv::RoutingTable> rtable;
for (const auto& rte : m_routingTableEntries) {
tlv::RoutingTable tlvRoutingTable;
std::shared_ptr<tlv::Destination> tlvDes = tlv::makeDes(rte);
tlvRoutingTable.setDestination(*tlvDes);
for (const auto& nh : rte.getNexthopList().getNextHops()) {
tlv::NextHop tlvNexthop;
tlvNexthop.setUri(nh.getConnectingFaceUri());
tlvNexthop.setCost(nh.getRouteCost());
tlvRoutingTable.addNexthops(tlvNexthop);
}
rtable.push_back(tlvRoutingTable);
}
if (!m_dryRoutingTableEntries.empty()) {
for (const auto& dryRte : m_dryRoutingTableEntries) {
tlv::RoutingTable tlvRoutingTable;
std::shared_ptr<tlv::Destination> tlvDes = tlv::makeDes(dryRte);
tlvRoutingTable.setDestination(*tlvDes);
for (const auto& nh : dryRte.getNexthopList().getNextHops()) {
tlv::NextHop tlvNexthop;
tlvNexthop.setUri(nh.getConnectingFaceUri());
tlvNexthop.setCost(nh.getRouteCost());
tlvRoutingTable.addNexthops(tlvNexthop);
}
rtable.push_back(tlvRoutingTable);
}
}
return rtable;
}
void
DatasetInterestHandler::publishRtStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
ndn::mgmt::StatusDatasetContext& context)
{
NLSR_LOG_DEBUG("Received interest: " << interest);
tlv::RoutingTableStatus rtStatus;
for (const tlv::RoutingTable& rt : getTlvRTEntries()) {
rtStatus.addRoutingTable(rt);
}
const ndn::Block& wire = rtStatus.wireEncode();
context.append(wire);
NLSR_LOG_TRACE("Received interest: " << interest);
context.append(m_routingTable.wireEncode());
context.end();
}
template<> std::list<tlv::AdjacencyLsa>
getTlvLsas<tlv::AdjacencyLsa>(const Lsdb& lsdb)
{
std::list<tlv::AdjacencyLsa> lsas;
auto lsaRange = std::make_pair<std::list<AdjLsa>::const_iterator,
std::list<AdjLsa>::const_iterator>(
lsdb.getAdjLsdb().cbegin(), lsdb.getAdjLsdb().cend());
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
tlv::AdjacencyLsa tlvLsa;
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
tlvLsa.setLsaInfo(*tlvLsaInfo);
for (const Adjacent& adj : lsa->getAdl().getAdjList()) {
tlv::Adjacency tlvAdj;
tlvAdj.setName(adj.getName());
tlvAdj.setUri(adj.getFaceUri().toString());
tlvAdj.setCost(adj.getLinkCost());
tlvLsa.addAdjacency(tlvAdj);
}
lsas.push_back(tlvLsa);
}
return lsas;
}
template<> std::list<tlv::CoordinateLsa>
getTlvLsas<tlv::CoordinateLsa>(const Lsdb& lsdb)
{
std::list<tlv::CoordinateLsa> lsas;
auto lsaRange = std::make_pair<std::list<CoordinateLsa>::const_iterator,
std::list<CoordinateLsa>::const_iterator>(
lsdb.getCoordinateLsdb().cbegin(), lsdb.getCoordinateLsdb().cend());
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
tlv::CoordinateLsa tlvLsa;
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
tlvLsa.setLsaInfo(*tlvLsaInfo);
tlvLsa.setHyperbolicRadius(lsa->getCorRadius());
tlvLsa.setHyperbolicAngle(lsa->getCorTheta());
lsas.push_back(tlvLsa);
}
return lsas;
}
template<> std::list<tlv::NameLsa>
getTlvLsas<tlv::NameLsa>(const Lsdb& lsdb)
{
std::list<tlv::NameLsa> lsas;
auto lsaRange = std::make_pair<std::list<NameLsa>::const_iterator,
std::list<NameLsa>::const_iterator>(
lsdb.getNameLsdb().cbegin(), lsdb.getNameLsdb().cend());
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
tlv::NameLsa tlvLsa;
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
tlvLsa.setLsaInfo(*tlvLsaInfo);
for (const ndn::Name& name : lsa->getNpl().getNames()) {
tlvLsa.addName(name);
}
lsas.push_back(tlvLsa);
}
return lsas;
}
} // namespace nlsr
+16 -78
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,7 +17,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
/*! \file dataset-interest-handler.hpp
@@ -35,23 +35,17 @@
#include "route/routing-table.hpp"
#include "route/nexthop-list.hpp"
#include "lsdb.hpp"
#include "logger.hpp"
#include "tlv/adjacency-lsa.hpp"
#include "tlv/coordinate-lsa.hpp"
#include "tlv/name-lsa.hpp"
#include "tlv/routing-table-status.hpp"
#include "tlv/routing-table-entry.hpp"
#include <ndn-cxx/mgmt/dispatcher.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/mgmt/dispatcher.hpp>
#include <boost/noncopyable.hpp>
namespace nlsr {
namespace dataset {
const ndn::Name::Component ADJACENCY_COMPONENT = ndn::Name::Component{"adjacencies"};
const ndn::Name::Component NAME_COMPONENT = ndn::Name::Component{"names"};
const ndn::Name::Component COORDINATE_COMPONENT = ndn::Name::Component{"coordinates"};
inline const ndn::Name::Component ADJACENCY_COMPONENT{"adjacencies"};
inline const ndn::Name::Component NAME_COMPONENT{"names"};
inline const ndn::Name::Component COORDINATE_COMPONENT{"coordinates"};
} // namespace dataset
/*!
@@ -65,88 +59,32 @@ public:
class Error : std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
using std::runtime_error::runtime_error;
};
DatasetInterestHandler(const Lsdb& lsdb,
const RoutingTable& rt,
ndn::mgmt::Dispatcher& dispatcher,
const ndn::Face& face,
const ndn::KeyChain& keyChain);
ndn::Name&
getRouterNameCommandPrefix()
{
return m_routerNamePrefix;
}
void
setRouterNameCommandPrefix(const ndn::Name& routerName) {
m_routerNamePrefix = routerName;
m_routerNamePrefix.append(Lsdb::NAME_COMPONENT);
}
DatasetInterestHandler(ndn::mgmt::Dispatcher& dispatcher,
const Lsdb& lsdb,
const RoutingTable& rt);
private:
/*! \brief set dispatcher for localhost or remote router
*/
void
setDispatcher(ndn::mgmt::Dispatcher& dispatcher);
/*! \brief generate a TLV-format of routing table entry
*/
std::vector<tlv::RoutingTable>
getTlvRTEntries();
/*! \brief provide routing-table dataset
*/
void
publishRtStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
ndn::mgmt::StatusDatasetContext& context);
/*! \brief provide adjacent status dataset
/*! \brief provide LSA status dataset
*/
template<typename T>
void
publishAdjStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
publishLsaStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
ndn::mgmt::StatusDatasetContext& context);
/*! \brief provide coordinate status dataset
*/
void
publishCoordinateStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
ndn::mgmt::StatusDatasetContext& context);
/*! \brief provide name status dataset
*/
void
publishNameStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
ndn::mgmt::StatusDatasetContext& context);
private:
const Lsdb& m_lsdb;
ndn::Name m_routerNamePrefix;
ndn::mgmt::Dispatcher& m_dispatcher;
const std::list<RoutingTableEntry>& m_routingTableEntries;
const std::list<RoutingTableEntry>& m_dryRoutingTableEntries;
const RoutingTable& m_routingTable;
};
template<typename T> std::list<T>
getTlvLsas(const Lsdb& lsdb);
template<> std::list<tlv::AdjacencyLsa>
getTlvLsas<tlv::AdjacencyLsa>(const Lsdb& lsdb);
template<> std::list<tlv::CoordinateLsa>
getTlvLsas<tlv::CoordinateLsa>(const Lsdb& lsdb);
template<> std::list<tlv::NameLsa>
getTlvLsas<tlv::NameLsa>(const Lsdb& lsdb);
} // namespace nlsr
#endif // NLSR_PUBLISHER_DATASET_INTEREST_HANDLER_HPP
-141
View File
@@ -1,141 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, 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 NLSR_PUBLISHER_SEGMENT_PUBLISHER_HPP
#define NLSR_PUBLISHER_SEGMENT_PUBLISHER_HPP
#include <ndn-cxx/encoding/encoding-buffer.hpp>
#include <ndn-cxx/security/key-chain.hpp>
namespace nlsr {
/*! \brief provides a publisher of Status Dataset or other segmented octet stream
\sa https://redmine.named-data.net/projects/nfd/wiki/StatusDataset
*/
template <class FaceBase>
class SegmentPublisher : boost::noncopyable
{
public:
SegmentPublisher(FaceBase& face,
ndn::KeyChain& keyChain,
const ndn::security::SigningInfo& signingInfo,
const ndn::time::milliseconds& freshnessPeriod = getDefaultFreshness())
: m_face(face)
, m_keyChain(keyChain)
, m_signingInfo(signingInfo)
, m_freshnessPeriod(freshnessPeriod)
{
}
virtual
~SegmentPublisher()
{
}
/*! \brief Define the max segment size as half the max NDN packet size.
*/
static size_t
getMaxSegmentSize()
{
static const size_t MAX_SEGMENT_SIZE = ndn::MAX_NDN_PACKET_SIZE >> 1;
return MAX_SEGMENT_SIZE;
}
static constexpr ndn::time::milliseconds
getDefaultFreshness()
{
return ndn::time::milliseconds(1000);
}
/*! \brief Publish data under the provided prefix
*
* Processes whatever is provided from SegmentPublisher::generate,
* by breaking it into segments of MAX_SEGMENT_SIZE and sending each
* one individually. The last segment is distinguished by having the
* final block ID set to a timestamp.
*/
void
publish(const ndn::Name& prefix)
{
ndn::EncodingBuffer buffer;
generate(buffer);
const uint8_t* rawBuffer = buffer.buf();
const uint8_t* segmentBegin = rawBuffer;
const uint8_t* end = rawBuffer + buffer.size();
ndn::Name segmentPrefix(prefix);
segmentPrefix.appendVersion();
uint64_t segmentNo = 0;
do {
const uint8_t* segmentEnd = segmentBegin + getMaxSegmentSize();
if (segmentEnd > end) {
segmentEnd = end;
}
ndn::Name segmentName(segmentPrefix);
segmentName.appendSegment(segmentNo);
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(segmentName);
data->setContent(segmentBegin, segmentEnd - segmentBegin);
data->setFreshnessPeriod(m_freshnessPeriod);
segmentBegin = segmentEnd;
if (segmentBegin >= end) {
data->setFinalBlockId(segmentName[-1]);
}
publishSegment(data);
++segmentNo;
} while (segmentBegin < end);
}
protected:
/*! \brief In a derived class, write the octets into outBuffer.
*/
virtual size_t
generate(ndn::EncodingBuffer& outBuffer) = 0;
private:
/*! \brief Helper function to sign and put data on a Face.
*/
void
publishSegment(std::shared_ptr<ndn::Data>& data)
{
m_keyChain.sign(*data, m_signingInfo);
m_face.put(*data);
}
private:
FaceBase& m_face;
ndn::KeyChain& m_keyChain;
const ndn::security::SigningInfo& m_signingInfo;
const ndn::time::milliseconds m_freshnessPeriod;
};
} // namespace nlsr
#endif // NLSR_PUBLISHER_SEGMENT_PUBLISHER_HPP
-44
View File
@@ -1,44 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
* \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
*
**/
#include "face-map.hpp"
#include "common.hpp"
#include "logger.hpp"
#include <iostream>
#include <utility>
namespace nlsr {
INIT_LOGGER(route.FaceMap);
void
FaceMap::writeLog()
{
NLSR_LOG_DEBUG("------- Face Map-----------");
for (const auto& it : m_table) {
NLSR_LOG_DEBUG("Face Map Entry (FaceUri: " << (it.second).getFaceUri()
<< " Face Id: " << (it.second).getFaceId() << ")");
}
}
} // namespace nlsr
-121
View File
@@ -1,121 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
**/
#ifndef NLSR_FACE_MAP_HPP
#define NLSR_FACE_MAP_HPP
#include "common.hpp"
#include <map>
namespace nlsr {
class FaceMapEntry
{
public:
FaceMapEntry(const std::string& faceUri, uint32_t faceId)
: m_faceUri(faceUri)
, m_faceId(faceId)
{
}
void
setFaceUri(const std::string& faceUri)
{
m_faceUri = faceUri;
}
const std::string&
getFaceUri() const
{
return m_faceUri;
}
void
setFaceId(uint32_t faceId)
{
m_faceId = faceId;
}
uint32_t
getFaceId() const
{
return m_faceId;
}
bool
compare(const FaceMapEntry& fme)
{
return m_faceUri == fme.getFaceUri();
}
private:
std::string m_faceUri;
uint32_t m_faceId;
};
class FaceMap
{
public:
FaceMap()
{
}
~FaceMap()
{
}
inline void
update(const std::string& faceUri, uint32_t faceId)
{
FaceMapEntry fme(faceUri, faceId);
std::map<std::string, FaceMapEntry>::iterator it = m_table.find(faceUri);
if (it == m_table.end()) {
m_table.emplace(faceUri, fme);
}
else {
(it->second).setFaceId(fme.getFaceId());
}
}
inline uint32_t
getFaceId(const std::string& faceUri)
{
FaceMapEntry fme(faceUri, 0);
std::map<std::string, FaceMapEntry>::iterator it = m_table.find(faceUri);
if (it != m_table.end()) {
return (it->second).getFaceId();
}
return 0;
}
void
writeLog();
private:
std::map<std::string, FaceMapEntry> m_table;
};
} // namespace nlsr
#endif // NLSR_FACE_MAP_HPP
-115
View File
@@ -1,115 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NLSR_FIB_ENTRY_HPP
#define NLSR_FIB_ENTRY_HPP
#include <ndn-cxx/util/scheduler.hpp>
#include "nexthop-list.hpp"
namespace nlsr {
class FibEntry
{
public:
FibEntry()
: m_name()
, m_seqNo(1)
, m_nexthopList()
{
}
FibEntry(const ndn::Name& name)
: m_seqNo(1)
, m_nexthopList()
{
m_name = name;
}
const ndn::Name&
getName() const
{
return m_name;
}
NexthopList&
getNexthopList()
{
return m_nexthopList;
}
void
setRefreshEventId(ndn::EventId id)
{
m_refreshEventId = id;
}
ndn::EventId
getRefreshEventId() const
{
return m_refreshEventId;
}
void
setSeqNo(int32_t fsn)
{
m_seqNo = fsn;
}
int32_t
getSeqNo() const
{
return m_seqNo;
}
void
writeLog();
typedef NexthopList::const_iterator const_iterator;
const_iterator
begin() const;
const_iterator
end() const;
private:
ndn::Name m_name;
ndn::EventId m_refreshEventId;
int32_t m_seqNo;
NexthopList m_nexthopList;
};
inline FibEntry::const_iterator
FibEntry::begin() const
{
return m_nexthopList.cbegin();
}
inline FibEntry::const_iterator
FibEntry::end() const
{
return m_nexthopList.cend();
}
} // namespace nlsr
#endif // NLSR_FIB_ENTRY_HPP
+124 -173
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
@@ -16,7 +16,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "fib.hpp"
#include "adjacency-list.hpp"
@@ -24,51 +24,56 @@
#include "logger.hpp"
#include "nexthop-list.hpp"
#include <map>
#include <cmath>
#include <algorithm>
#include <iterator>
#include <cmath>
#include <map>
namespace nlsr {
INIT_LOGGER(route.Fib);
const uint64_t Fib::GRACE_PERIOD = 10;
Fib::Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList,
ConfParameter& conf, ndn::security::KeyChain& keyChain)
: m_scheduler(scheduler)
, m_refreshTime(2 * conf.getLsaRefreshTime())
, m_controller(face, keyChain)
, m_adjacencyList(adjacencyList)
, m_confParameter(conf)
{
}
void
Fib::remove(const ndn::Name& name)
{
NLSR_LOG_DEBUG("Fib::remove called");
std::map<ndn::Name, FibEntry>::iterator it = m_table.find(name);
if (it != m_table.end()) {
for (std::set<NextHop, NextHopComparator>::iterator nhit =
(it->second).getNexthopList().getNextHops().begin();
nhit != (it->second).getNexthopList().getNextHops().end(); nhit++) {
//remove entry from NDN-FIB
// Only unregister the prefix if it ISN'T a neighbor.
if (isPrefixUpdatable((it->second).getName())) {
unregisterPrefix((it->second).getName(), nhit->getConnectingFaceUri());
}
auto it = m_table.find(name);
// Only unregister the prefix if it ISN'T a neighbor.
if (it != m_table.end() && isNotNeighbor((it->second).name)) {
for (const auto& nexthop : (it->second).nexthopSet) {
unregisterPrefix((it->second).name, nexthop.getConnectingFaceUri());
}
cancelEntryRefresh(it->second);
m_table.erase(it);
}
}
void
Fib::addNextHopsToFibEntryAndNfd(FibEntry& entry, NexthopList& hopsToAdd)
Fib::addNextHopsToFibEntryAndNfd(FibEntry& entry, const NextHopsUriSortedSet& hopsToAdd)
{
const ndn::Name& name = entry.getName();
const ndn::Name& name = entry.name;
for (NexthopList::iterator it = hopsToAdd.begin(); it != hopsToAdd.end(); ++it)
bool shouldRegister = isNotNeighbor(name);
for (const auto& hop : hopsToAdd)
{
// Add nexthop to FIB entry
entry.getNexthopList().addNextHop(*it);
NLSR_LOG_DEBUG("Adding " << hop.getConnectingFaceUri() << " to " << entry.name);
entry.nexthopSet.addNextHop(hop);
if (isPrefixUpdatable(name)) {
if (shouldRegister) {
// Add nexthop to NDN-FIB
registerPrefix(name, ndn::FaceUri(it->getConnectingFaceUri()),
it->getRouteCostAsAdjustedInteger(),
registerPrefix(name, ndn::FaceUri(hop.getConnectingFaceUri()),
hop.getRouteCostAsAdjustedInteger(),
ndn::time::seconds(m_refreshTime + GRACE_PERIOD),
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
}
@@ -76,36 +81,33 @@ Fib::addNextHopsToFibEntryAndNfd(FibEntry& entry, NexthopList& hopsToAdd)
}
void
Fib::update(const ndn::Name& name, NexthopList& allHops)
Fib::update(const ndn::Name& name, const NexthopList& allHops)
{
NLSR_LOG_DEBUG("Fib::update called");
// Get the max possible faces which is the minumum of the configuration setting and
// Get the max possible faces which is the minimum of the configuration setting and
// the length of the list of all next hops.
unsigned int maxFaces = getNumberOfFacesForName(allHops);
NexthopList hopsToAdd;
NextHopsUriSortedSet hopsToAdd;
unsigned int nFaces = 0;
// Create a list of next hops to be installed with length == maxFaces
for (NexthopList::iterator it = allHops.begin(); it != allHops.end() && nFaces < maxFaces;
++it, ++nFaces) {
for (auto it = allHops.cbegin(); it != allHops.cend() && nFaces < maxFaces; ++it, ++nFaces) {
hopsToAdd.addNextHop(*it);
}
std::map<ndn::Name, FibEntry>::iterator entryIt = m_table.find(name);
auto entryIt = m_table.find(name);
// New FIB entry that has nextHops
if (entryIt == m_table.end() && hopsToAdd.size() != 0) {
NLSR_LOG_DEBUG("New FIB Entry");
FibEntry entry(name);
FibEntry entry;
entry.name = name;
addNextHopsToFibEntryAndNfd(entry, hopsToAdd);
m_table.emplace(name, entry);
entryIt = m_table.find(name);
entryIt = m_table.try_emplace(name, std::move(entry)).first;
}
// Existing FIB entry that may or may not have nextHops
else {
@@ -118,92 +120,72 @@ Fib::update(const ndn::Name& name, NexthopList& allHops)
return;
}
FibEntry& entry = (entryIt->second);
FibEntry& entry = entryIt->second;
addNextHopsToFibEntryAndNfd(entry, hopsToAdd);
std::set<NextHop, NextHopComparator> hopsToRemove;
std::set_difference(entry.getNexthopList().begin(), entry.getNexthopList().end(),
std::set<NextHop, NextHopUriSortedComparator> hopsToRemove;
std::set_difference(entry.nexthopSet.begin(), entry.nexthopSet.end(),
hopsToAdd.begin(), hopsToAdd.end(),
std::inserter(hopsToRemove, hopsToRemove.end()), NextHopComparator());
std::inserter(hopsToRemove, hopsToRemove.begin()),
NextHopUriSortedComparator());
bool isUpdatable = isPrefixUpdatable(entry.getName());
bool isUpdatable = isNotNeighbor(entry.name);
// Remove the uninstalled next hops from NFD and FIB entry
for (const auto& hop: hopsToRemove){
for (const auto& hop : hopsToRemove){
if (isUpdatable) {
unregisterPrefix(entry.getName(), hop.getConnectingFaceUri());
unregisterPrefix(entry.name, hop.getConnectingFaceUri());
}
NLSR_LOG_DEBUG("Removing " << hop.getConnectingFaceUri() << " from " << entry.getName());
entry.getNexthopList().removeNextHop(hop);
NLSR_LOG_DEBUG("Removing " << hop.getConnectingFaceUri() << " from " << entry.name);
entry.nexthopSet.removeNextHop(hop);
}
// Increment sequence number
entry.setSeqNo(entry.getSeqNo() + 1);
entry.seqNo += 1;
entryIt = m_table.find(name);
}
if (entryIt != m_table.end() && !entryIt->second.getRefreshEventId()) {
scheduleEntryRefresh(entryIt->second,
[this] (FibEntry& entry) {
scheduleLoop(entry);
});
if (entryIt != m_table.end() &&
!entryIt->second.refreshEventId &&
isNotNeighbor(entryIt->second.name)) {
scheduleEntryRefresh(entryIt->second, [this] (FibEntry& entry) { scheduleLoop(entry); });
}
}
void
Fib::clean()
{
NLSR_LOG_DEBUG("Fib::clean called");
for (std::map<ndn::Name, FibEntry>::iterator it = m_table.begin();
it != m_table.end();
++it) {
NLSR_LOG_DEBUG("Cancelling Scheduled event. Name: " << it->second.getName());
cancelEntryRefresh(it->second);
for (std::set<NextHop, NextHopComparator>::iterator nhit =
(it->second).getNexthopList().getNextHops().begin();
nhit != (it->second).getNexthopList().getNextHops().end(); nhit++) {
//Remove entry from NDN-FIB
unregisterPrefix((it->second).getName(), nhit->getConnectingFaceUri());
NLSR_LOG_DEBUG("Clean called");
for (const auto& it : m_table) {
for (const auto& hop : it.second.nexthopSet) {
unregisterPrefix(it.second.name, hop.getConnectingFaceUri());
}
}
if (m_table.size() > 0) {
m_table.clear();
}
}
unsigned int
Fib::getNumberOfFacesForName(NexthopList& nextHopList)
Fib::getNumberOfFacesForName(const NexthopList& nextHopList)
{
uint32_t nNextHops = static_cast<uint32_t>(nextHopList.getNextHops().size());
uint32_t nMaxFaces = m_confParameter.getMaxFacesPerPrefix();
// Allow all faces
if (nMaxFaces == 0) {
return nNextHops;
}
else {
return std::min(nNextHops, nMaxFaces);
}
// 0 == all faces
return nMaxFaces == 0 ? nNextHops : std::min(nNextHops, nMaxFaces);
}
bool
Fib::isPrefixUpdatable(const ndn::Name& name) {
if (!m_adjacencyList.isNeighbor(name)) {
return true;
}
return false;
Fib::isNotNeighbor(const ndn::Name& name)
{
return !m_adjacencyList.isNeighbor(name);
}
void
Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri,
uint64_t faceCost,
const ndn::time::milliseconds& timeout,
uint64_t faceCost, const ndn::time::milliseconds& timeout,
uint64_t flags, uint8_t times)
{
uint64_t faceId = m_adjacencyList.getFaceId(ndn::FaceUri(faceUri));
uint64_t faceId = m_adjacencyList.getFaceId(faceUri);
if (faceId != 0) {
if (faceId > 0) {
ndn::nfd::ControlParameters faceParameters;
faceParameters
.setName(namePrefix)
@@ -215,14 +197,9 @@ Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri,
NLSR_LOG_DEBUG("Registering prefix: " << faceParameters.getName() << " faceUri: " << faceUri);
m_controller.start<ndn::nfd::RibRegisterCommand>(faceParameters,
std::bind(&Fib::onRegistrationSuccess, this, _1,
"Successful in name registration",
faceUri),
std::bind(&Fib::onRegistrationFailure,
this, _1,
"Failed in name registration",
faceParameters,
faceUri, times));
std::bind(&Fib::onRegistrationSuccess, this, _1, faceUri),
std::bind(&Fib::onRegistrationFailure, this, _1,
faceParameters, faceUri, times));
}
else {
NLSR_LOG_WARN("Error: No Face Id for face uri: " << faceUri);
@@ -230,31 +207,28 @@ Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri,
}
void
Fib::onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
const std::string& message, const ndn::FaceUri& faceUri)
Fib::onRegistrationSuccess(const ndn::nfd::ControlParameters& param,
const ndn::FaceUri& faceUri)
{
NLSR_LOG_DEBUG(message << ": " << commandSuccessResult.getName() <<
" Face Uri: " << faceUri << " faceId: " << commandSuccessResult.getFaceId());
NLSR_LOG_DEBUG("Successful in name registration: " << param.getName() <<
" Face Uri: " << faceUri << " faceId: " << param.getFaceId());
AdjacencyList::iterator adjacent = m_adjacencyList.findAdjacent(faceUri);
auto adjacent = m_adjacencyList.findAdjacent(faceUri);
if (adjacent != m_adjacencyList.end()) {
adjacent->setFaceId(commandSuccessResult.getFaceId());
adjacent->setFaceId(param.getFaceId());
}
// Update the fast-access FaceMap with the new Face ID, too
m_faceMap.update(faceUri.toString(), commandSuccessResult.getFaceId());
m_faceMap.writeLog();
onPrefixRegistrationSuccess(param.getName());
}
void
Fib::onRegistrationFailure(const ndn::nfd::ControlResponse& response,
const std::string& message,
const ndn::nfd::ControlParameters& parameters,
const ndn::FaceUri& faceUri,
uint8_t times)
{
NLSR_LOG_DEBUG(message << ": " << response.getText() << " (code: " << response.getCode() << ")");
NLSR_LOG_DEBUG("Prefix: " << parameters.getName() << " failed for: " << times);
NLSR_LOG_DEBUG("Failed in name registration: " << response.getText() <<
" (code: " << response.getCode() << ")");
NLSR_LOG_DEBUG("Prefix: " << parameters.getName() << " failed for: " << +times);
if (times < 3) {
NLSR_LOG_DEBUG("Trying to register again...");
registerPrefix(parameters.getName(), faceUri,
@@ -268,9 +242,14 @@ Fib::onRegistrationFailure(const ndn::nfd::ControlResponse& response,
}
void
Fib::unregisterPrefix(const ndn::Name& namePrefix, const std::string& faceUri)
Fib::unregisterPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri)
{
uint32_t faceId = m_faceMap.getFaceId(faceUri);
uint64_t faceId = 0;
auto adjacent = m_adjacencyList.findAdjacent(faceUri);
if (adjacent != m_adjacencyList.end()) {
faceId = adjacent->getFaceId();
}
NLSR_LOG_DEBUG("Unregister prefix: " << namePrefix << " Face Uri: " << faceUri);
if (faceId > 0) {
ndn::nfd::ControlParameters controlParameters;
@@ -278,32 +257,21 @@ Fib::unregisterPrefix(const ndn::Name& namePrefix, const std::string& faceUri)
.setName(namePrefix)
.setFaceId(faceId)
.setOrigin(ndn::nfd::ROUTE_ORIGIN_NLSR);
m_controller.start<ndn::nfd::RibUnregisterCommand>(controlParameters,
std::bind(&Fib::onUnregistrationSuccess, this, _1,
"Successful in unregistering name"),
std::bind(&Fib::onUnregistrationFailure,
this, _1,
"Failed in unregistering name"));
[] (const ndn::nfd::ControlParameters& commandSuccessResult) {
NLSR_LOG_DEBUG("Unregister successful Prefix: " << commandSuccessResult.getName() <<
" Face Id: " << commandSuccessResult.getFaceId());
},
[] (const ndn::nfd::ControlResponse& response) {
NLSR_LOG_DEBUG("Failed in unregistering name" << ": " << response.getText() <<
" (code: " << response.getCode() << ")");
});
}
}
void
Fib::onUnregistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
const std::string& message)
{
NLSR_LOG_DEBUG("Unregister successful Prefix: " << commandSuccessResult.getName() <<
" Face Id: " << commandSuccessResult.getFaceId());
}
void
Fib::onUnregistrationFailure(const ndn::nfd::ControlResponse& response,
const std::string& message)
{
NLSR_LOG_DEBUG(message << ": " << response.getText() << " (code: " << response.getCode() << ")");
}
void
Fib::setStrategy(const ndn::Name& name, const std::string& strategy, uint32_t count)
Fib::setStrategy(const ndn::Name& name, const ndn::Name& strategy, uint32_t count)
{
ndn::nfd::ControlParameters parameters;
parameters
@@ -311,80 +279,63 @@ Fib::setStrategy(const ndn::Name& name, const std::string& strategy, uint32_t co
.setStrategy(strategy);
m_controller.start<ndn::nfd::StrategyChoiceSetCommand>(parameters,
std::bind(&Fib::onSetStrategySuccess, this, _1,
"Successfully set strategy choice"),
std::bind(&Fib::onSetStrategySuccess, this, _1),
std::bind(&Fib::onSetStrategyFailure, this, _1,
parameters,
count,
"Failed to set strategy choice"));
parameters, count));
}
void
Fib::onSetStrategySuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
const std::string& message)
Fib::onSetStrategySuccess(const ndn::nfd::ControlParameters& commandSuccessResult)
{
NLSR_LOG_DEBUG(message << ": " << commandSuccessResult.getStrategy() << " "
<< "for name: " << commandSuccessResult.getName());
NLSR_LOG_DEBUG("Successfully set strategy choice: " << commandSuccessResult.getStrategy() <<
" for name: " << commandSuccessResult.getName());
}
void
Fib::onSetStrategyFailure(const ndn::nfd::ControlResponse& response,
const ndn::nfd::ControlParameters& parameters,
uint32_t count,
const std::string& message)
uint32_t count)
{
NLSR_LOG_DEBUG(message << ": " << parameters.getStrategy() << " "
<< "for name: " << parameters.getName());
NLSR_LOG_DEBUG("Failed to set strategy choice: " << parameters.getStrategy() <<
" for name: " << parameters.getName());
if (count < 3) {
setStrategy(parameters.getName(), parameters.getStrategy().toUri(),count+1);
setStrategy(parameters.getName(), parameters.getStrategy().toUri(), count + 1);
}
}
void
Fib::scheduleEntryRefresh(FibEntry& entry, const afterRefreshCallback& refreshCallback)
Fib::scheduleEntryRefresh(FibEntry& entry, const AfterRefreshCallback& refreshCallback)
{
NLSR_LOG_DEBUG("Scheduling refresh for " << entry.getName()
<< " Seq Num: " << entry.getSeqNo()
<< " in " << m_refreshTime << " seconds");
NLSR_LOG_DEBUG("Scheduling refresh for " << entry.name <<
" Seq Num: " << entry.seqNo <<
" in " << m_refreshTime << " seconds");
entry.setRefreshEventId(m_scheduler.scheduleEvent(ndn::time::seconds(m_refreshTime),
std::bind(&Fib::refreshEntry, this,
entry.getName(), refreshCallback)));
entry.refreshEventId = m_scheduler.schedule(ndn::time::seconds(m_refreshTime),
std::bind(&Fib::refreshEntry, this,
entry.name, refreshCallback));
}
void
Fib::scheduleLoop(FibEntry& entry)
{
scheduleEntryRefresh(entry,
std::bind(&Fib::scheduleLoop, this, _1));
scheduleEntryRefresh(entry, std::bind(&Fib::scheduleLoop, this, _1));
}
void
Fib::cancelEntryRefresh(const FibEntry& entry)
Fib::refreshEntry(const ndn::Name& name, AfterRefreshCallback refreshCb)
{
NLSR_LOG_DEBUG("Cancelling refresh for " << entry.getName() << " Seq Num: " << entry.getSeqNo());
m_scheduler.cancelEvent(entry.getRefreshEventId());
entry.getRefreshEventId().reset();
}
void
Fib::refreshEntry(const ndn::Name& name, afterRefreshCallback refreshCb)
{
std::map<ndn::Name, FibEntry>::iterator it = m_table.find(name);
auto it = m_table.find(name);
if (it == m_table.end()) {
return;
}
FibEntry& entry = it->second;
NLSR_LOG_DEBUG("Refreshing " << entry.getName() << " Seq Num: " << entry.getSeqNo());
NLSR_LOG_DEBUG("Refreshing " << entry.name << " Seq Num: " << entry.seqNo);
// Increment sequence number
entry.setSeqNo(entry.getSeqNo() + 1);
entry.seqNo += 1;
for (const NextHop& hop : entry) {
registerPrefix(entry.getName(),
for (const NextHop& hop : entry.nexthopSet) {
registerPrefix(entry.name,
ndn::FaceUri(hop.getConnectingFaceUri()),
hop.getRouteCostAsAdjustedInteger(),
ndn::time::seconds(m_refreshTime + GRACE_PERIOD),
@@ -398,10 +349,10 @@ void
Fib::writeLog()
{
NLSR_LOG_DEBUG("-------------------FIB-----------------------------");
for (std::map<ndn::Name, FibEntry>::iterator it = m_table.begin();
it != m_table.end();
++it) {
(it->second).writeLog();
for (const auto& entry : m_table) {
NLSR_LOG_DEBUG("Name prefix: " << entry.first);
NLSR_LOG_DEBUG("Seq No: " << entry.second.seqNo);
NLSR_LOG_DEBUG("Nexthop List: \n" << entry.second.nexthopSet);
}
}
+39 -63
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
/*
* Copyright (c) 2014-2023, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -17,26 +17,34 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
**/
*/
#ifndef NLSR_ROUTE_FIB_HPP
#define NLSR_ROUTE_FIB_HPP
#include "face-map.hpp"
#include "fib-entry.hpp"
#include "test-access-control.hpp"
#include "nexthop-list.hpp"
#include <ndn-cxx/mgmt/nfd/controller.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <ndn-cxx/util/time.hpp>
namespace nlsr {
typedef std::function<void(FibEntry&)> afterRefreshCallback;
using NextHopsUriSortedSet = NexthopListT<NextHopUriSortedComparator>;
struct FibEntry
{
ndn::Name name;
ndn::scheduler::ScopedEventId refreshEventId;
int32_t seqNo = 1;
NextHopsUriSortedSet nexthopSet;
};
using AfterRefreshCallback = std::function<void(FibEntry&)>;
class AdjacencyList;
class ConfParameter;
class FibEntry;
/*! \brief Maps names to lists of next hops, and exports this information to NFD.
*
@@ -54,15 +62,8 @@ class FibEntry;
class Fib
{
public:
Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList, ConfParameter& conf,
ndn::security::v2::KeyChain& keyChain)
: m_scheduler(scheduler)
, m_refreshTime(0)
, m_controller(face, keyChain)
, m_adjacencyList(adjacencyList)
, m_confParameter(conf)
{
}
Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList,
ConfParameter& conf, ndn::security::KeyChain& keyChain);
/*! \brief Completely remove a name prefix from the FIB.
*
@@ -72,7 +73,7 @@ public:
*
* \sa nlsr::NamePrefixTable::removeEntry
*/
VIRTUAL_WITH_TESTS void
void
remove(const ndn::Name& name);
/*! \brief Set the nexthop list of a name.
@@ -86,8 +87,8 @@ public:
* \param name The name prefix that the next-hops apply to
* \param allHops A complete list of next-hops to associate with name.
*/
VIRTUAL_WITH_TESTS void
update(const ndn::Name& name, NexthopList& allHops);
void
update(const ndn::Name& name, const NexthopList& allHops);
/*! \brief Remove all entries from the FIB.
*
@@ -96,9 +97,6 @@ public:
* strictly necessary, because eventually those prefix registrations
* will expire, but cleaning up after ourselves improves
* performance.
*
* \sa NlsrRunner::run
*
*/
void
clean();
@@ -138,7 +136,7 @@ public:
uint8_t times);
void
setStrategy(const ndn::Name& name, const std::string& strategy, uint32_t count);
setStrategy(const ndn::Name& name, const ndn::Name& strategy, uint32_t count);
void
writeLog();
@@ -149,7 +147,7 @@ private:
* \return Whether the name is NOT associated with a direct neighbor
*/
bool
isPrefixUpdatable(const ndn::Name& name);
isNotNeighbor(const ndn::Name& name);
/*! \brief Does one half of the updating of a FibEntry with new next-hops.
*
@@ -158,57 +156,42 @@ private:
* \sa Fib::removeOldNextHopsFromFibEntryAndNfd
*/
void
addNextHopsToFibEntryAndNfd(FibEntry& entry, NexthopList& hopsToAdd);
addNextHopsToFibEntryAndNfd(FibEntry& entry, const NextHopsUriSortedSet& hopsToAdd);
unsigned int
getNumberOfFacesForName(NexthopList& nextHopList);
getNumberOfFacesForName(const NexthopList& nextHopList);
/*! \brief Unregisters a prefix from NFD's RIB.
*
*/
void
unregisterPrefix(const ndn::Name& namePrefix, const std::string& faceUri);
unregisterPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri);
/*! \brief Log registration success, and update the Face ID associated with a URI.
*/
void
onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
const std::string& message, const ndn::FaceUri& faceUri);
onRegistrationSuccess(const ndn::nfd::ControlParameters& param,
const ndn::FaceUri& faceUri);
/*! \brief Retry a prefix (next-hop) registration up to three (3) times.
*/
void
onRegistrationFailure(const ndn::nfd::ControlResponse& response,
const std::string& message,
const ndn::nfd::ControlParameters& parameters,
const ndn::FaceUri& faceUri,
uint8_t times);
/*! \brief Log a successful unregistration.
*/
void
onUnregistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
const std::string& message);
/*! \brief Log an unregistration failure. Does not retry.
*/
void
onUnregistrationFailure(const ndn::nfd::ControlResponse& response,
const std::string& message);
/*! \brief Log a successful strategy setting.
*/
void
onSetStrategySuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
const std::string& message);
onSetStrategySuccess(const ndn::nfd::ControlParameters& commandSuccessResult);
/*! \brief Retry a strategy setting up to three (3) times.
*/
void
onSetStrategyFailure(const ndn::nfd::ControlResponse& response,
const ndn::nfd::ControlParameters& parameters,
uint32_t count,
const std::string& message);
uint32_t count);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/*! \brief Schedule a refresh event for an entry.
@@ -222,7 +205,7 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
* \sa Fib::scheduleLoop
*/
void
scheduleEntryRefresh(FibEntry& entry, const afterRefreshCallback& refreshCb);
scheduleEntryRefresh(FibEntry& entry, const AfterRefreshCallback& refreshCb);
private:
/*! \brief Continue the entry refresh cycle.
@@ -230,22 +213,16 @@ private:
void
scheduleLoop(FibEntry& entry);
/*! \brief Cancel an entry's refresh event.
*
* Cancel an entry's refresh event. This only needs to be done when
* an entry is removed. Typically this happens when NLSR is
* terminated or crashes, and we don't want the scheduler to crash
* because it's referencing memory that has no valid function.
*
* \sa NlsrRunner::run
*/
void
cancelEntryRefresh(const FibEntry& entry);
/*! \brief Refreshes an entry in NFD.
*/
void
refreshEntry(const ndn::Name& name, afterRefreshCallback refreshCb);
refreshEntry(const ndn::Name& name, AfterRefreshCallback refreshCb);
public:
static inline const ndn::Name MULTICAST_STRATEGY{"/localhost/nfd/strategy/multicast"};
static inline const ndn::Name BEST_ROUTE_STRATEGY{"/localhost/nfd/strategy/best-route"};
ndn::signal::Signal<Fib, ndn::Name> onPrefixRegistrationSuccess;
private:
ndn::Scheduler& m_scheduler;
@@ -253,7 +230,6 @@ private:
ndn::nfd::Controller m_controller;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
FaceMap m_faceMap;
std::map<ndn::Name, FibEntry> m_table;
private:
@@ -264,7 +240,7 @@ private:
* allow for things like stuttering prefix registrations and
* processing time when refreshing events.
*/
static const uint64_t GRACE_PERIOD;
static constexpr uint64_t GRACE_PERIOD = 10;
};
} // namespace nlsr
+14 -32
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, The University of Memphis,
/*
* Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
@@ -16,12 +16,12 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
*/
#include "map.hpp"
#include "nlsr.hpp"
#include "adjacent.hpp"
#include "lsa.hpp"
#include "lsa/lsa.hpp"
#include "lsdb.hpp"
#include "logger.hpp"
@@ -32,7 +32,7 @@ INIT_LOGGER(route.Map);
void
Map::addEntry(const ndn::Name& rtrName)
{
MapEntry me(rtrName, m_mappingIndex);
MapEntry me {rtrName, m_mappingIndex};
if (addEntry(me)) {
m_mappingIndex++;
}
@@ -44,47 +44,29 @@ Map::addEntry(MapEntry& mpe)
return m_entries.insert(mpe).second;
}
ndn::optional<ndn::Name>
std::optional<ndn::Name>
Map::getRouterNameByMappingNo(int32_t mn) const
{
auto&& mappingNumberView = m_entries.get<detail::byMappingNumber>();
auto iterator = mappingNumberView.find(mn);
if (iterator == mappingNumberView.end()) {
return {};
}
else {
return {iterator->getRouter()};
}
auto it = mappingNumberView.find(mn);
return it == mappingNumberView.end() ? std::nullopt : std::optional(it->router);
}
ndn::optional<int32_t>
std::optional<int32_t>
Map::getMappingNoByRouterName(const ndn::Name& rName)
{
auto&& routerNameView = m_entries.get<detail::byRouterName>();
auto iterator = routerNameView.find(rName);
if (iterator == routerNameView.end()) {
return {};
}
else {
return {iterator->getMappingNumber()};
}
}
void
Map::reset()
{
m_entries = detail::entryContainer{};
m_mappingIndex = 0;
auto it = routerNameView.find(rName);
return it == routerNameView.end() ? std::nullopt : std::optional(it->mappingNumber);
}
void
Map::writeLog()
{
NLSR_LOG_DEBUG("---------------Map----------------------");
auto&& routerNameView = m_entries.get<detail::byRouterName>();
for (auto entry = routerNameView.begin(); entry != routerNameView.end(); entry++) {
NLSR_LOG_DEBUG("MapEntry: ( Router: " << entry->getRouter() << " Mapping No: "
<< entry->getMappingNumber() << " )");
for (const auto& entry : m_entries.get<detail::byRouterName>()) {
NLSR_LOG_DEBUG("MapEntry: ( Router: " << entry.router << " Mapping No: " <<
entry.mappingNumber << " )");
}
}
Loaded 100 of 229 files, more files were not shown because too many files have changed in this diff. Show more