129 Commits
Author SHA1 Message Date
Ashlesh Gawande 39cf81a110 docs: Prepare version 0.4.1 release notes
Change-Id: I91db5b65dfe06187ddb0e9df32905dc2c8797ddc
2018-02-22 17:37:51 -06:00
Alexander Afanasyev b0bf8df1bd Hard-code fixed session name for ChronoSync sockets
This commit reverts behavior of the hard-coded fixed session name that
was feature in old nsync-based implementation.

Also fixing an initialized configuration parameter.

refs: #4513

Change-Id: I44559e729c949f90511a5c53282fd4a240356157
2018-02-21 13:49:40 -08:00
laqinfan a073e2e23e publisher: fix encoding bug in routing table publisher
refs: #4453

Change-Id: I03e819e963f0957f3d40ff25e378f2b9b17357b7
2018-02-16 12:30:36 +00:00
Saurab Dulal 9da6aa7fce Routing: Print labels on adjacency matrix when logging
refs: #2045

Change-Id: I0fa36eed1a6afdca6f135c80a20aa062a5e8cd63
2018-02-15 12:20:15 -08:00
Ashlesh Gawande 304bebf64f Remove some unused functions
Change-Id: Ic99891d2037e928ac927651607559e7660bd677f
2018-02-15 12:41:43 -06:00
Ashlesh Gawande 982a58fae5 Add version number after ChronoSync prefix
Change-Id: I5c6782461e6c00129850ab00df407a1f59f4353b
2018-02-14 17:39:12 -06:00
Alexander Afanasyev 7afe22f410 Output extended diagnostic information on fatal errors
Change-Id: I36bdd60df742837aeffb16ab78a93b93d5b24887
2018-02-13 16:17:40 -05:00
Ashlesh Gawande f7da9c542c conf: make ChronoSync's sync interest lifetime configurable
refs: #4490

Change-Id: Id3eabeed1049d1208ba49c47206f73f798f37a35
2018-02-09 15:24:47 -06:00
Muktadir Chowdhury c3ea26f000 Serve other routers' certificate and LSA
refs #4448, #4430

Change-Id: I3a9a9ae613770774be06effe26dfb866ea49f05a
2018-01-29 23:23:19 +00:00
Ashlesh Gawande 0d2c38299e Change certificate validity period to 1 year
Change certificate freshness period to 1 year
Catch Malformed URI error

refs: #4473, #4474

Change-Id: Ia341cba1e72b541c13eb480dfa53f26f89d854fa
2018-01-25 10:34:01 -06:00
Nick Gordon 563611eb20 communication: improve constness
Change-Id: Iabc5093d3c8e84540ddef4f6f2ff768dd9f3d0da
refs: #4472
2018-01-23 14:08:26 -06:00
Nick Gordon af87575012 nlsr: refactor equality operator
Change-Id: Iaaef9511e6569d597afcc5fa083b98ce86d8f78d
refs: #4127
2018-01-23 11:36:54 -08:00
Nick Gordon 4964870e9d src: improve constness
Change-Id: I8b3084e311642578628ea7c1017dc2a58979ab83
refs: #4472
2018-01-23 08:45:37 -08:00
dmcoomes b2ef6adbd3 Remove log4cxx from Jenkins
refs: #3949

Change-Id: I7ff3da932fe8a011aa391766c501b475118eaea5
2018-01-22 16:22:50 -06:00
dmcoomes cf8d0eda75 Use ndn-cxx logging facility
refs: #3949

Change-Id: I5d0931c3576c88e0c2fa52bdd0a716946400e0bc
2018-01-22 13:24:35 -06:00
Davide Pesavento 437adfeed6 ci: expand Travis-CI build matrix
Change-Id: I6ef5a461eaed9d66bed12189cde28cab30e55df8
2018-01-11 18:57:47 -05:00
laqinfan 357318540d publisher: implement routing table dataset publisher
refs: #3631, #3634

Change-Id: I7e961fdd0857690bee65d2bdfa4cf3de90ccac06
2018-01-11 12:08:27 +00:00
Ashlesh Gawande 14ab329746 Fix NLSR not converging without content store
refs: #4430

Change-Id: I8bff1facf528a07a3c2d90e8f512128c0420d799
2017-12-29 12:03:26 -06:00
Nick Gordon ed473c6c47 docs: mention the contributing guide
Change-Id: Ie14448f2fdf228db380f8332bee3dbe0b769fa50
refs: #4412
2017-12-21 14:02:30 -06:00
laqinfan ac4b65664f communication: fix dry-run mode not working
refs: #4394

Change-Id: I6b7eba5e36af307b9da6b5c198d44f9915db6358
2017-12-08 11:33:52 +00:00
Ashlesh Gawande d88c1dfdc2 ci+docs: remove all references to cryptopp/crypto++
Also update COPYING

refs: #3946

Change-Id: I87ded823f806857bb27079648e51619bb9dde6bc
2017-12-05 16:37:22 -06:00
Ashlesh Gawande 9e955bcec7 docs: Prepare version 0.4.0 release notes
Split the long release notes similar to NFD

Change-Id: If5ce5247bf74a4e402a33d92a35a686e7193dea1
2017-11-30 21:03:03 -06:00
Muktadir Chowdhury f04f98943d Convert to v2::security and adapt to ndn-cxx changes
Change-Id: I54f1b758cfb8f3f6cbc66a1aec5120ae1640b0ec
refs: #3964
2017-11-30 20:54:47 +00:00
Nick Gordon 2f62338d12 lsa: added noexcept and docs
Change-Id: Ic8c8566ced9654185a0619eca614ee1c6d108674
refs: #4354
2017-11-03 13:49:31 -05:00
Nick Gordon ae0a047c41 lsa: improved printing and logging
refs: #4354

Change-Id: I27cc99c6d01ba22668f4f56ad57b6f34f24f8af2
2017-11-02 13:55:56 -05:00
dmcoomes 5bcb39e255 rename log macros to comply with ISO C++ standard
refs: #4341

Change-Id: Idb05f59660f42c01a7bf014c6fff4125a28327f2
2017-11-01 09:36:53 -05:00
Nick Gordon 0fa4c77987 lsa: simplify initializeFromContent and improve naming
refs: #4354

Change-Id: I5ddd5a9f482f59e6ca52061ac92514feab8c3070
2017-10-30 17:09:24 -05:00
Nick Gordon 22cc1a8d17 lsa: simplified key getter
refs: #4354

Change-Id: Id886d41ff98530e1953066593640232d31b93b26
2017-10-27 10:18:57 -07:00
Nick Gordon 96861ca49c npl: npls more conveniently instantiable
NPLs can now be instantiated using brace-init lists, as well as by passing
any iterator-capable container.

refs: #4345

Change-Id: Ib43373d5899d0ac14861027c34431fa928eec191
2017-10-26 15:25:59 -07:00
Nick Gordon faf49f4c32 lsa: leverage class hierarchy when serializing.
refs: #4354

Change-Id: Ia3e79694c785b208184137d8ef0813629d61cc83
2017-10-26 11:08:25 -05:00
Nick Gordon 9212bd43bb lsa: make base class abstract
refs: #4353

Change-Id: If95c1689727f541c123623d21aec78ab8bdd58e6
2017-10-23 13:56:46 -05:00
Nick Gordon 727d4830d7 lsa: change type variable to enum class
Change-Id: I7fba951649771700ce6ccc4be7fb400546607e96
refs: #4340
2017-10-19 15:44:06 -07:00
Nick Gordon ff9a62713b style: made container APIs more consistent.
Change-Id: Ib4feedfc4c9fb497dfcd67e7e6a33ee03db58d7f
refs: #4337
2017-10-13 16:03:27 -07:00
Nick Gordon e18296c270 hello: move constructor definition to implementation file.
Change-Id: Ia176b5cad081a61368f45ac137dc6c9474101751
refs: #4334
2017-10-11 14:41:09 -07:00
Nick Gordon 2a1ac616b3 adjacency-list: improve constness of equality operator
refs: #4331

Change-Id: Ia57a82859abb2a32b22a7dbff471d1843d8237f0
2017-10-11 11:55:49 -07:00
dmcoomes a47255c2c5 docs: add commit ids for dependencies to README.md
refs: #4260

Change-Id: I096d5502a1cdc5fe712021fc0046d883a456173b
2017-10-04 11:24:48 -05:00
dmcoomes ffb62fa3fb docs: update authors
refs: #4231

Change-Id: Idbee3121d59d10ee96ff6b044cc55552f3b64c94
2017-09-29 10:29:17 -05:00
Nick Gordon 114537f6e0 publisher: simplified LSDB dataset interest handler.
refs: #4235

Change-Id: Ia3f606947884304e8b01211b5887ad62488f7167
2017-09-08 14:47:52 -07:00
Nick Gordon 922714a0d9 nlsr: Added a finally() to canonizeNeighborUris
Change-Id: I0046ae7a07be69f20a8f9d2b4acb33d8533a28e7
refs: #4128
2017-09-08 10:25:45 -07:00
Nick Gordon 5867b5233f fib: merged redundant functions
Change-Id: Iebec912fa7a3b8ab2cfe36835868dbdb068d7076
refs: #4105
2017-09-07 08:48:11 -07:00
Nick Gordon d40a588e25 routing: use unique_ptr for signal container
Change-Id: I1912f8630d0e26d8c25c2050208f6b8b0ffd9009
refs: #4268
2017-09-06 14:51:26 -07:00
Nick Gordon 8f23b5d58e sync: improved unit tests
refs: #4264

Change-Id: I981f3d8f653e4750ee6f9d77f2c89188f11d8ebb
2017-09-06 14:23:16 -07:00
Nick Gordon 9eac4d9830 sync: removed ref to lsdb.
Sync now emits to a signal whenever a new LSA is detected, and the LSDB
listens to this signal.  Sync consults a function object gotten at ctor time
to determine LSA newness.  This means Sync no longer needs a reference to
the LSDB, and LSA newness criteria can be freely manipulated.

Change-Id: Ifce3ebfc921ad846fcfa12d99c78f3b337180827
refs: #4264
2017-09-05 12:20:53 -07:00
Davide Pesavento 6ebfd7c182 build+ci: enable code-coverage reporting
This required changing the CI scripts to run the
unit tests against the debug version of NLSR.

Also sync default-compiler-flags.py with NFD.

Change-Id: I31f37e3dfef2c1237393512e0c238f5e6bcbe525
2017-08-31 13:49:13 -04:00
Nick Gordon b7b5839197 route: communicate routing changes using signals
The RoutingTable now has a signal that it emits upon finishing
calculation, which other modules can subscribe to. The NamePrefixTable
now references this emitted container to update its local copies of
routing information.

Change-Id: Id601776258ad0367cc47461ea8f86a710eada132
refs: #4249
2017-08-29 13:18:38 -07:00
Davide Pesavento 813df80e20 ci: sync CI scripts with NFD
Notable changes include:
  - support WAF_JOBS env var
  - use two parallel build jobs on Travis-CI
  - use "limited builds" for code-coverage and Travis-CI
  - upgrade Travis-CI osx from xcode8.2 to xcode8.3
  - enable ASan on Travis-CI

Change-Id: I4101499ebc590478d67ec8134c0395c4aafb8fb6
2017-08-26 17:06:00 -04:00
Davide Pesavento 0bd37314fe ci: speed up Travis-CI osx jobs by upgrading only the packages we need
Synchronize the rest of the file with NFD.

Change-Id: If2f5fba0eb614a881b51396b15a5a30e7939f728
2017-08-26 17:06:00 -04:00
Davide Pesavento 6a81b77260 ci: preserve PATH when running waf under sudo
Change-Id: I85bdc5b69de2c2c7b8c0dc5a7aa2927b495e2168
Refs: #4186
2017-08-26 17:06:00 -04:00
Nick Gordon c0c6bcf7e2 route: updates to name prefixes are more efficent.
With this change, only entries that have changed next-hops will
cause any change in the name prefix table.  Consequently, routing
table calculations no longer cause RIB registrations for unchanged
prefixes.  However, this is not a problem because FIB entries
refresh themselves.  This resulted in the removal of a test from the
TestNlsr suite.

refs: #2864

Change-Id: If28a04cb7bb47a3a6c32cd24578c68885d08d6b3
2017-08-24 16:54:39 -05:00
Nick Gordon 098aae410a tests: make LSDB tests more deterministic
TestLsdb/LsdbSync now iterates over all sent Interests to
check that any of them match, as opposed to checking
positionally, which cannot be guaranteed to pass.

Change-Id: Ib9e3a4b0aea4e1a4dd9f1c7e65d1b2a299863a9c
refs: #4257
2017-08-23 14:47:29 -07:00
Nick Gordon e40377d570 routing: improved routing map data structure.
Change-Id: I1cde5b2b9cffcec5cbfd78c5dd4262b5fb919a73
refs: #4240
2017-08-23 12:57:19 -05:00
Nick Gordon 7afcab4652 tests: make sync tests more deterministic
This change makes the UpdateForOther{LS,HR} tests more deterministic by
removing the temporal ordering requirement of sent interests.

Change-Id: Iceab5735baa2ff2fb97b18babfcf2bb32110a3c2
refs: #4253
2017-08-22 14:05:43 -07:00
Nick Gordon e98480b5d1 nlsr: removed references to ndn-cxx/common aliases and improved namespacing
Change-Id: I65e4691305b0157f334fc68d96998c119ef8b03b
refs: #3406
2017-08-22 13:37:21 -05:00
Nick Gordon d0a7df337f docs: wrote Doxygen comments for all files
refs: #4118

Change-Id: Ib0e7f1926cdabcca5aa401b59b24519412a099f7
2017-08-21 14:30:50 -07:00
Alejandro Gil Torres e0d2048d5f src: Implement packet statistics collection
refs: #2955, #2956

Change-Id: I57476a63562dbd378e566ad0280c89ccc5883e3e
2017-08-17 11:59:53 -07:00
Nick Gordon f14ec357d5 nlsr: Add support for sources to NamePrefixList
Added support for string sources to NamePrefixList entries.  Required was
some tweaking of the API, and refactoring usage around the codebase.

Change-Id: I44813e024a88dc1f591f427b0fad568a7d5353ab
refs: #4177
2017-08-16 15:00:14 -07:00
Davide Pesavento c58cc7f596 build+ci: enable AddressSanitizer and LeakSanitizer for unit tests
Refs: #2589, #4206

Change-Id: Ie9770134ff87fce438029b97c9ed61dbef3a71a3
2017-08-16 12:35:52 -07:00
Nick Gordon 22b5c957c0 routing: made map more container-agnostic
Change-Id: Ib18a41bac7627a9eb0bbafa6ccad0335d420dd68
refs: #4239
2017-08-15 09:06:28 -07:00
Ashlesh Gawande 90173ad966 Resolve ASan errors that will be thrown once it is turned on
Plus few minor spelling and code-style issues

refs: #4230

Change-Id: Ia665bab546a9628347af45836dcbe765dc91c54f
2017-08-14 10:54:15 -05:00
Nick Gordon 608061b95d tests: wrote select-cheapest-hop test.
Change-Id: I1eaed69675010bbf7b85221b72c4fcea71ebd9f0
refs: #4169
2017-08-11 10:38:40 -07:00
Ashlesh Gawande 793e8707a1 src: fix prefix advertise runtime error
Don't schedule Hello after receiving face changes in dataset,
let it be on its schedule. Also don't schedule routing calc (HR)
or AdjLsa (LS) let them be scheduled on Hello Data.

refs: #4215

Change-Id: I5c3881943f83b2f7683316fa3e22e6c280b6b64d
2017-08-10 16:21:34 -05:00
Laqin Fan 54a43f06e1 update: Refactor to use ndn-cxx dispatcher for prefix update/readvertise
refs: #3728

Change-Id: I3186433ed460850753f033a1d03fe27fd1fe889c
2017-08-04 12:46:50 -07:00
Ashlesh Gawande 820bb66350 src/lsdb: fix heap buffer overflow
refs: #4217

Change-Id: I902dfd7fcb856b5fd5cd285ef4d498956029848e
2017-08-03 16:14:19 -05:00
Ashlesh Gawande 9b71bbc970 wscript: install nlsr.conf as sample in the system
refs: #4197

Change-Id: If4fa9282f71661450950d8d6e44bf2ac4fe2bcee
2017-08-01 11:00:44 -07:00
Ashlesh Gawande 3909aa160a src: fix incorrect error on face-dataset-fetch-interval valid values
refs: #4211

Change-Id: I9ec04483a633ecf31797dd1637229d147d436d35
2017-07-31 12:30:13 -05:00
Nick Gordon d5c1a378d1 nlsr: discover Faces from NFD
refs: #2954

Change-Id: I072972d88bce0e1012e96f33577657048b7df1e1
2017-07-21 08:39:11 -07:00
Ashlesh Gawande f6bfb14def src/logger: use unix timestamp as default
refs: #4187

Change-Id: I235c1ba60d981b7c52d50b14b6fefafca049679a
2017-07-19 15:41:44 -05:00
laqinfan d22da51783 publisher: use ndn-cxx dispatcher for dataset publisher
Change-Id: I836a718ba40ff471bcdac7a7cc684c13914c4ea5
refs: #3728
2017-07-07 10:46:25 -05:00
Nick Gordon a75fdb27c5 build: fix build issues with pegged ndn-cxx
Change-Id: I0f000455d1eaf974d85ed76414af8710bc44dad4
2017-07-06 14:10:43 -05:00
laqinfan cd7ca05378 route: refactor Fib::removeOldNextHopsFromFibEntryAndNfd()
Change-Id: I6ef61fcec6b934c0238ecb697c14564c02cacfe2
refs: #3820
2017-06-28 08:45:13 -05:00
Muktadir R Chowdhury b00dc2acea Accommodate n-Dimensional HR coordinates
refs: #3751

Change-Id: Ib705b671daba56f58e09876a48d8b31649bd7ab1
2017-06-26 15:52:48 -05:00
Nick Gordon 0f1bf1dfcd Revert "sync: remove check-for-self in sync updates"
This reverts commit b23f279353.

Change-Id: I8630be544195a01e09b3a2e4d85d102ac00cfc72
refs: #4134
2017-06-22 13:47:55 -07:00
Ashlesh Gawande 8bfd124212 Use network name in sync prefix to avoid sync leaks from other networks
refs: #4101

Change-Id: I97d76d54571a124de33c6e62e07115c0df26882c
2017-06-22 09:15:27 -07:00
Ashlesh Gawande 7600c90882 Complete remaining changes for ChronoSync dependency issue
refs: #2400

Change-Id: If0cf9d3140f3ef65d86394fad3b6a6c7c58064f9
2017-06-21 14:25:03 -05:00
Nick Gordon e9733ed876 nlsr: refactor Adjacent to use FaceUri objects
Change-Id: Ib46f70570669c381572182eeea5c047a38a05104
refs: #4063
2017-06-20 15:02:55 -07:00
Nick Gordon b9e2c650e6 build: Fixed ChronoSync not being found on OS X.
Change-Id: I79dfa5bb8c25d6922c1e7b7529953fb2fb2fcae2
2017-06-20 13:12:02 -07:00
Nick Gordon 494de4033d nlsr: remove writeLog in NamePrefixList
Change-Id: Id54152684d1aa366b5eec8eeb79c046dedf6da7c
refs: #4131
2017-06-15 09:15:29 -07:00
Nick Gordon 56d1fae10a nlsr: implement NameLsa::isEqualContent
Change-Id: Ibf9021144f5ff253515875ac61de97740a1fecd7
refs: #2962
2017-06-15 09:15:24 -07:00
Nick Gordon adad2490e5 nlsr: LSA getData() now uses ostream instead of manually building the string
Change-Id: Ib4f6e27ccbe614140dbda63e6a5c7f4a78baedb7
refs: #2346
2017-06-13 12:15:43 -07:00
Nick Gordon b23f279353 sync: remove check-for-self in sync updates
Change-Id: Iba7e80370acc7c7144725bb6de1d018a8493b9b7
refs: #4117
2017-06-12 17:17:06 -05:00
Ashlesh Gawande 3e105a0493 Use separate name prefix and sequence number for each LSA type
refs: #1523

Change-Id: I9db6b3a3ea9ce5e17e132d2a4e2ae9f30dd4f591
2017-06-09 13:54:24 -05:00
Nick Gordon b9c5cecfb2 build: specify pre-v2 change version of ndn-cxx, ChronoSync in Jenkins file
Change-Id: I4c1a13542444821df6455958cdbbd9685c017337
refs: #3920 #4119
2017-06-09 10:37:12 -05:00
Nick Gordon f8852c2d27 nlsr: change configuration parameter output level to info
Change-Id: I32ec91457aaa45e0dbd87c599b3a6bd0b5ac92a6
refs: #2850
2017-05-25 10:07:53 -05:00
Nick Gordon 9461afb721 nlsr: canonize Adjacent FaceURIs on startup
Change-Id: I6a2b31631918c1ece79c3fc13e392917162efc2d
refs: #4063
2017-05-24 10:42:57 -07:00
Nick Gordon 2108808ae3 nlsr: remove deprecated ndn-cxx header includes
Change-Id: Ia016bf6f29304bbc2232db45003fedb331f43ee6
refs: #4088
2017-05-24 10:57:49 -05:00
Ashlesh Gawande 6fa00d923c Add missing dispatcher header to fix compilation
Change-Id: I7a7c637e74974c546bfc2c70fa39e850e8dbeaa2
2017-05-19 19:31:46 -05:00
Ashlesh Gawande b4567f40fb docs+README: improve documentation
Change-Id: I562508869f7e60ccf465b8c1acdf63e27c905c7a
2017-05-05 10:25:24 -05:00
Ashlesh Gawande 415676b6cc make chronosync a dependency
refs: #2400

Change-Id: I8b488f165a4f9a2c9a7731931be3b6d2e3c43c89
2017-05-02 14:26:16 -05:00
Nick Gordon c780a6986b nlsr: refactor AdjacencyList to use iterators instead of bare ptrs
Change-Id: I42225ee63c3d64eb80e58bc51c8d1afd20dd2ce2
refs: #4068
2017-04-28 10:43:08 -05:00
dmcoomes 9eaf3f4417 nlsr: Improve logging throughout lsdb.cpp and others
refs: #3934

Change-Id: I2365c88b795316c83dbeac2eab82f371c0275f88
2017-04-27 12:37:18 -05:00
dmcoomes c2c3ae0fd2 nlsr: update manpages for nlsrc when security is enabled
refs: #3911

Change-Id: Idf496ed2c3826c2aafd015a42b9a61d9ec4ecceb
2017-04-24 13:34:13 -05:00
Ashlesh Gawande 812af97447 ci: check boost version change on OSX
refs: #4060

Change-Id: I70819d428c6285ed4e18d2da9478d2c99333d37a
2017-04-24 10:31:49 -05:00
dmcoomes e689dd6d8b Make header guards comply with Rule 3.2
refs: #3984

Change-Id: Iec7a0d9ff49cf6124af9e554432ee5f09a199651
2017-04-12 09:24:42 -05:00
Nick Gordon 4d2c6c07ae nlsr: accept NFD-RIB-style register/unregister commands
refs: #3818

Change-Id: I7a5455bdec815bdcbe53ad535dab44249d1a18ce
2017-03-31 12:22:42 -05:00
Ashlesh Gawande 30096b8f37 docs: update NLSR paper
Change-Id: Ia8fda3373c5873db77db43f30165ec41dd4d05b2
2017-03-30 18:16:11 -05:00
Muktadir Chowdhury 3be6466a85 route: Refresh FIB entries independently of routing table calculation
refs: #2778

Change-Id: I3536faa9c097152bfb99ebc0270221ca359cba35
2017-03-28 10:58:30 -05:00
Muktadir R Chowdhury f023a88ec1 docs+build: Prepare release for version 0.3.2
refs: #3995

Change-Id: If9ea3e69eee886abce90700e33f37c0102e367a7
2017-03-16 09:19:50 -07:00
Alexander Afanasyev 4c2bb361ae Remove more use of deprecated code
Change-Id: I4322ab4aedb9287acf2eb608f96b7eefbc5f7dba
Refs: #3988
2017-03-14 12:29:19 -07:00
Alexander Afanasyev 1de901f161 Remove use of deprecated code
Change-Id: I197471c48c54c5671bb8f641c4332b3ac7893824
Refs: #3988
2017-03-11 13:50:28 -08:00
dmcoomes 9f93666519 nlsr: Don't use ndn aliases provided by ndn-cxx/common.hpp
refs: #3983

Change-Id: I31da8d68e0285dcfe9c7d3e5e678c00397d22bef
2017-03-09 12:12:40 -06:00
Nick Gordon 48daea20d7 nlsr: enable dispatcher for LOCALHOST_PREFIX
refs: #3938

Change-Id: I532b69aa7e2ade22929588f42de55366fccb80d2
2017-02-27 15:33:10 -06:00
Ashlesh Gawande 218aaef118 utility: temp fix for face already exists (409)
refs: #3976

Change-Id: I930ae5dae8938c83b7deff5079a499b7c5dcc639
2017-02-25 21:34:36 -06:00
Davide Pesavento 87911dacd5 src: use ndn::nfd::ROUTE_ORIGIN_NLSR instead of a magic number
Change-Id: I88dc8e8bc5893820085f305abb52bfd1b654dfcd
Refs: #3903
2017-02-21 22:13:25 -05:00
Ashlesh Gawande 54e726cf5e update config file for /localhop LSA
refs: #3899

Change-Id: I028ed7067724a2d3506ceca0813aea89efea528d
2017-02-14 11:04:08 -06:00
Laqin Fan a4cf402084 nlsr: Pass keyChain to NLSR constructor
refs: #3742

Change-Id: I186784da2989aa8bcc396c81c4fc80254a6f313a
2017-02-01 10:18:05 -08:00
Nick Gordon f590fecfc2 docs+build: Prepare release for version 0.3.1
Change-Id: I01d0b8e71ee4fdf37957a323e11e87f69672d473
2017-01-22 11:03:28 -08:00
Ashlesh Gawande 6077ea910c src: use /localhop component in LSA prefix
refs: #3899

Change-Id: Ibbb42adf3cc34e4a09e267bd73ffb248aad715d5
2017-01-21 16:23:34 -08:00
Nick Gordon d1f4f33cfd nlsr: Add dispatcher to NLSR class
refs: #3930

Change-Id: I69d3a1a87558118ea25258f08f7441e0d7ebe73d
2017-01-20 14:50:20 -06:00
Laqin Fan d8c9d8cdab Fix typos in the sample configuration file.
Change-Id: I66d66bef84aeb3508af654f7e664ca59bc5fee53
refs: #3113
2017-01-19 15:54:12 +00:00
Nick Gordon feae5574b8 boilerplate: Update copyright year in .cpp files
refs: #3923

Change-Id: I8a46f2634527094d82c85c605384f25ddd172732
2017-01-13 12:18:32 -06:00
Alexander Afanasyev 4fc69e49a9 ci: Fix macOS build with Travis-CI
Change-Id: Iabdfd71c4ba8b3c35f6de117da3b42b61cb1dc4e
2017-01-11 13:31:43 -08:00
Nick Gordon c6a852234d nlsr: Updated license boilerplate for all NLSR files.
refs: #3909

Change-Id: I7186b62e2e3506e23a28c70b95b7e6a225a8d78b
2017-01-03 16:56:17 -06:00
Ashlesh Gawande 44395237b8 src: use /localhop component in Sync prefix
refs: #3627

Change-Id: I666f4072601cf7b66bcde632c31c632fabe6e684
2016-12-13 14:35:44 -06:00
Ashlesh Gawande c5fa320239 hello-protocol: re-calculate HR nexthops on status change of a neighbor
refs: #3874

Change-Id: I8295248d95e047e24cced9700eabd458ab3e9112
2016-12-05 12:06:25 -08:00
Eric Newberry 41330f4256 ci: set Travis CI Xcode version and update NODE_LABELS to 10.11
refs #3833

Change-Id: I4c9f98d11e01ce1b712295c884d49fc14def37e2
2016-11-01 15:33:36 -07:00
Alexander Afanasyev 96bf2f0db8 build: Do not fail the build in debug mode when using deprecated declarations
The original motivation of this change was to avoid compilation failure
in debug mode on macOS 10.12.

Change-Id: Ibc006a6be6f5d9aba80dfe4b5f9b13a758bafcc7
Refs: #3795
2016-11-01 15:33:20 -07:00
Laqin Fan 2b057af9e1 hello-protocol: delete redundant call to Nlsr::setStragies()
ref: #3743

Change-Id: Ic793b0e78639adceec0932ded5a87514b9af94ea
2016-09-27 18:32:02 +00:00
Nick Gordon b71684744f src: Fib and FaceMap now use map instead of list as their table data structure.
ref: #2781

Change-Id: I93ad23266ee7b79fd5c53b538c30af76565abc4b
2016-09-26 10:54:41 -05:00
Nick Gordon b50e51b374 Name prefix table entries keep pointers instead of keeping a copy of the object for routing table entries.
refs: #2863

Change-Id: I3271c9f96dfc8721a0ca7c900542c6ddb0b321ac
2016-09-12 10:36:32 -07:00
Junxiao Shi 3e5120c543 include ndn-cxx/mgmt/nfd/*
refs #3760

Change-Id: Iaa0e127a2035960fc96a7c6f958538d3bc3cdee6
2016-09-10 16:58:34 +00:00
Vince Lehman ef21d8eab0 src: Sort NextHops on NexthopList insertion
refs: #2721

Change-Id: I39893c5fb6b5fac93220901ab3190090f0d2cc57
2016-09-06 19:41:31 -05:00
Nick G 97e3494256 docs: improve Doxygen comments.
refs: #1435

Change-Id: I21624ef4eec393c82a50229a07e8277fb6ae4ddf
2016-09-02 12:11:42 -07:00
Nick G d69f9a3c82 Copied ndn-cxx's .jenkins script for better compatibility.
refs: #3695

Change-Id: I909fd9b486e16939a58f07d42e356885d809ef9a
2016-08-24 13:25:39 -05:00
Junxiao Shi 63bd0348b3 adapt to Controller::CommandFailCallback with ControlResponse
refs #3739

Change-Id: I193fb11fd96bd91808fc6e3af22a8da2511246e2
2016-08-17 16:57:14 +00:00
Muktadir R Chowdhury b9d43d06cc docs: Mention change in configuration file in release note.
Change-Id: I70dda0a904e03bdd93b3f2f4404f70ecd108b65d
2016-08-15 09:50:39 -07:00
Nick Gordon e2d3fe9d9a Brought script into POSIX-compliance for find.
refs: #3695

Change-Id: Id35218b560f55a19fec81409950fed5a4f8504d5
2016-08-12 14:00:52 -07:00
Nick Gordon 7b5872ec86 face-map.hpp: Fixed class formatting per style rule 1.4
refs: #3737

Change-Id: Iee14f98a967a3887c34700c3c2a004dcb8b6d97d
2016-08-12 13:57:01 -07:00
Nick Gordon fad8e257c0 Fixed namespace formatting across all files.
refs: #3735

Change-Id: Ia04f0895de9906e280d6140f775bb6609db714e6
2016-08-12 13:49:12 -07:00
Nick Gordon f8b5bcd27e Fixed copyright dates across all files.
refs: #3736

Change-Id: Ibe089fd2e8c4ddc8a4c68d073b435f7d3060d1a4
2016-08-11 15:14:18 -05:00
264 changed files with 13705 additions and 12614 deletions

No files matched your search

+4 -3
View File
@@ -3,7 +3,8 @@ set -e
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
for i in $( find "$DIR/.jenkins.d" -type f -perm +111 | sort ); do
echo "Run: $i"
"$i"
for file in "$DIR"/.jenkins.d/*; do
[[ -f $file && -x $file ]] || continue
echo "Run: $file"
"$file"
done
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
set -x
if has OSX $NODE_LABELS; then
FORMULAE=(boost pkg-config openssl)
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
sudo apt-get -qq update
sudo apt-get -qy install build-essential pkg-config libboost-all-dev \
libsqlite3-dev libssl-dev
if [[ $JOB_NAME == *"code-coverage" ]]; then
sudo apt-get -qy install lcov libgd-perl python-setuptools
sudo easy_install --upgrade gcovr
fi
fi
-28
View File
@@ -1,28 +0,0 @@
#!/usr/bin/env bash
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
if has OSX $NODE_LABELS && ! has OSX-10.8-c++11-64bit $NODE_LABELS; then
# OSX 10.8 requires special handling of dependencies
set -x
brew update
brew upgrade
brew install boost pkg-config sqlite cryptopp log4cxx protobuf openssl
brew link --force openssl log4cxx protobuf
brew cleanup
fi
if has Ubuntu $NODE_LABELS; then
BOOST_PKG=libboost-all-dev
if has Ubuntu-12.04 $NODE_LABELS; then
BOOST_PKG=libboost1.48-all-dev
fi
set -x
sudo apt-get update -qq -y
sudo apt-get -qq -y install build-essential pkg-config $BOOST_PKG \
libcrypto++-dev libsqlite3-dev \
liblog4cxx10-dev protobuf-compiler libprotobuf-dev libssl-dev
fi
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
set -x
pushd "${CACHE_DIR:-/tmp}" >/dev/null
INSTALLED_VERSION=
if has OSX $NODE_LABELS; then
BOOST=$(brew ls --versions boost)
OLD_BOOST=$(cat boost.txt || :)
if [[ $OLD_BOOST != $BOOST ]]; then
echo "$BOOST" > boost.txt
INSTALLED_VERSION=NONE
fi
fi
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
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
mv ndn-cxx-latest ndn-cxx
else
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
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
popd >/dev/null
popd >/dev/null
if has Linux $NODE_LABELS; then
sudo ldconfig
elif has FreeBSD10 $NODE_LABELS; then
sudo ldconfig -m
fi
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
set -x
pushd "${CACHE_DIR:-/tmp}" >/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
fi
if [[ -z $INSTALLED_VERSION ]]; then
INSTALLED_VERSION=$(git -C ChronoSync 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)
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
sudo rm -Rf ChronoSync
mv ChronoSync-latest ChronoSync
else
sudo rm -Rf ChronoSync-latest
fi
sudo rm -fr /usr/local/include/ChronoSync
sudo rm -f /usr/local/lib/libChronoSync*
sudo rm -f /usr/local/lib/pkgconfig/ChronoSync*
pushd ChronoSync >/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
popd >/dev/null
popd >/dev/null
if has Linux $NODE_LABELS; then
sudo ldconfig
elif has FreeBSD10 $NODE_LABELS; then
sudo ldconfig -m
fi
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
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}
# Cleanup
sudo env "PATH=$PATH" ./waf --color=yes distclean
# Configure/build in optimized mode without tests
./waf --color=yes configure
./waf --color=yes build -j${WAF_JOBS:-1}
# Cleanup
sudo env "PATH=$PATH" ./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}
# (tests will be run against debug version)
# Install
sudo env "PATH=$PATH" ./waf --color=yes install
-42
View File
@@ -1,42 +0,0 @@
#!/usr/bin/env bash
set -x
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
pushd /tmp >/dev/null
INSTALLED_VERSION=$((cd ndn-cxx && git rev-parse HEAD) 2>/dev/null || echo NONE)
sudo rm -Rf ndn-cxx-latest
git clone --depth 1 git://github.com/named-data/ndn-cxx ndn-cxx-latest
LATEST_VERSION=$((cd ndn-cxx-latest && git rev-parse HEAD) 2>/dev/null || echo UNKNOWN)
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
sudo rm -Rf ndn-cxx
mv ndn-cxx-latest ndn-cxx
else
sudo rm -Rf ndn-cxx-latest
fi
sudo rm -Rf /usr/local/include/ndn-cxx
sudo rm -f /usr/local/lib/libndn-cxx*
sudo rm -f /usr/local/lib/pkgconfig/libndn-cxx*
pushd ndn-cxx >/dev/null
./waf configure -j1 --color=yes --enable-shared --disable-static --without-osx-keychain
./waf -j1 --color=yes
sudo ./waf install -j1 --color=yes
popd >/dev/null
popd >/dev/null
if has Linux $NODE_LABELS; then
sudo ldconfig
elif has FreeBSD $NODE_LABELS; then
sudo ldconfig -a
fi
-37
View File
@@ -1,37 +0,0 @@
#!/usr/bin/env bash
set -x
set -e
git submodule init
git submodule sync
git submodule update
COVERAGE=$( python -c "print '--with-coverage' if 'code-coverage' in '$JOB_NAME' else ''" )
# Cleanup
sudo ./waf -j1 --color=yes distclean
# Configure/build in debug mode
./waf -j1 --color=yes configure --with-tests --debug
./waf -j1 --color=yes build
# Cleanup
sudo ./waf -j1 --color=yes distclean
# Configure/build in optimized mode without tests
./waf -j1 --color=yes configure
./waf -j1 --color=yes build
# Cleanup
sudo ./waf -j1 --color=yes distclean
# Configure/build in optimized mode with tests
./waf -j1 --color=yes configure --with-tests $COVERAGE
./waf -j1 --color=yes build
# (tests will be run against optimized version)
./waf configure --color=yes --with-tests $COVERAGE
./waf -j1 --color=yes
sudo ./waf install --color=yes
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -e
set -x
# Prepare environment
rm -Rf ~/.ndn
ut_log_args() {
echo --log_level=test_suite
}
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+=":strip_path_prefix=${PWD}/"
export ASAN_OPTIONS
# Run unit tests
./build/unit-tests-nlsr $(ut_log_args)
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
set -x
if [[ $JOB_NAME == *"code-coverage" ]]; then
lcov --quiet \
--capture \
--directory . \
--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 \
--title "NLSR unit tests" \
build/coverage.info
fi
-7
View File
@@ -1,7 +0,0 @@
#!/usr/bin/env bash
set -x
set -e
rm -Rf ~/.ndn
./build/unit-tests-nlsr -l test_suite
+36
View File
@@ -0,0 +1,36 @@
CONTINUOUS INTEGRATION SCRIPTS
==============================
Environment Variables Used in Build Scripts
-------------------------------------------
- `NODE_LABELS`: the variable defines a list of OS properties. The set values are used by the
build scripts to select proper behavior for different OS.
The list should include at least `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
Possible values for Linux:
* `[OS_TYPE]`: `Linux`
* `[DISTRO_TYPE]`: `Ubuntu`
* `[DISTRO_VERSION]`: `Ubuntu-14.04`, `Ubuntu-16.04`
Possible values for OS X / macOS:
* `[OS_TYPE]`: `OSX`
* `[DISTRO_TYPE]`: `OSX` (can be absent)
* `[DISTRO_VERSION]`: `OSX-10.10`, `OSX-10.11`, `OSX-10.12`
- `JOB_NAME`: optional variable to define type of the job. Depending on the defined job type,
the build scripts can perform different tasks.
Possible values:
* empty: default build process
* `code-coverage` (Linux OS is assumed): debug build with tests and code coverage analysis
* `limited-build`: only a single debug build with tests
- `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.
- `WAF_JOBS`: number of parallel build jobs used by waf, defaults to 1.
Executable → Regular
+13 -4
View File
@@ -1,9 +1,18 @@
has() {
local saved_xtrace
[[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
set +x
local p=$1
shift
local x
for x in "$@"; do
[[ "${x}" == "${p}" ]] && return 0
local i ret=1
for i in "$@"; do
if [[ "${i}" == "${p}" ]]; then
ret=0
break
fi
done
return 1
set ${saved_xtrace}
return ${ret}
}
+95 -16
View File
@@ -1,24 +1,103 @@
language: cpp
dist: trusty
sudo: required
language: generic
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
dist: trusty
env:
- CXX=g++
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
env: COMPILER=g++-4.8
- os: linux
dist: trusty
env:
- CXX=clang++
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
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
env:
- CXX=clang++
- NODE_LABELS="OSX OSX-10.9"
notifications:
email:
on_success: always
on_failure: always
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
+216 -76
View File
@@ -30,15 +30,15 @@ When using this tool, the wscript will look like:
Options are generated, in order to specify the location of boost includes/libraries.
The `check_boost` configuration function allows to specify the used boost libraries.
It can also provide default arguments to the --boost-static and --boost-mt command-line arguments.
It can also provide default arguments to the --boost-mt command-line arguments.
Everything will be packaged together in a BOOST component that you can use.
When using MSVC, a lot of compilation flags need to match your BOOST build configuration:
- you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined.
Errors: C4530
- boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC
So before calling `conf.check_boost` you might want to disabling by adding:
conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
So before calling `conf.check_boost` you might want to disabling by adding
conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
Errors:
- boost might also be compiled with /MT, which links the runtime statically.
If you have problems with redefined symbols,
@@ -52,24 +52,55 @@ import sys
import re
from waflib import Utils, Logs, Errors
from waflib.Configure import conf
from waflib.TaskGen import feature, after_method
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib', '/usr/lib/x86_64-linux-gnu', '/usr/lib/i386-linux-gnu', '/usr/local/ndn/lib']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include', '/usr/local/ndn/include']
BOOST_LIBS = ['/usr/lib/x86_64-linux-gnu', '/usr/lib/i386-linux-gnu',
'/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
BOOST_VERSION_FILE = 'boost/version.hpp'
BOOST_VERSION_CODE = '''
#include <iostream>
#include <boost/version.hpp>
int main() { std::cout << BOOST_LIB_VERSION << ":" << BOOST_VERSION << std::endl; }
'''
BOOST_SYSTEM_CODE = '''
BOOST_ERROR_CODE = '''
#include <boost/system/error_code.hpp>
int main() { boost::system::error_code c; }
'''
PTHREAD_CODE = '''
#include <pthread.h>
static void* f(void*) { return 0; }
int main() {
pthread_t th;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&th, &attr, &f, 0);
pthread_join(th, 0);
pthread_cleanup_push(0, 0);
pthread_cleanup_pop(0);
pthread_attr_destroy(&attr);
}
'''
BOOST_THREAD_CODE = '''
#include <boost/thread.hpp>
int main() { boost::thread t; }
'''
BOOST_LOG_CODE = '''
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
int main() {
using namespace boost::log;
add_common_attributes();
add_console_log(std::clog, keywords::format = "%Message%");
BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl;
}
'''
# toolsets from {boost_dir}/tools/build/v2/tools/common.jam
PLATFORM = Utils.unversioned_sys_platform()
detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
@@ -101,34 +132,37 @@ BOOST_TOOLSETS = {
def options(opt):
opt = opt.add_option_group('Boost Options')
opt.add_option('--boost-includes', type='string',
default='', dest='boost_includes',
help='''path to the directory where the boost includes are, e.g., /path/to/boost_1_55_0/stage/include''')
help='''path to the directory where the boost includes are,
e.g., /path/to/boost_1_55_0/stage/include''')
opt.add_option('--boost-libs', type='string',
default='', dest='boost_libs',
help='''path to the directory where the boost libs are, e.g., /path/to/boost_1_55_0/stage/lib''')
opt.add_option('--boost-static', action='store_true',
default=False, dest='boost_static',
help='link with static boost libraries (.lib/.a)')
help='''path to the directory where the boost libs are,
e.g., path/to/boost_1_55_0/stage/lib''')
opt.add_option('--boost-mt', action='store_true',
default=False, dest='boost_mt',
help='select multi-threaded libraries')
opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
help='''select libraries with tags (dgsyp, d for debug), see doc Boost, Getting Started, chapter 6.1''')
help='''select libraries with tags (gd for debug, static is automatically added),
see doc Boost, Getting Started, chapter 6.1''')
opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
opt.add_option('--boost-toolset', type='string',
default='', dest='boost_toolset',
help='force a toolset e.g. msvc, vc90, gcc, mingw, mgw45 (default: auto)')
help='force a toolset e.g. msvc, vc90, \
gcc, mingw, mgw45 (default: auto)')
py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
opt.add_option('--boost-python', type='string',
default=py_version, dest='boost_python',
help='select the lib python with this version (default: %s)' % py_version)
help='select the lib python with this version \
(default: %s)' % py_version)
@conf
def __boost_get_version_file(self, d):
if not d:
return None
dnode = self.root.find_dir(d)
if dnode:
return dnode.find_node(BOOST_VERSION_FILE)
@@ -141,18 +175,15 @@ def boost_get_version(self, d):
if node:
try:
txt = node.read()
except (OSError, IOError):
except EnvironmentError:
Logs.error("Could not read the file %r" % node.abspath())
else:
re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M)
m1 = re_but1.search(txt)
re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+(\\d+)', re.M)
m2 = re_but2.search(txt)
if m1 and m2:
return (m1.group(1), m2.group(1))
return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":")
@conf
@@ -160,7 +191,7 @@ def boost_get_includes(self, *k, **kw):
includes = k and k[0] or kw.get('includes', None)
if includes and self.__boost_get_version_file(includes):
return includes
for d in Utils.to_list(self.environ.get('INCLUDE', '')) + BOOST_INCLUDES:
for d in self.environ.get('INCLUDE', '').split(';') + BOOST_INCLUDES:
if self.__boost_get_version_file(d):
return d
if includes:
@@ -195,7 +226,9 @@ def __boost_get_libs_path(self, *k, **kw):
path = self.root.find_dir(libs)
files = path.ant_glob('*boost_*')
if not libs or not files:
for d in Utils.to_list(self.environ.get('LIB', [])) + BOOST_LIBS:
for d in self.environ.get('LIB', '').split(';') + BOOST_LIBS:
if not d:
continue
path = self.root.find_dir(d)
if path:
files = path.ant_glob('*boost_*')
@@ -226,15 +259,10 @@ def boost_get_libs(self, *k, **kw):
according to the parameters
'''
path, files = self.__boost_get_libs_path(**kw)
t = []
if kw.get('mt', False):
t.append('mt')
if kw.get('abi', None):
t.append(kw['abi'])
tags = t and '(-%s)+' % '-'.join(t) or ''
files = sorted(files, key=lambda f: (len(f.name), f.name), reverse=True)
toolset = self.boost_get_toolset(kw.get('toolset', ''))
toolset_pat = '(-%s[0-9]{0,3})+' % toolset
version = '(-%s)+' % self.env.BOOST_VERSION
toolset_pat = '(-%s[0-9]{0,3})' % toolset
version = '-%s' % self.env.BOOST_VERSION
def find_lib(re_lib, files):
for file in files:
@@ -248,28 +276,110 @@ def boost_get_libs(self, *k, **kw):
name = name[3:]
return name[:name.rfind('.')]
libs = []
for lib in Utils.to_list(k and k[0] or kw.get('lib', None)):
py = (lib == 'python') and '(-py%s)+' % kw['python'] or ''
# Trying libraries, from most strict match to least one
for pattern in ['boost_%s%s%s%s%s' % (lib, toolset_pat, tags, py, version),
'boost_%s%s%s%s' % (lib, tags, py, version),
'boost_%s%s%s' % (lib, tags, version),
# Give up trying to find the right version
'boost_%s%s%s%s' % (lib, toolset_pat, tags, py),
'boost_%s%s%s' % (lib, tags, py),
'boost_%s%s' % (lib, tags)]:
self.to_log('Trying pattern %s' % pattern)
file = find_lib(re.compile(pattern), files)
if file:
libs.append(format_lib_name(file.name))
break
else:
self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
self.fatal('The configuration failed')
def match_libs(lib_names, is_static):
libs = []
lib_names = Utils.to_list(lib_names)
if not lib_names:
return libs
t = []
if kw.get('mt', False):
t.append('-mt')
if kw.get('abi', None):
t.append('%s%s' % (is_static and '-s' or '-', kw['abi']))
elif is_static:
t.append('-s')
tags_pat = t and ''.join(t) or ''
ext = is_static and self.env.cxxstlib_PATTERN or self.env.cxxshlib_PATTERN
ext = ext.partition('%s')[2] # remove '%s' or 'lib%s' from PATTERN
return path.abspath(), libs
for lib in lib_names:
if lib == 'python':
# for instance, with python='27',
# accepts '-py27', '-py2', '27' and '2'
# but will reject '-py3', '-py26', '26' and '3'
tags = '({0})?((-py{2})|(-py{1}(?=[^0-9]))|({2})|({1}(?=[^0-9]))|(?=[^0-9])(?!-py))'.format(tags_pat, kw['python'][0], kw['python'])
else:
tags = tags_pat
# Trying libraries, from most strict match to least one
for pattern in ['boost_%s%s%s%s%s$' % (lib, toolset_pat, tags, version, ext),
'boost_%s%s%s%s$' % (lib, tags, version, ext),
# Give up trying to find the right version
'boost_%s%s%s%s$' % (lib, toolset_pat, tags, ext),
'boost_%s%s%s$' % (lib, tags, ext),
'boost_%s%s$' % (lib, ext),
'boost_%s' % lib]:
self.to_log('Trying pattern %s' % pattern)
file = find_lib(re.compile(pattern), files)
if file:
libs.append(format_lib_name(file.name))
break
else:
self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
self.fatal('The configuration failed')
return libs
return path.abspath(), match_libs(kw.get('lib', None), False), match_libs(kw.get('stlib', None), True)
@conf
def _check_pthread_flag(self, *k, **kw):
'''
Computes which flags should be added to CXXFLAGS and LINKFLAGS to compile in multi-threading mode
Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3,
boost/thread.hpp will trigger a #error if -pthread isn't used:
boost/config/requires_threads.hpp:47:5: #error "Compiler threading support
is not turned on. Please set the correct command line options for
threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)"
Based on _BOOST_PTHREAD_FLAG(): https://github.com/tsuna/boost.m4/blob/master/build-aux/boost.m4
'''
var = kw.get('uselib_store', 'BOOST')
self.start_msg('Checking the flags needed to use pthreads')
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# (none): in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -lpthreads: AIX (must check this before -lpthread)
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads)
# -pthreads: Solaris/GCC
# -mthreads: MinGW32/GCC, Lynx/GCC
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# -lpthread: GNU Linux, etc.
# --thread-safe: KAI C++
if Utils.unversioned_sys_platform() == "sunos":
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"]
else:
boost_pthread_flags = ["", "-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread",
"-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"]
for boost_pthread_flag in boost_pthread_flags:
try:
self.env.stash()
self.env['CXXFLAGS_%s' % var] += [boost_pthread_flag]
self.env['LINKFLAGS_%s' % var] += [boost_pthread_flag]
self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False)
self.end_msg(boost_pthread_flag)
return
except self.errors.ConfigurationError:
self.env.revert()
self.end_msg('None')
@conf
def check_boost(self, *k, **kw):
@@ -282,7 +392,10 @@ def check_boost(self, *k, **kw):
if not self.env['CXX']:
self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
params = {'lib': k and k[0] or kw.get('lib', None)}
params = {
'lib': k and k[0] or kw.get('lib', None),
'stlib': kw.get('stlib', None)
}
for key, value in self.options.__dict__.items():
if not key.startswith('boost_'):
continue
@@ -297,42 +410,53 @@ def check_boost(self, *k, **kw):
self.env.BOOST_VERSION = versions[0]
self.env.BOOST_VERSION_NUMBER = int(versions[1])
self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000,
int(versions[1]) / 100 % 1000,
int(versions[1]) % 100))
int(versions[1]) / 100 % 1000,
int(versions[1]) % 100))
if Logs.verbose:
Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
if not params['lib']:
if not params['lib'] and not params['stlib']:
return
if 'static' in kw or 'static' in params:
Logs.warn('boost: static parameter is deprecated, use stlib instead.')
self.start_msg('Checking boost libs')
suffix = params.get('static', None) and 'ST' or ''
path, libs = self.boost_get_libs(**params)
self.env['%sLIBPATH_%s' % (suffix, var)] = [path]
self.env['%sLIB_%s' % (suffix, var)] = libs
path, libs, stlibs = self.boost_get_libs(**params)
self.env['LIBPATH_%s' % var] = [path]
self.env['STLIBPATH_%s' % var] = [path]
self.env['LIB_%s' % var] = libs
self.env['STLIB_%s' % var] = stlibs
self.end_msg('ok')
if Logs.verbose:
Logs.pprint('CYAN', ' path : %s' % path)
Logs.pprint('CYAN', ' libs : %s' % libs)
Logs.pprint('CYAN', ' shared libs : %s' % libs)
Logs.pprint('CYAN', ' static libs : %s' % stlibs)
def has_shlib(lib):
return params['lib'] and lib in params['lib']
def has_stlib(lib):
return params['stlib'] and lib in params['stlib']
def has_lib(lib):
return has_shlib(lib) or has_stlib(lib)
if has_lib('thread'):
# not inside try_link to make check visible in the output
self._check_pthread_flag(k, kw)
def try_link():
if 'system' in params['lib']:
self.check_cxx(
fragment=BOOST_SYSTEM_CODE,
use=var,
execute=False,
)
if 'thread' in params['lib']:
self.check_cxx(
fragment=BOOST_THREAD_CODE,
use=var,
execute=False,
)
if has_lib('system'):
self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False)
if has_lib('thread'):
self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False)
if has_lib('log'):
if not has_lib('thread'):
self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS']
if has_shlib('log'):
self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK']
self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)
if params.get('linkage_autodetect', False):
self.start_msg("Attempting to detect boost linkage flags")
toolset = self.boost_get_toolset(kw.get('toolset', ''))
if toolset in ['vc']:
if toolset in ('vc',):
# disable auto-linking feature, causing error LNK1181
# because the code wants to be linked against
self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
@@ -356,14 +480,14 @@ def check_boost(self, *k, **kw):
try:
try_link()
self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var]))
e = None
exc = None
break
except Errors.ConfigurationError as exc:
except Errors.ConfigurationError as e:
self.env.revert()
e = exc
exc = e
if e is not None:
self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=e)
if exc is not None:
self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=exc)
self.fatal('The configuration failed')
else:
self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain")
@@ -376,3 +500,19 @@ def check_boost(self, *k, **kw):
self.end_msg("Could not link against boost libraries using supplied options")
self.fatal('The configuration failed')
self.end_msg('ok')
@feature('cxx')
@after_method('apply_link')
def install_boost(self):
if install_boost.done or not Utils.is_win32 or not self.bld.cmd.startswith('install'):
return
install_boost.done = True
inst_to = getattr(self, 'install_path', '${BINDIR}')
for lib in self.env.LIB_BOOST:
try:
file = self.bld.find_file(self.env.cxxshlib_PATTERN % lib, self.env.LIBPATH_BOOST)
self.bld.install_files(inst_to, self.bld.root.find_node(file))
except:
continue
install_boost.done = False
+3 -5
View File
@@ -1,10 +1,6 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
#
# Copyright (c) 2014, Regents of the University of California
#
# GPL 3.0 license, see the COPYING.md file for more information
from waflib import TaskGen
from waflib import TaskGen, Logs
def options(opt):
opt.add_option('--with-coverage', action='store_true', default=False, dest='with_coverage',
@@ -12,6 +8,8 @@ def options(opt):
def configure(conf):
if conf.options.with_coverage:
if not conf.options.debug:
conf.fatal("Code coverage flags require debug mode compilation (add --debug)")
conf.check_cxx(cxxflags=['-fprofile-arcs', '-ftest-coverage', '-fPIC'],
linkflags=['-fprofile-arcs'], uselib_store='GCOV', mandatory=True)
+43 -32
View File
@@ -4,17 +4,37 @@ from waflib import Logs, Configure, Utils
def options(opt):
opt.add_option('--debug', '--with-debug', action='store_true', default=False, dest='debug',
help='''Compile in debugging mode without optimizations (-O0 or -Og)''')
help='''Compile in debugging mode with minimal optimizations (-O0 or -Og)''')
def configure(conf):
cxx = conf.env['CXX_NAME'] # CXX_NAME represents generic name of the compiler
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'])
errmsg = ''
warnmsg = ''
if cxx == 'gcc':
if ccver < (4, 8, 2):
errmsg = ('The version of gcc you are using is too old.\n'
'The minimum supported gcc version is 4.8.2.')
flags = GccFlags()
elif cxx == 'clang':
if ccver < (3, 4, 0):
errmsg = ('The version of clang you are using is too old.\n'
'The minimum supported clang version is 3.4.0.')
flags = ClangFlags()
else:
warnmsg = 'Note: %s compiler is unsupported' % cxx
flags = CompilerFlags()
Logs.warn('The code has not yet been tested with %s compiler' % cxx)
if errmsg:
conf.end_msg('.'.join(conf.env['CC_VERSION']), color='RED')
conf.fatal(errmsg)
elif warnmsg:
conf.end_msg('.'.join(conf.env['CC_VERSION']), color='YELLOW')
Logs.warn(warnmsg)
else:
conf.end_msg('.'.join(conf.env['CC_VERSION']))
areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
@@ -60,7 +80,7 @@ def add_supported_cxxflags(self, cxxflags):
supportedFlags += [flag]
self.end_msg(' '.join(supportedFlags))
self.env.CXXFLAGS = supportedFlags + self.env.CXXFLAGS
self.env.prepend_value('CXXFLAGS', supportedFlags)
@Configure.conf
def add_supported_linkflags(self, linkflags):
@@ -78,7 +98,7 @@ def add_supported_linkflags(self, linkflags):
supportedFlags += [flag]
self.end_msg(' '.join(supportedFlags))
self.env.LINKFLAGS = supportedFlags + self.env.LINKFLAGS
self.env.prepend_value('LINKFLAGS', supportedFlags)
class CompilerFlags(object):
@@ -98,17 +118,25 @@ class GccBasicFlags(CompilerFlags):
"""
This class defines basic flags that work for both gcc and clang compilers
"""
def getGeneralFlags(self, conf):
flags = super(GccBasicFlags, self).getGeneralFlags(conf)
flags['CXXFLAGS'] += ['-std=c++11']
return flags
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-unused-parameter',
'-Wno-error=deprecated-declarations', # Bug #3795
'-Wno-error=maybe-uninitialized', # Bug #1615
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
return flags
def getOptimizedFlags(self, conf):
@@ -120,32 +148,16 @@ class GccBasicFlags(CompilerFlags):
'-Wextra',
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
return flags
class GccFlags(GccBasicFlags):
def getGeneralFlags(self, conf):
flags = super(GccFlags, self).getGeneralFlags(conf)
version = tuple(int(i) for i in conf.env['CC_VERSION'])
if version < (4, 6, 0):
conf.fatal('The version of gcc you are using (%s) is too old.\n' %
'.'.join(conf.env['CC_VERSION']) +
'The minimum supported gcc version is 4.6.0.')
elif version < (4, 7, 0):
flags['CXXFLAGS'] += ['-std=c++0x']
else:
flags['CXXFLAGS'] += ['-std=c++11']
if version < (4, 8, 0):
flags['DEFINES'] += ['_GLIBCXX_USE_NANOSLEEP'] # Bug #2499
return flags
def getDebugFlags(self, conf):
flags = super(GccFlags, self).getDebugFlags(conf)
version = tuple(int(i) for i in conf.env['CC_VERSION'])
if version < (5, 1, 0):
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
flags['CXXFLAGS'] += ['-Og', # gcc >= 4.8
'-fdiagnostics-color', # gcc >= 4.9
]
flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
return flags
def getOptimizedFlags(self, conf):
@@ -159,7 +171,6 @@ class GccFlags(GccBasicFlags):
class ClangFlags(GccBasicFlags):
def getGeneralFlags(self, conf):
flags = super(ClangFlags, self).getGeneralFlags(conf)
flags['CXXFLAGS'] += ['-std=c++11']
if Utils.unversioned_sys_platform() == 'darwin':
flags['CXXFLAGS'] += ['-stdlib=libc++']
flags['LINKFLAGS'] += ['-stdlib=libc++']
@@ -168,24 +179,24 @@ class ClangFlags(GccBasicFlags):
def getDebugFlags(self, conf):
flags = super(ClangFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
'-Wno-error=unneeded-internal-declaration', # Bug #1588
'-Wno-error=deprecated-register',
'-Wno-error=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-keyword-macro',
'-Wno-error=ignored-qualifiers',
'-Wno-error=infinite-recursion',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
return flags
def getOptimizedFlags(self, conf):
flags = super(ClangFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
'-Wno-keyword-macro',
'-Wno-nested-anon-types',
'-Wno-sign-compare',
'-Wno-keyword-macro',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
return flags
+1 -1
View File
@@ -85,7 +85,7 @@ class doxygen(Task.Task):
# Override with any parameters passed to the task generator
if getattr(self.generator, 'pars', None):
for k, v in self.generator.pars.iteritems():
for k, v in self.generator.pars.items():
self.pars[k] = v
self.doxy_inputs = getattr(self, 'doxy_inputs', [])
-47
View File
@@ -1,47 +0,0 @@
#! /usr/bin/env python
# encoding: utf-8
'''
When using this tool, the wscript will look like:
def options(opt):
opt.tool_options('openssl')
def configure(conf):
conf.load('compiler_cxx openssl')
conf.check_openssl()
def build(bld):
bld(source='main.cpp', target='app', use='OPENSSL')
'''
from waflib import Options
from waflib.Configure import conf
@conf
def check_openssl(self,*k,**kw):
root = k and k[0] or kw.get('path', None) or Options.options.with_openssl
mandatory = kw.get('mandatory', True)
var = kw.get('uselib_store', 'OPENSSL')
if root:
libcrypto = self.check_cxx(lib=['ssl', 'crypto'],
msg='Checking for OpenSSL library',
define_name='HAVE_%s' % var,
global_define=True,
uselib_store=var,
mandatory=mandatory,
includes="%s/include" % root,
libpath="%s/lib" % root)
else:
libcrypto = self.check_cxx(lib=['ssl', 'crypto'],
msg='Checking for OpenSSL library',
define_name='HAVE_%s' % var,
uselib_store=var,
mandatory=mandatory)
def options(opt):
opt.add_option('--with-openssl', type='string', default=None,
dest='with_openssl', help='''Path to OpenSSL''')
-47
View File
@@ -1,47 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
# Philipp Bender, 2012
# Matt Clarkson, 2012
from waflib.Task import Task
from waflib.TaskGen import extension
"""
A simple tool to integrate protocol buffers into your build system.
def configure(conf):
conf.load('compiler_cxx cxx protoc')
def build(bld):
bld(
features = 'cxx cxxprogram'
source = 'main.cpp file1.proto proto/file2.proto',
include = '. proto',
target = 'executable')
"""
class protoc(Task):
run_str = '${PROTOC} ${PROTOC_FLAGS} ${PROTOC_ST:INCPATHS} ${SRC[0].abspath()}'
color = 'BLUE'
ext_out = ['.h', 'pb.cc']
@extension('.proto')
def process_protoc(self, node):
cpp_node = node.change_ext('.pb.cc')
hpp_node = node.change_ext('.pb.h')
self.create_task('protoc', node, [cpp_node, hpp_node])
self.source.append(cpp_node)
if 'cxx' in self.features and not self.env.PROTOC_FLAGS:
self.env.PROTOC_FLAGS = '--cpp_out=%s' % node.parent.get_bld().abspath()
use = getattr(self, 'use', '')
if not 'PROTOBUF' in use:
self.use = self.to_list(use) + ['PROTOBUF']
def configure(conf):
conf.check_cfg(package="protobuf", uselib_store="PROTOBUF", args=['--cflags', '--libs'])
conf.find_program('protoc', var='PROTOC')
conf.env.PROTOC_ST = '-I%s'
+22
View File
@@ -0,0 +1,22 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
def options(opt):
opt.add_option('--with-sanitizer', action='store', default='', dest='sanitizers',
help='Comma-separated list of compiler sanitizers to enable [default=none]')
def configure(conf):
for san in conf.options.sanitizers.split(','):
if not san:
continue
sanflag = '-fsanitize=%s' % san
conf.start_msg('Checking if compiler supports %s' % sanflag)
if conf.check_cxx(cxxflags=['-Werror', sanflag, '-fno-omit-frame-pointer'],
linkflags=[sanflag], mandatory=False):
conf.end_msg('yes')
conf.env.append_unique('CXXFLAGS', [sanflag, '-fno-omit-frame-pointer'])
conf.env.append_unique('LINKFLAGS', [sanflag])
else:
conf.end_msg('no', color='RED')
conf.fatal('%s sanitizer is not supported by the current compiler' % san)
+15 -7
View File
@@ -1,16 +1,18 @@
NLSR Authors
===========
============
NLSR is an open source project includes contributions from the members of the
[NDN project team](http://named-data.net/project/participants/).
## Project lead:
## Project co-leads:
* Vince Lehman <http://vslehman.com>
* Ashlesh Gawande <https://www.linkedin.com/in/agawande>
* Nicholas Gordon <nmgordon@memphis.edu>
## Past project leads:
* A K M Mahmudul Hoque <https://sites.google.com/site/akmhoque/home>
* Vince Lehman <http://vslehman.com>
## Technical advisors:
@@ -24,24 +26,30 @@ NLSR is an open source project includes contributions from the members of the
* The University of Memphis
* A K M Mahmudul Hoque <https://sites.google.com/site/akmhoque/home>
* Ashlesh Gawande <agawande@memphis.edu>
* Minsheng Zhang <mzhang4@memphis.edu>
* 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 <alanwake@ucla.edu>
* Jiewen Tan <https://www.linkedin.com/in/jiewentan>
* University of Arizona
* Junxiao Shi <https://www.cs.arizona.edu/people/shijunxiao/>
* 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
+4 -24
View File
@@ -1,8 +1,7 @@
NLSR LICENSE
============
NLSR is released under the GPL with the additional exemption that
compiling, linking, and/or using OpenSSL is allowed.
NLSR is released under the GPL.
NLSR relies on third-party software and libraries, licensed under the following
licenses:
@@ -10,33 +9,14 @@ licenses:
- Boost libraries are licensed under the conditions of
[Boost Software License 1.0](http://www.boost.org/users/license.html)
- CryptoPP library is licensed under the conditions of
[Boost Software License 1.0](http://www.boost.org/users/license.html)
- log4cxx is licensed under the conditions of
[Apache License, Version 2.0](https://logging.apache.org/log4cxx/license.html)
- ndn-cxx is licensed under the conditions of
[LGPL 3.0](https://github.com/named-data/ndn-cxx/blob/master/COPYING.md)
- protobuf is licensed under the conditions of
[BSD license](https://github.com/google/protobuf/blob/master/LICENSE)
- SQLite is in [public domain](http://www.sqlite.org/copyright.html)
- ChronoSync is licensed under the conditions of
[GPL 3.0](https://github.com/named-data/ChronoSync/blob/master/COPYING.md)
- waf build system is licensed under the conditions of
[BSD license](https://github.com/named-data/ndn-cxx/blob/master/waf)
NLSR also relies on third-party libraries with non-GPL compatible licenses.
These libraries fall into the category of "System Libraries" under GPL
license definitions and are used in accordance with the GPL license exception
for "System Libraries":
- OpenSSL is licensed under an
[Apache-style licence](http://www.openssl.org/source/license.html)
- (OS X platform only) OS X Security Framework is licensed under
[Apple Public Source License](http://www.opensource.apple.com/license/apsl/)
[BSD license](https://github.com/named-data/NLSR/blob/master/waf)
The GPL license is provided below in this file.
For more information, see http://www.gnu.org/licenses/
+6 -3
View File
@@ -28,10 +28,13 @@ Include the following header in all `.hpp` and `.cpp` files:
If you are affiliated with an NSF-supported NDN project institution,
please use the [NDN Team License Boilerplate]
(http://redmine.named-data.net/projects/nlsr/wiki/NDN_Team_License_Boilerplate_(NLSR)).
(https://redmine.named-data.net/projects/nlsr/wiki/NDN_Team_License_Boilerplate_(NLSR)).
Recommendations
---------------
NSLR code is subject to the code style, defined here:
http://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
+14 -6
View File
@@ -4,6 +4,9 @@ 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/).
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).
## Overview
NLSR is a routing protocol in NDN that populates NDN's Routing Information Base. NLSR
@@ -13,10 +16,10 @@ NLSR is an open and free software package licensed under the GPL 3.0 license and
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](http://named-data.net/project/participants/).
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](http://redmine.named-data.net/projects/nlsr).
[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.
NLSR calculates the routing table using link-state or hyperbolic routing and produces
@@ -31,13 +34,18 @@ Source releases
The source code and source-code installation instructions are always available at
the following links:
- [Installation](http://named-data.net/doc/NLSR/current/INSTALL.html)
- [Getting Started with NLSR](http://named-data.net/doc/NLSR/current/GETTING-STARTED.html)
- [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)
Additional information
----------------------
- [NLSR Wiki](http://redmine.named-data.net/projects/nlsr/wiki/)
- [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](http://redmine.named-data.net/projects/nlsr)
[NLSR on NDN Redmine](https://redmine.named-data.net/projects/nlsr)
- [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)
+34 -2
View File
@@ -14,6 +14,20 @@ Installation
:doc:`INSTALL`
Important Notes About Configuration
-----------------------------------
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.
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>`_
Configuration
-------------
@@ -39,8 +53,26 @@ You can also run ``nlsr -f`` with the absolute path of the configuration file:
nlsr -f /usr/local/etc/ndn/nlsr.conf
To run NLSR as daemon, use the ``-d`` flag:
Logging
-------
NLSR uses the ndn-cxx logging facility. All levels listed below the selected log-level
value are enabled.
::
nlsr -d
Valid values:
TRACE trace messages (most verbose)
DEBUG debugging messages
INFO informational messages
WARN warning messages
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.
+2 -38
View File
@@ -12,47 +12,11 @@ Prerequisites
Refer to `Getting started with NFD <http://named-data.net/doc/NFD/current/INSTALL.html>`_
for detailed installation and running instruction.
- log4cxx library
On Ubuntu Linux:
- ChronoSync library
::
sudo apt-get install liblog4cxx10-dev
On OS X with MacPorts:
::
sudo port install log4cxx
- protobuf
On Ubuntu Linux:
::
sudo apt-get install libprotobuf-dev protobuf-compiler
On OS X with MacPorts:
::
sudo port install protobuf-cpp
- openssl
On Ubuntu Linux:
::
sudo apt-get install libssl-dev
On OS X with MacPorts:
::
sudo port install openssl
https://github.com/named-data/ChronoSync#build
Build
-----
+3 -183
View File
@@ -1,184 +1,4 @@
Release Notes
=============
NLSR Release Notes
==================
NLSR version 0.3.0 (changes since version 0.2.2)
++++++++++++++++++++++++++++++++++++++++++++++++
Release date: August 1, 2016
**Code changes**:
- Do not advertise Adjacency LSAs when hyperbolic routing is enabled (:issue:`2402`)
- Do not distribute coordinate LSAs when using link-state routing. (:issue:`3661`)
- LSAs should be segmented before they are published (:issue:`2965`)
- Don't use DummyClientFace::sentDatas (:issue:`3383`)
- Remove disabled security files (:issue:`2960`)
- Lsa type should be argument for base class LSA constructor (:issue:`2788`)
- Use ndn-cxx/DummyClientFace (:issue:`2637`)
**Bug fixes**:
- Unit tests cases are installed with `./waf install` (:issue:`3359`)
NLSR version 0.2.2 (changes since version 0.2.1)
++++++++++++++++++++++++++++++++++++++++++++++++
Release date: January 5, 2016
**Code changes**:
- Adapt code to changes in NFD/ndn-cxx version 0.4.0 release
NLSR version 0.2.1 (changes since version 0.2.0)
++++++++++++++++++++++++++++++++++++++++++++++++
Release date: June 30, 2015
**Code changes**:
- Using a configuration file without ``prefix-update-validator`` disables runtime advertise/withdraw instead of exiting (:issue:`2814`)
**Bug fixes**:
- Prevent incomplete removal of NPT entry (:issue:`2785`)
- Correct bidirectional links with differing costs (:issue:`2801`)
- Fix non-incrementing Adjacency number in AdjLsa::writeLog (:issue:`2594`)
- Remove FaceDestroyEvent test's reliance on nlsrSeqNo.txt (:issue:`2881`)
- Test ACTIVE/INACTIVE Adjacencies in LSA construction (:issue:`2735`)
NLSR version 0.2.0 (changes since version 0.1.0)
++++++++++++++++++++++++++++++++++++++++++++++++
Release date: April 30, 2015
**Build**:
- The code now requires C++11. The minimum supported gcc version is 4.6, as earlier versions do not have proper support for C++11 features. (:issue:`1930`)
- Require OpenSSL (:issue:`2375`)
**New features**:
- Add nlsrc command-line tool (:issue:`1834`)
- Advertise/Withdraw name prefixes at runtime (:issue:`1834`)
- Assign zero cost to hyperbolic direct neighbors (:issue:`1975`)
- Only hyperbolic costs are adjusted before registering (:issue:`1974`)
- Add ability to specify different logging levels (:issue:`1935`)
- Add LSDB dataset publishers (:issue:`2280`)
- Add LSDB dataset tlv abstractions (:issue:`2280`)
- Allow zero cost neighbors for hyperbolic routing table calculation (:issue:`1982`)
- Faces are now created with canonical Face URI (:issue:`1911`)
- Add configurable router event intervals (:issue:`2071`)
- Add router-dead-interval configuration setting (:issue:`1878`)
- Add log formatting specified by log4cxx configuration file (:issue:`1950`)
- Face URIs in configuration file are checked for validity on load (:issue:`2070`)
- Configuration variables with default values are now optional (:issue:`1949`)
- Recalculate routing table after face destroy event (:issue:`2635`)
- Add Travis-CI build script
**Code changes**:
- Change adjacency status from uint32_t to enum (:issue:`1946`)
- Remove scheduler from NLSR class (:issue:`1981`)
- Change hyperbolic cost adjustment factor from 100 to 1000 (:issue:`1974`)
- Remove use of outdated namespace ``ndn::Tlv`` (:issue:`2079`)
- Remove use of deprecated ``ndn::nfd::Controller(Face&)`` constructor (:issue:`2133`)
- Routing update publishing is abstracted to SyncLogicHandler (:issue:`2289`)
- Make ConfParameter variable types consistent with min and max values (:issue:`2084`)
- Replace LSA string literals with constants (:issue:`2310`)
- Subscribe to FaceMonitor notifications using connect (:issue:`2350`)
- Log exceptions thrown in event loop
- Change ``ndn::ptr_lib::shared_ptr`` to ``std::shared_ptr`` (:issue:`2110`)
- Avoid deprecated ``ndn::Name::set`` method (:issue:`2505`)
- Update waf to version 1.8.8-dev
- Add sorting tiebreaker to NexthopList (:issue:`2715`)
- Update Jenkins-CI build scripts
**Bug fixes**:
- Fix python3 build error (:issue:`1956`)
- Fix typos in nlsr.conf security section (:issue:`1985`)
- Stop SyncLogicHandler from fetching a router’s own LSAs (:issue:`2005`)
- Fix Name LSA comparison which could cause incorrect advertised names to be removed (:issue:`2029`)
- Fix issue where more faces than max-faces-per-prefix could be applied to a prefix (:issue:`2018`)
- Stop LSDB from retrieving and out of date LSA when a new one is detected (:issue:`1987`)
- Correct mistakes in documentation
- Correct bitmask used to copy Name LSA sequence number (:issue:`2323`)
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
link-state or hyperbolic routing and produces multiple faces for each reachable name
prefix in a single authoritative domain.
**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
- 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
- Set up NFD tunnels to neighbors automatically and maintain the tunnels to neighbors
- Provide two routing protocols:
+ Link State routing: calculate route cost based on link costs
+ Hyperbolic routing: calculate route cost based on hyperbolic coordinates
- Use a hierarchical trust model for routing within a single administrative domain
- Keep NFD’s RIB updated on failure and recovery
.. include:: release-notes-latest.rst
+89 -24
View File
@@ -42,9 +42,9 @@ Type the following in the terminal:
::
nfd-status -f
nfd-status
If you see ``ERROR: error while connecting to the forwarder (No such file or directory)``,
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.
@@ -83,11 +83,7 @@ configuration commands follows:
; InterestLifetime (in seconds) for LSA fetching
lsa-interest-lifetime 4 ; default value 4. Valid values 1-60
; log-level is to set the levels of log for NLSR
log-level INFO ; default value INFO, valid value DEBUG, INFO
log-dir /var/log/nlsr/
seq-dir /var/lib/nlsr/
; log4cxx-conf /path/to/log4cxx-conf
}
; the neighbors section contains the configuration for router's neighbors and hello's behavior
@@ -106,11 +102,12 @@ configuration commands follows:
hello-interval 60 ; interest sending interval in seconds. Default value 60
; valid values 30-90
; 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 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
; 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
@@ -121,8 +118,8 @@ configuration commands follows:
neighbor
{
name /ndn/edu/arizona/%C1.Router/router3 ; name prefix of the neighbor router consists
; of network, site-name and router-name
name /ndn/edu/arizona/%C1.Router/router3 ; name prefix of the neighbor router consists
; of network, site-name and router-name
face-uri udp4://router3.arizona.edu ; face uri of the face connected to the neighbor
link-cost 25 ; cost of the connecting link to neighbor
@@ -130,7 +127,7 @@ configuration commands follows:
neighbor
{
name /ndn/edu/colostate/%C1.Router/router2 ; name prefix of the neighbor router consists
name /ndn/edu/colostate/%C1.Router/router2 ; name prefix of the neighbor router consists
; of network, site-name and router-name
face-uri udp4://79.123.10.145 ; face uri of the face connected to the neighbor
@@ -147,9 +144,9 @@ configuration commands follows:
; commands in this section follows a strict order
; the switch is used to set hyperbolic routing calculation in NLSR
state off ; default value 'off', set value 'on' to enable hyperbolic routing table
; calculation which turns link state routing 'off'. set value to 'dry-run'
; to test hyperbolic routing and compare with link state routing.
state off ; default value 'off', set value 'on' to enable hyperbolic routing table
; calculation which turns link state routing 'off'. set value to 'dry-run'
; to test hyperbolic routing and compare with link state routing.
radius 123.456 ; radius of the router in hyperbolic coordinate system
@@ -164,8 +161,8 @@ configuration commands follows:
; the max-faces-per-prefix is used to limit the number of faces for each name prefixes
; by NLSR in ndn FIB
max-faces-per-prefix 3 ; default value 0. Valid value 0-60. By default (value 0) NLSR adds
; all available faces for each reachable name prefixes in NDN FIB
max-faces-per-prefix 3 ; default value 0. Valid value 0-60. By default (value 0) NLSR adds
; all available faces for each reachable name prefixes in NDN FIB
}
@@ -182,10 +179,78 @@ configuration commands follows:
prefix /ndn/news/memphis/politics/lutherking
}
.. note::
By default NLSR's sequence file directory is set to ``/var/lib/nlsr/``. User must create this
directory before starting NLSR. Since this is a system directory, NLSR must either be executed
as root, or NLSR can be run as user "nlsr" after configuring the filesystem to grant "nlsr"
read and write permissions. If user lacks permissions, the following error will occur:
Security configuration is discussed in :doc:`SECURITY-CONFIG`, which will be also part
of this configuration file
::
User does not have read and write permission on the directory
Error in configuration file processing! Exiting from NLSR
To avoid this, the directory can be set in a user-owned directory. For example:
::
general
{
...
seq-dir /home/username/nlsr/log ; path for sequence directory (Absolute path)
}
...
The user will encounter errors such as the following if security is not configured:
::
Cannot read certificate from file: /home/username/NLSR/root.cert
To get rid of this and similar errors relating to security one has to configure security
as described in :doc:`SECURITY-CONFIG`. Security can be disabled for testing purposes as follows:
::
...
trust-anchor
{
type any
;file-name "root.cert"
}
...
trust-anchor
{
type any
;file-name "site.cert"
}
; cert-to-publish "root.cert"
; cert-to-publish "router.cert"
; cert-to-publish "site.cert"
; cert-to-publish "router.cert"
Or by simply replacing the whole security section with:
::
security
{
validator
{
trust-anchor
{
type any
}
}
prefix-update-validator
{
trust-anchor
{
type any
}
}
}
Step 4: Running NLSR on /ndn/memphis.edu/router1
-------------------------------------------------
@@ -207,9 +272,9 @@ The same process needs to be followed for ``/ndn/arizona.edu/router3`` and
Expected Output
----------------
Assuming that all three routers are configured correctly and routing has converged, ``nfd-status`` in
``/ndn/edu/colostate/%C1.Router/router2`` will have the following entries for the name
advertised by ``/ndn/edu/memphis/%C1.Router/router1``:
Assuming that all three routers are configured correctly and routing has converged,
``nfd-status`` in ``/ndn/edu/colostate/%C1.Router/router2`` will have the following (or similar)
entries for the name advertised by ``/ndn/edu/memphis/%C1.Router/router1``:
RIB:
@@ -219,7 +284,7 @@ RIB:
/ndn/memphis/sports/basketball/grizzlies route={faceid=17 (origin=128 cost=25 ChildInherit), faceid=7 (origin=128 cost=58 ChildInherit)}
/ndn/news/memphis/politics/lutherking route={faceid=17 (origin=128 cost=25 ChildInherit, faceid=7 (origin=128 cost=58 ChildInherit)}
This output can be seen by typing ``nfd-status -r`` in the terminal. Please refer to the
This output can be seen by typing ``nfdc route list`` in the terminal. Please refer to the
network figure for face IDs.
.. _hyperbolic routing table calculation: http://arxiv.org/abs/0805.1266
+11 -6
View File
@@ -20,7 +20,7 @@ The trust model of NLSR is semi-hierarchical. An example certificate signing hie
router1 router2 router3 router4 router5 router6 router7
| | | | | | |
+ + + + + + +
NLSR NSLR NSLR NSLR NSLR NSLR NSLR
NLSR NLSR NLSR NLSR NLSR NLSR NLSR
Each entity's name and corresponding certificate name follow the
convention below:
@@ -28,15 +28,20 @@ convention below:
======== ===================================================== ================================= ===============================================
Entity Identity Name Example Certificate Name Example
-------- ----------------------------------------------------- --------------------------------- -----------------------------------------------
root /\<network\> /ndn /ndn/KEY/ksk-1/ID-CERT/%01
site /\<network\>/\<site\> /ndn/edu/ucla /ndn/edu/ucla/KEY/ksk-2/ID-CERT/%01
operator /\<network\>/\<site\>/%C1.Operator/\<operator-name\> /ndn/edu/ucla/%C1.Operator/op1 /ndn/edu/ucla/%C1.Operator/op1/KEY/ksk-3/ID-CERT/%01
router /\<network\>/\<site\>/%C1.Router/\<router-name\> /ndn/edu/ucla/%C1.Router/rt1 /ndn/edu/ucla/%C1.Router/rt1/KEY/ksk-4/ID-CERT/%01
NLSR /\<network\>/\<site\>/%C1.Router/\<router-name\>/NLSR /ndn/edu/ucla/%C1.Router/rt1/NLSR /ndn/edu/ucla/%C1.Router/rt1/NLSR/KEY/ksk-5/ID-CERT/%01
root /\<network\> /ndn /ndn/KEY/1/%00/%01
site /\<network\>/\<site\> /ndn/edu/ucla /ndn/edu/ucla/KEY/2/%00/%01
operator /\<network\>/\<site\>/%C1.Operator/\<operator-name\> /ndn/edu/ucla/%C1.Operator/op1 /ndn/edu/ucla/%C1.Operator/op1/KEY/3/%00/%01
router /\<network\>/\<site\>/%C1.Router/\<router-name\> /ndn/edu/ucla/%C1.Router/rt1 /ndn/edu/ucla/%C1.Router/rt1/KEY/4/%00/%01
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.
.. note::
Detailed information about key setup is given in NLSR Developer's Guide.
Certificate Publishing
----------------------
+4 -3
View File
@@ -12,6 +12,7 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
import datetime
import sys
import os
@@ -30,7 +31,7 @@ sys.path.insert(0, os.path.abspath('.'))
# ones.
extensions = [
'sphinx.ext.todo',
'redmine_issue',
'redmine_issue'
]
def addExtensionIfExists(extension):
@@ -60,7 +61,7 @@ master_doc = 'index'
# General information about the project.
project = u'NLSR - Named Data Link State Routing Protocol'
copyright = u'2014-2015, Named Data Networking Project'
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
@@ -251,4 +252,4 @@ if os.getenv('GOOGLE_ANALYTICS', None):
googleanalytics_id = os.environ['GOOGLE_ANALYTICS']
googleanalytics_enabled = True
redmine_project_url = "http://redmine.named-data.net/"
redmine_project_url = "https://redmine.named-data.net/"
+4 -4
View File
@@ -408,7 +408,7 @@ EXTRACT_PRIVATE = NO
# scope will be included in the documentation.
# The default value is: NO.
EXTRACT_PACKAGE = NO
EXTRACT_PACKAGE = YES
# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
# included in the documentation.
@@ -2025,7 +2025,7 @@ MSCGEN_PATH =
# and usage relations if the target is undocumented or is not a class.
# The default value is: YES.
HIDE_UNDOC_RELATIONS = YES
HIDE_UNDOC_RELATIONS = NO
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz (see:
@@ -2150,7 +2150,7 @@ INCLUDED_BY_GRAPH = YES
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALL_GRAPH = NO
CALL_GRAPH = YES
# 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 +2161,7 @@ CALL_GRAPH = NO
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALLER_GRAPH = NO
CALLER_GRAPH = YES
# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
# hierarchy of all classes instead of a textual one.
+26 -5
View File
@@ -3,7 +3,7 @@ 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
<http://named-data.net/doc/ndn-tlv/>`_.
<https://named-data.net/doc/ndn-tlv/>`_.
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
@@ -11,7 +11,7 @@ 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
<http://named-data.net/project/participants/>`_. For more details, please refer to
<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`_.
@@ -29,11 +29,12 @@ NLSR Documentation
:hidden:
:maxdepth: 3
RELEASE-NOTES
GETTING-STARTED
INSTALL
ROUTER-CONFIG
SECURITY-CONFIG
RELEASE-NOTES
releases
manpages
- :doc:`GETTING-STARTED`
@@ -41,6 +42,7 @@ NLSR Documentation
- :doc:`ROUTER-CONFIG`
- :doc:`SECURITY-CONFIG`
- :doc:`RELEASE-NOTES`
- :doc:`releases`
- :doc:`manpages`
Downloading
@@ -48,14 +50,33 @@ Downloading
- `GitHub NLSR repository <https://github.com/named-data/NLSR>`_
NLSR mailing list
-----------------
- `NLSR Mailing List`_
- `NLSR Mailing List Archives`_
`Sign up`_ is needed to post to the list or access the archives.
Additional information
----------------------
- `NLSR Wiki`_
- `NLSR Redmine`_
Feature requests and bug reports
- `NLSR Paper`_
Detailed explanation of the NLSR design
- `NLSR Developer's Guide`_
For NLSR Development
.. _NLSR Wiki: http://redmine.named-data.net/projects/nlsr
.. _NLSR Paper: http://www.cs.memphis.edu/~lanwang/paper/nlsr-final.pdf
.. _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
.. _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
.. _Sign up: https://listserv.memphis.edu/scripts/wa.exe?GETPW1
.. _NLSR Redmine: https://redmine.named-data.net/projects/nlsr
+2 -12
View File
@@ -12,16 +12,12 @@ Usage
Description
-----------
``nlsr`` is a daemon that implements routing protocol in NDN to populates NDN's Routing
``nlsr`` is a process that implements routing protocol in NDN to populate NDN's Routing
Information Base.
Options:
--------
``-d``
Run in daemon mode
``-f <FILE>``
Specify configuration file name (default: ``./nlsr.conf``)
@@ -34,14 +30,8 @@ Options:
Examples
--------
To run NLSR daemon and use a configuration file from the ``/path/to`` directory.
To run NLSR and use a configuration file from the ``/path/to`` directory.
::
nlsr -f /path/to/nlsr.conf
To run NLSR as daemon, use the ``-d`` flag:
::
nlsr -d
+20 -1
View File
@@ -26,9 +26,15 @@ Options
``COMMAND``
``status``
``lsdb``
Retrieve LSDB status information
``routing``
Retrieve routing table status information
``status``
Retrieve LSDB status and routing table status information
``advertise``
Add a Name prefix to be advertised by NLSR
@@ -45,6 +51,19 @@ Options
``name``
The Name prefix to be withdrawn
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'.
Example:
ndnsec-set-default /ndn/a-site/%C1.Operator/op
Exit Status
-----------
+1 -1
View File
@@ -32,7 +32,7 @@ $mathjax
<!--top menu-->
<div class="nine columns" id="menu_container" >
<h1><a href="http://named-data.net/doc/NFD/$projectnumber/">$projectname $projectnumber documentation</a></h1>
<h1><a href="http://named-data.net/doc/NLSR/$projectnumber/">$projectname $projectnumber documentation</a></h1>
</div>
</div>
</div><!--header container end-->
+3 -3
View File
@@ -50,8 +50,8 @@ def make_link_node(rawtext, app, type, slug, options):
base = app.config.redmine_project_url
if not base:
raise AttributeError
except AttributeError, err:
raise ValueError('redmine_project_url configuration value is not set (%s)' % str(err))
except AttributeError:
raise ValueError('redmine_project_url configuration value is not set')
#
slash = '/' if base[-1] != '/' else ''
ref = base + slash + type + '/' + slug + '/'
@@ -67,4 +67,4 @@ def setup(app):
"""
app.add_role('issue', redmine_role)
app.add_config_value('redmine_project_url', None, 'env')
return
return
+1
View File
@@ -0,0 +1 @@
release-notes/release-notes-0.4.0.rst
@@ -0,0 +1,30 @@
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
link-state or hyperbolic routing and produces multiple faces for each reachable name
prefix in a single authoritative domain.
**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
- 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
- Set up NFD tunnels to neighbors automatically and maintain the tunnels to neighbors
- Provide two routing protocols:
+ Link State routing: calculate route cost based on link costs
+ Hyperbolic routing: calculate route cost based on hyperbolic coordinates
- Use a hierarchical trust model for routing within a single administrative domain
- Keep NFD’s RIB updated on failure and recovery
@@ -0,0 +1,94 @@
NLSR version 0.2.0 (changes since version 0.1.0)
++++++++++++++++++++++++++++++++++++++++++++++++
Release date: April 30, 2015
**Build**:
- The code now requires C++11. The minimum supported gcc version is 4.6, as earlier versions do not have proper support for C++11 features. (:issue:`1930`)
- Require OpenSSL (:issue:`2375`)
**New features**:
- Add nlsrc command-line tool (:issue:`1834`)
- Advertise/Withdraw name prefixes at runtime (:issue:`1834`)
- Assign zero cost to hyperbolic direct neighbors (:issue:`1975`)
- Only hyperbolic costs are adjusted before registering (:issue:`1974`)
- Add ability to specify different logging levels (:issue:`1935`)
- Add LSDB dataset publishers (:issue:`2280`)
- Add LSDB dataset tlv abstractions (:issue:`2280`)
- Allow zero cost neighbors for hyperbolic routing table calculation (:issue:`1982`)
- Faces are now created with canonical Face URI (:issue:`1911`)
- Add configurable router event intervals (:issue:`2071`)
- Add router-dead-interval configuration setting (:issue:`1878`)
- Add log formatting specified by log4cxx configuration file (:issue:`1950`)
- Face URIs in configuration file are checked for validity on load (:issue:`2070`)
- Configuration variables with default values are now optional (:issue:`1949`)
- Recalculate routing table after face destroy event (:issue:`2635`)
- Add Travis-CI build script
**Code changes**:
- Change adjacency status from uint32_t to enum (:issue:`1946`)
- Remove scheduler from NLSR class (:issue:`1981`)
- Change hyperbolic cost adjustment factor from 100 to 1000 (:issue:`1974`)
- Remove use of outdated namespace ``ndn::Tlv`` (:issue:`2079`)
- Remove use of deprecated ``ndn::nfd::Controller(Face&)`` constructor (:issue:`2133`)
- Routing update publishing is abstracted to SyncLogicHandler (:issue:`2289`)
- Make ConfParameter variable types consistent with min and max values (:issue:`2084`)
- Replace LSA string literals with constants (:issue:`2310`)
- Subscribe to FaceMonitor notifications using connect (:issue:`2350`)
- Log exceptions thrown in event loop
- Change ``ndn::ptr_lib::shared_ptr`` to ``std::shared_ptr`` (:issue:`2110`)
- Avoid deprecated ``ndn::Name::set`` method (:issue:`2505`)
- Update waf to version 1.8.8-dev
- Add sorting tiebreaker to NexthopList (:issue:`2715`)
- Update Jenkins-CI build scripts
**Bug fixes**:
- Fix python3 build error (:issue:`1956`)
- Fix typos in nlsr.conf security section (:issue:`1985`)
- Stop SyncLogicHandler from fetching a router’s own LSAs (:issue:`2005`)
- Fix Name LSA comparison which could cause incorrect advertised names to be removed (:issue:`2029`)
- Fix issue where more faces than max-faces-per-prefix could be applied to a prefix (:issue:`2018`)
- Stop LSDB from retrieving and out of date LSA when a new one is detected (:issue:`1987`)
- Correct mistakes in documentation
- Correct bitmask used to copy Name LSA sequence number (:issue:`2323`)
@@ -0,0 +1,20 @@
NLSR version 0.2.1 (changes since version 0.2.0)
++++++++++++++++++++++++++++++++++++++++++++++++
Release date: June 30, 2015
**Code changes**:
- Using a configuration file without ``prefix-update-validator`` disables runtime advertise/withdraw instead of exiting (:issue:`2814`)
**Bug fixes**:
- Prevent incomplete removal of NPT entry (:issue:`2785`)
- Correct bidirectional links with differing costs (:issue:`2801`)
- Fix non-incrementing Adjacency number in AdjLsa::writeLog (:issue:`2594`)
- Remove FaceDestroyEvent test's reliance on nlsrSeqNo.txt (:issue:`2881`)
- Test ACTIVE/INACTIVE Adjacencies in LSA construction (:issue:`2735`)
@@ -0,0 +1,8 @@
NLSR version 0.2.2 (changes since version 0.2.1)
++++++++++++++++++++++++++++++++++++++++++++++++
Release date: January 5, 2016
**Code changes**:
- Adapt code to changes in NFD/ndn-cxx version 0.4.0 release
@@ -0,0 +1,26 @@
NLSR version 0.3.0 (changes since version 0.2.2)
++++++++++++++++++++++++++++++++++++++++++++++++
Release date: August 1, 2016
**Code changes**:
- Updated validation checker for LSA rule in the configuration file (:issue:`2965`)
- Do not advertise Adjacency LSAs when hyperbolic routing is enabled (:issue:`2402`)
- Do not distribute coordinate LSAs when using link-state routing. (:issue:`3661`)
- LSAs should be segmented before they are published (:issue:`2965`)
- Don't use DummyClientFace::sentDatas (:issue:`3383`)
- Remove disabled security files (:issue:`2960`)
- Lsa type should be argument for base class LSA constructor (:issue:`2788`)
- Use ndn-cxx/DummyClientFace (:issue:`2637`)
**Bug fixes**:
- Unit tests cases are installed with `./waf install` (:issue:`3359`)
@@ -0,0 +1,34 @@
NLSR version 0.3.1 (changes since version 0.3.0)
++++++++++++++++++++++++++++++++++++++++++++++++
Release date: January 22, 2017
**Changes**
- **breaking change** Sync uses /localhop component in prefix to reduce duplicate NACKs (:issue:`3627`)
- **breaking change** LSA uses /localhop component in prefix to reduce duplicate NACKs (:issue:`3899`)
**Code Changes**:
- Fib and FaceMap use std::map instead of std::list (:issue:`2781`)
- NamePrefixTableEntries store RoutingTableEntries using a pointer (:issue:`2863`)
- Namespace closing comments are now consistent with ndn-cxx guidelines (:issue:`3735`)
- Update copyright date across all files (:issue:`3736`, `3909`, `3923`)
- Improve formatting of FaceMap and FaceMapEntry (:issue:`3737`)
- Sort NextHops on NexthopList insertion (:issue:`2721`)
**Bug fixes**:
- HR now recalculates paths after status change of a neighbor (:issue:`3874`)
- NLSR no longer sets strategies multiple times (:issue:`3743`)
- NLSR should enable use of ndn-cxx dispatcher (:issue:`3930`)
- Fix typos in the sample configuration file (:issue:`3113`)
@@ -0,0 +1,20 @@
NLSR version 0.3.2 (changes since version 0.3.1)
++++++++++++++++++++++++++++++++++++++++++++++++
Release date: March 15, 2017
**Changes**
- NLSR constructor now accept a KeyChain argument. (:issue:`3742`)
- Fix security rule for /localhop LSA prefix (:issue:`3899`)
- Use ndn::nfd::ROUTE_ORIGIN_NLSR instead of a magic number. (:issue:`3903`)
- Handle "Face Already Exists" error (error code 409) in NFD. (:issue:`3976`)
- Enable NLSR to register localhost prefix with dispatcher before top-level prefix. (:issue:`3938`)
- Don't use ndn aliases provided by ndn-cxx/common.hpp. (:issue:`3983`)
- Remove use of deprecated code. (:issue:`3988`)
@@ -0,0 +1,79 @@
NLSR version 0.4.0
++++++++++++++++++
**New features**:
- **breaking change** Discover Faces from NFD (:issue:`2954`)
- **breaking change** Accommodate n-Dimensional HR coordinates (:issue:`3751`)
**Changes**:
- **breaking change** Make chronosync a dependency (:issue:`2400`)
- **breaking change** Use separate name prefix and sequence number
for each LSA type (:issue:`3964`)
- **breaking change** Convert to ``v2::security`` and adapt to ndn-cxx changes (:issue:`3964`)
- Use unix timestamp as default (:issue:`4187`)
**Bug Fixes**:
- Add support for sources to NamePrefixList (:issue:`4177`)
- Fix incorrect error on face-dataset-fetch-interval valid values (:issue:`4211`)
- Fix prefix advertise runtime error (:issue:`4215`)
- Fix heap buffer overflow error (:issue:`4217`)
**Code Changes**:
- LSA getData() now uses ostream instead of manually building the string (:issue:`2346`)
- Refresh FIB entries independently of routing table calculation (:issue:`2778`)
- Change configuration parameter output level to info (:issue:`2850`)
- Updates to name prefixes are more efficient (:issue:`2864`)
- Implement statistics collector/recorder (:issue:`2956`)
- Implement ``NameLsa::isEqualContent`` (:issue:`2962`)
- Refactor ``Fib::removeOldNextHopsFromFibEntryAndNfd()`` for simplicity, readability. (:issue:`3820`)
- Improve logging throughout lsdb.cpp and others (:issue:`3934`)
- Enable dispatcher for LOCALHOST_PREFIX (:issue:`3938`)
- Don't use ndn aliases provided by ndn-cxx/common.hpp (:issue:`3983`)
- Canonize Adjacent FaceURIs on startup (:issue:`4063`)
- Refactor AdjacencyList to use iterators instead of bare ptrs (:issue:`4068`)
- Merge redundant functions (:issue:`4105`)
- Remove writeLog in NamePrefixList (:issue:`4131`)
- Check for self in ChronoSync updates (:issue:`4134`)
- Install nlsr.conf as sample in the system (:issue:`4197`)
- Enable AddressSanitizer and LeakSanitizer for unit tests (:issue:`4206`)
- Resolve all ASan errors in unit tests (:issue:`4230`)
- Simplified LSDB dataset interest handler. (:issue:`4235`)
- Made map more container-agnostic (:issue:`4239`)
- Improved routing map data structure. (:issue:`4240`)
- Increased independence of SyncLogicHandler (:issue:`4264`)
- Use unique_ptr for signal container (:issue:`4268`)
- Use network name in sync prefix to avoid sync leaks from other networks (:issue:`4101`)
@@ -0,0 +1,24 @@
NLSR version 0.4.1
++++++++++++++++++
**New features**:
- The routing table dataset publisher (:issue:`3630`)
- Use ndn-cxx logging facility, remove log4cxx dependency (:issue:`3949`)
- Automatic serving of other routers' certificates (:issue:`4448`)
**Bug Fixes**:
- Hard-code a fixed session name for ChronoSync sockets (:issue:`4513`)
- Fix encoding bug in the routing table publisher (:issue:`4453`)
- Fix NLSR not converging without content store (:issue:`4430`)
**Miscellaneous Changes**:
- Make ChronoSync's sync interest lifetime configurable (:issue:`4490`)
- Print labels on adjacency matrix when logging (:issue:`2045`)
+70
View File
@@ -0,0 +1,70 @@
NLSR Versions
+++++++++++++
.. toctree::
:hidden:
:maxdepth: 1
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
* **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/>`__)
`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/>`__)
`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/>`__)
`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/>`__)
`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/>`__)
`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/>`__)
`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/>`__)
`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/>`__)
`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/>`__)
`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>`__)
-11
View File
@@ -1,11 +0,0 @@
log4j.rootLogger=DEBUG, Rolling
log4j.appender.Rolling=org.apache.log4j.rolling.RollingFileAppender
log4j.appender.Rolling.File=/tmp/testnlsrproperties.log
log4j.appender.Rolling.MaxSize=1MB
log4j.appender.Rolling.MaxBackupIndex=10
log4j.appender.Rolling.layout=PatternLayout
log4j.appender.Rolling.layout.ContextPrinting=enabled
log4j.appender.Rolling.layout.DateFormat=ISO8601
log4j.appender.Rolling.layout.ConversionPattern=%date{yyyyMMddHHmmssSSS} %p: [%c] %m%n
+34 -35
View File
@@ -11,7 +11,7 @@ general
; lsa-refresh-time is the time in seconds, after which router will refresh its LSAs
lsa-refresh-time 1800 ; default value 1800. Valid values 240-7200
; router-dead-interval is the time in seconds after which an inactive router's
; router-dead-interval is the time in seconds after which an inactive routers
; LSAs are removed
;router-dead-interval 3600 ; default value: 2*lsa-refresh-time. Value must be larger
; than lsa-refresh-time
@@ -19,27 +19,13 @@ general
; InterestLifetime (in seconds) for LSA fetching
lsa-interest-lifetime 4 ; default value 4. Valid values 1-60
; log-level is used to set the logging level for NLSR.
; All debugging levels listed above the selected value are enabled.
;
; Valid values:
;
; NONE ; no messages
; ERROR ; error messages
; WARN ; warning messages
; INFO ; informational messages (default)
; DEBUG ; debugging messages
; TRACE ; trace messages (most verbose)
; ALL ; all messages
; sync interest lifetime of ChronoSync in milliseconds
sync-interest-lifetime 60000 ; default value 60000. Valid values 1000-120,000
log-level INFO
log-dir /var/log/nlsr/ ; path for log directory (Absolute path)
seq-dir /var/lib/nlsr/ ; path for sequence directory (Absolute path)
;log4cxx-conf /path/to/log4cxx-conf ; path for log4cxx configuration file (Absolute path)
seq-dir /var/lib/nlsr ; path for sequence directory (Absolute path)
}
; the neighbors section contains the configuration for router's neighbors and hello's behavior
; the neighbor's section contains the configuration for router's neighbors and hellos behavior
neighbors
{
@@ -65,6 +51,16 @@ neighbors
first-hello-interval 10 ; Default value 10. Valid values 0-10
face-dataset-fetch-tries 3 ; default is 3. Valid values 1-10. The FaceDataset is
; gotten from NFD, and is needed to configure NLSR
; correctly. It is recommended not to set this
; variable too high, because it could cause
; congestion for NFD.
face-dataset-fetch-interval 3600 ; default is 3600. Valid values 1800-5400.
; This controls how often (in seconds) NLSR will attempt to
; fetch a FaceStatus dataset from NFD.
; neighbor command is used to configure router's neighbor. Each neighbor will need
; one block of neighbor command
@@ -101,11 +97,11 @@ hyperbolic
radius 123.456 ; radius of the router in hyperbolic coordinate system
angle 1.45 ; angle of the router in hyperbolic coordinate system
angle 1.45,2.36 ; angle of the router in hyperbolic coordinate system
}
; the fib section is used to configure fib entry's type to ndn FIB updated by NLSR
; the fib section is used to configure fib entrys type to ndn FIB updated by NLSR
fib
{
@@ -140,7 +136,7 @@ security
{
rule
{
id "NSLR Hello Rule"
id "NLSR Hello Rule"
for data
filter
{
@@ -156,7 +152,7 @@ security
type name
hyper-relation
{
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><>$
k-expand \\1
h-relation equal
p-regex ^([^<NLSR><INFO>]*)<NLSR><INFO><><>$
@@ -168,7 +164,7 @@ security
rule
{
id "NSLR LSA Rule"
id "NLSR LSA Rule"
for data
filter
{
@@ -184,11 +180,11 @@ security
type name
hyper-relation
{
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><>$
k-expand \\1
h-relation equal
; the last four components in the prefix should be <lsaType><seqNo><version><segmentNo>
p-regex ^([^<NLSR><LSA>]*)<NLSR><LSA>(<>*)<><><><>$
p-regex ^<localhop>([^<NLSR><LSA>]*)<NLSR><LSA>(<>*)<><><><>$
p-expand \\1\\2
}
}
@@ -197,12 +193,12 @@ security
rule
{
id "NSLR Hierarchy Exception Rule"
id "NLSR Hierarchy Exception Rule"
for data
filter
{
type name
regex ^[^<KEY><%C1.Router>]*<%C1.Router>[^<KEY><NLSR>]*<KEY><ksk-.*><ID-CERT><>$
regex ^[^<KEY><%C1.Router>]*<%C1.Router>[^<KEY><NLSR>]*<KEY><><><>$
}
checker
{
@@ -213,10 +209,10 @@ security
type name
hyper-relation
{
k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
k-expand \\1
h-relation equal
p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><><><>$
p-expand \\1
}
}
@@ -225,12 +221,12 @@ security
rule
{
id "NSLR Hierarchical Rule"
id "NLSR Hierarchical Rule"
for data
filter
{
type name
regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
regex ^[^<KEY>]*<KEY><><><>$
}
checker
{
@@ -255,7 +251,9 @@ security
filter
{
type name
regex ^<localhost><nlsr><prefix-update>[<advertise><withdraw>]<>$
; /<prefix>/<management-module>/<command-verb>/<control-parameters>
; /<timestamp>/<random-value>/<signed-interests-components>
regex ^<localhost><nlsr><prefix-update>[<advertise><withdraw>]<><><>$
}
checker
{
@@ -264,7 +262,7 @@ security
key-locator
{
type name
regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
}
}
}
@@ -276,7 +274,7 @@ security
filter
{
type name
regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
regex ^[^<KEY>]*<KEY><><><>$
}
checker
{
@@ -291,6 +289,7 @@ security
file-name "site.cert"
}
}
; cert-to-publish "root.cert" ; optional, a file containing the root certificate
; Only the router that is designated to publish the root cert
; needs to specify this
-3
View File
@@ -1,3 +0,0 @@
nsync is a copy of ChronoSync (https://github.com/bruinfish/ChronoSync/tree/master).
ChonoSync's license is GPL2.
-15
View File
@@ -1,15 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 University of Memphis,
* Regents of the University of California
*
* See COPYING.md for copyright and distribution information.
*/
// suppress Boost::archive warnings
#pragma GCC system_header
#pragma clang system_header
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/archive/iterators/dataflow_exception.hpp>
-21
View File
@@ -1,21 +0,0 @@
#ifndef NSYNC_OPENSSL_H
#define NSYNC_OPENSSL_H
// suppress deprecation warnings in OSX >= 10.7
#if defined(__APPLE__)
#ifdef __clang__
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif // __clang__
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif // __GNUC__
#endif
#include <openssl/evp.h>
#endif // NSYNC_OPENSSL_H
-74
View File
@@ -1,74 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-diff-leaf.h"
#include <boost/throw_exception.hpp>
typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info;
using namespace Sync::Error;
namespace Sync {
DiffLeaf::DiffLeaf (NameInfoConstPtr info, const SeqNo &seq)
: Leaf (info, seq)
, m_op (UPDATE)
{
}
DiffLeaf::DiffLeaf (NameInfoConstPtr info)
: Leaf (info, SeqNo (0,0))
, m_op (REMOVE)
{
}
std::ostream &
operator << (std::ostream &os, Operation op)
{
switch (op)
{
case UPDATE:
os << "update";
break;
case REMOVE:
os << "remove";
break;
}
return os;
}
std::istream &
operator >> (std::istream &is, Operation &op)
{
std::string operation;
is >> operation;
if (operation == "update")
op = UPDATE;
else if (operation == "remove")
op = REMOVE;
else
BOOST_THROW_EXCEPTION (SyncDiffLeafOperationParseError () << errmsg_info (operation));
return is;
}
}
-91
View File
@@ -1,91 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_DIFF_LEAF_H
#define SYNC_DIFF_LEAF_H
#include "sync-leaf.h"
#include <boost/exception/all.hpp>
namespace Sync {
/**
* @ingroup sync
* @brief Annotation for SYNC leaf
*/
enum Operation
{
UPDATE, ///< @brief Leaf was added or updated
REMOVE ///< @brief Leaf was removed
};
/**
* @ingroup sync
* @brief Annotated SYNC leaf
*/
class DiffLeaf : public Leaf
{
public:
/**
* @brief Constructor to create an UPDATE diff leaf
* @param info Smart pointer to leaf's name
* @param seq Initial sequence number of the pointer
*/
DiffLeaf (NameInfoConstPtr info, const SeqNo &seq);
/**
* @brief Constructor to create an REMOVE diff leaf
* @param info Smart pointer to leaf's name
*
* This constructor creates a leaf with phony sequence number
* with 0 session ID and 0 sequence number
*/
DiffLeaf (NameInfoConstPtr info);
virtual ~DiffLeaf () { }
/**
* @brief Get diff leaf type
*/
Operation
getOperation () const { return m_op; }
private:
Operation m_op;
};
typedef shared_ptr<DiffLeaf> DiffLeafPtr;
typedef shared_ptr<const DiffLeaf> DiffLeafConstPtr;
std::ostream &
operator << (std::ostream &os, Operation op);
std::istream &
operator >> (std::istream &is, Operation &op);
namespace Error {
struct SyncDiffLeafOperationParseError : virtual boost::exception, virtual std::exception { };
} // Error
} // Sync
#endif // SYNC_DIFF_LEAF_H
-72
View File
@@ -1,72 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_DIFF_STATE_CONTAINER_H
#define SYNC_DIFF_STATE_CONTAINER_H
#include "sync-diff-state.h"
#include "sync-digest.h"
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/tag.hpp>
// #include <boost/multi_index/ordered_index.hpp>
// #include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
// #include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
namespace mi = boost::multi_index;
namespace Sync {
/// @cond include_hidden
struct sequenced { };
struct timed { };
/// @endcond
/**
* \ingroup sync
* @brief Container for differential states
*/
struct DiffStateContainer : public mi::multi_index_container<
DiffStatePtr,
mi::indexed_by<
// For fast access to elements using DiffState hashes
mi::hashed_unique<
mi::tag<hashed>,
mi::const_mem_fun<DiffState, DigestConstPtr, &DiffState::getDigest>,
DigestPtrHash,
DigestPtrEqual
>
,
// sequenced index to access older/newer element (like in list)
mi::sequenced<mi::tag<sequenced> >
>
>
{
};
} // Sync
#endif // SYNC_DIFF_STATE_CONTAINER_H
-98
View File
@@ -1,98 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-diff-state.h"
#include "sync-diff-leaf.h"
#include <boost/foreach.hpp>
#include <boost/assert.hpp>
namespace Sync {
DiffState::DiffState ()
{
}
DiffState::~DiffState ()
{
}
DiffStatePtr
DiffState::diff () const
{
DiffStatePtr ret = make_shared<DiffState> ();
DiffStatePtr state = m_next;
while (state != 0)
{
*ret += *state;
state = state->m_next;
}
return ret;
}
DiffState &
DiffState::operator += (const DiffState &state)
{
BOOST_FOREACH (LeafConstPtr _leaf, state.getLeaves ())
{
DiffLeafConstPtr leaf = dynamic_pointer_cast<const DiffLeaf> (_leaf);
BOOST_ASSERT (leaf != 0);
if (leaf->getOperation () == UPDATE)
update (leaf->getInfo (), leaf->getSeq ());
else if (leaf->getOperation () == REMOVE)
remove (leaf->getInfo ());
else
{
BOOST_ASSERT (false);
}
}
return *this;
}
// from State
tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
DiffState::update (NameInfoConstPtr info, const SeqNo &seq)
{
m_leaves.erase (info);
DiffLeafPtr leaf = make_shared<DiffLeaf> (info, seq);
m_leaves.insert (leaf);
return make_tuple (true, false, SeqNo ());
}
bool
DiffState::remove (NameInfoConstPtr info)
{
m_leaves.erase (info);
DiffLeafPtr leaf = make_shared<DiffLeaf> (info);
m_leaves.insert (leaf);
return true;
}
} // ns3
-102
View File
@@ -1,102 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_DIFF_STATE_H
#define SYNC_DIFF_STATE_H
#include "sync-state.h"
#include <iostream>
namespace Sync {
class DiffState;
typedef shared_ptr<DiffState> DiffStatePtr;
typedef shared_ptr<DiffState> DiffStateConstPtr;
/**
* @ingroup ccnx
* @brief Differential SYNC state
*/
class DiffState : public State
{
public:
/**
* @see Default constructor
*/
DiffState ();
virtual ~DiffState ();
/**
* @brief Set successor for the diff state
* @param next successor state
*/
void
setNext (DiffStatePtr next)
{
m_next = next;
}
/**
* @brief Set digest for the diff state (obtained from a corresponding full state)
* @param digest A read only smart pointer to a digest object (that should be unmodified anywhere else)
*/
void
setDigest (DigestConstPtr digest) { m_digest = digest; }
/**
* @brief Get digest for the diff state
*/
DigestConstPtr
getDigest () const { return m_digest; }
/**
* @brief Accumulate differences from `this' state to the most current state
* @returns Accumulated differences from `this' state to the most current state
*/
DiffStatePtr
diff () const;
/**
* @brief Combine differences from `this' and `state'
* @param state Differential state to combine with
* @return Combined differences
*
* In case of collisions, `this' leaf will be replaced with the leaf of `state'
*/
DiffState&
operator += (const DiffState &state);
// from State
virtual tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
update (NameInfoConstPtr info, const SeqNo &seq);
virtual bool
remove (NameInfoConstPtr info);
private:
DiffStatePtr m_next;
DigestConstPtr m_digest;
};
} // Sync
#endif // SYNC_DIFF_STATE_H
-262
View File
@@ -1,262 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-digest.h"
#include <string.h>
#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>
typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info_str;
typedef boost::error_info<struct tag_errmsg, int> errmsg_info_int;
// for printing, may be disabled in optimized build
// #ifdef DIGEST_BASE64
// #include <boost/archive/iterators/base64_from_binary.hpp>
// #include <boost/archive/iterators/binary_from_base64.hpp>
// #endif
#include "boost-archive.h"
using namespace boost;
using namespace boost::archive::iterators;
using namespace std;
// Other options: VP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_sha256, EVP_dss, EVP_dss1, EVP_mdc2, EVP_ripemd160
#define HASH_FUNCTION EVP_sha256
#define HASH_FUNCTION_LEN 32
// #ifndef DIGEST_BASE64
template<class CharType>
struct hex_from_4_bit
{
typedef CharType result_type;
CharType operator () (CharType ch) const
{
const char *lookup_table = "0123456789abcdef";
// cout << "New character: " << (int) ch << " (" << (char) ch << ")" << "\n";
BOOST_ASSERT (ch < 16);
return lookup_table[static_cast<size_t>(ch)];
}
};
typedef transform_iterator<hex_from_4_bit<std::vector<uint8_t>::const_iterator::value_type>,
transform_width<std::vector<uint8_t>::const_iterator, 4, 8, std::vector<uint8_t>::const_iterator::value_type> > string_from_binary;
template<class CharType>
struct hex_to_4_bit
{
typedef CharType result_type;
CharType operator () (CharType ch) const
{
const signed char lookup_table [] = {
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
};
// cout << "New character: " << hex << (int) ch << " (" << (char) ch << ")" << "\n";
signed char value = -1;
if ((unsigned)ch < 128)
value = lookup_table [(unsigned)ch];
if (value == -1)
BOOST_THROW_EXCEPTION (Sync::Error::DigestCalculationError () << errmsg_info_int ((int)ch));
return value;
}
};
typedef transform_width<transform_iterator<hex_to_4_bit<string::const_iterator::value_type>, string::const_iterator>, 8, 4> string_to_binary;
namespace Sync {
Digest::Digest ()
{
m_context = EVP_MD_CTX_create ();
reset ();
}
Digest::~Digest ()
{
EVP_MD_CTX_destroy (m_context);
}
bool
Digest::empty () const
{
return m_buffer.empty ();
}
bool
Digest::isZero () const
{
if (m_buffer.empty ())
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
<< errmsg_info_str ("Digest has not been yet finalized"));
return (m_buffer.size () == 1 && m_buffer[0] == 0);
}
void
Digest::reset ()
{
m_buffer.clear ();
int ok = EVP_DigestInit_ex (m_context, HASH_FUNCTION (), 0);
if (!ok)
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
<< errmsg_info_str ("EVP_DigestInit_ex returned error")
<< errmsg_info_int (ok));
}
void
Digest::finalize ()
{
if (!m_buffer.empty ()) return;
m_buffer.resize (HASH_FUNCTION_LEN);
unsigned int tmp;
int ok = EVP_DigestFinal_ex (m_context,
&m_buffer[0], &tmp);
if (!ok)
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
<< errmsg_info_str ("EVP_DigestFinal_ex returned error")
<< errmsg_info_int (ok));
}
std::size_t
Digest::getHash () const
{
if (isZero ()) return 0;
if (sizeof (std::size_t) > m_buffer.size ())
{
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
<< errmsg_info_str ("Hash is not zero and length is less than size_t")
<< errmsg_info_int (m_buffer.size ()));
}
// just getting first sizeof(std::size_t) bytes
// not ideal, but should work pretty well
return *(reinterpret_cast<const std::size_t*> (&m_buffer[0]));
}
bool
Digest::operator == (const Digest &digest) const
{
if (m_buffer.empty ())
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
<< errmsg_info_str ("Digest1 is empty"));
if (digest.m_buffer.empty ())
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
<< errmsg_info_str ("Digest2 is empty"));
return m_buffer == digest.m_buffer;
}
void
Digest::update (const uint8_t *buffer, size_t size)
{
// cout << "Update: " << (void*)buffer << " / size: " << size << "\n";
// cannot update Digest when it has been finalized
if (!m_buffer.empty ())
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
<< errmsg_info_str ("Digest has been already finalized"));
bool ok = EVP_DigestUpdate (m_context, buffer, size);
if (!ok)
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
<< errmsg_info_str ("EVP_DigestUpdate returned error")
<< errmsg_info_int (ok));
}
Digest &
Digest::operator << (const Digest &src)
{
if (src.m_buffer.empty ())
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
<< errmsg_info_str ("Digest has not been yet finalized"));
update (&src.m_buffer[0], src.m_buffer.size ());
return *this;
}
std::ostream &
operator << (std::ostream &os, const Digest &digest)
{
BOOST_ASSERT (!digest.m_buffer.empty ());
ostreambuf_iterator<char> out_it (os); // ostream iterator
// need to encode to base64
copy (string_from_binary (digest.m_buffer.begin ()),
string_from_binary (digest.m_buffer.end ()),
out_it);
return os;
}
std::istream &
operator >> (std::istream &is, Digest &digest)
{
string str;
is >> str; // read string first
if (str.size () == 0)
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
<< errmsg_info_str ("Input is empty"));
// uint8_t padding = (3 - str.size () % 3) % 3;
// for (uint8_t i = 0; i < padding; i++) str.push_back ('=');
// only empty digest object can be used for reading
if (!digest.m_buffer.empty ())
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
<< errmsg_info_str ("Digest has been already finalized"));
digest.m_buffer.clear ();
copy (string_to_binary (str.begin ()),
string_to_binary (str.end ()),
std::back_inserter (digest.m_buffer));
return is;
}
} // Sync
-199
View File
@@ -1,199 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_DIGEST_H
#define SYNC_DIGEST_H
#include "sync-common.h"
#include <vector>
#include "openssl.h"
namespace Sync {
/**
* @ingroup sync
* @brief A simple wrapper for libcrypto hash functions
*/
class Digest
{
public:
/**
* @brief Default constructor. Will initialize internal libssl structures
*/
Digest ();
/**
* @brief Check if digest is empty
*/
bool
empty () const;
/**
* @brief Reset digest to the initial state
*/
void
reset ();
/**
* @brief Destructor
*/
~Digest ();
/**
* @brief Obtain a short version of the hash (just first sizeof(size_t) bytes
*
* Side effect: finalize() will be called on `this'
*/
std::size_t
getHash () const;
/**
* @brief Finalize digest. All subsequent calls to "operator <<" will fire an exception
*/
void
finalize ();
/**
* @brief Compare two full digests
*
* Side effect: Finalize will be called on `this' and `digest'
*/
bool
operator == (const Digest &digest) const;
bool
operator != (const Digest &digest) const
{ return ! (*this == digest); }
/**
* @brief Add existing digest to digest calculation
* @param src digest to combine with
*
* The result of this combination is hash (hash (...))
*/
Digest &
operator << (const Digest &src);
/**
* @brief Add string to digest calculation
* @param str string to put into digest
*/
inline Digest &
operator << (const std::string &str);
/**
* @brief Add uint64_t value to digest calculation
* @param value uint64_t value to put into digest
*/
inline Digest &
operator << (uint64_t value);
/**
* @brief Checks if the stored hash is zero-root hash
*
* Zero-root hash is a valid hash that optimally represents an empty state
*/
bool
isZero () const;
private:
Digest &
operator = (Digest &digest) { (void)digest; return *this; }
/**
* @brief Add size bytes of buffer to the hash
*/
void
update (const uint8_t *buffer, size_t size);
friend std::ostream &
operator << (std::ostream &os, const Digest &digest);
friend std::istream &
operator >> (std::istream &is, Digest &digest);
private:
EVP_MD_CTX *m_context;
std::vector<uint8_t> m_buffer;
};
namespace Error {
struct DigestCalculationError : virtual boost::exception, virtual std::exception { };
}
typedef shared_ptr<Digest> DigestPtr;
typedef shared_ptr<const Digest> DigestConstPtr;
Digest &
Digest::operator << (const std::string &str)
{
update (reinterpret_cast<const uint8_t*> (str.c_str ()), str.size ());
return *this;
}
inline Digest &
Digest::operator << (uint64_t value)
{
update (reinterpret_cast<const uint8_t*> (&value), sizeof (uint64_t));
return *this;
}
std::ostream &
operator << (std::ostream &os, const Digest &digest);
std::istream &
operator >> (std::istream &is, Digest &digest);
// template<class INT>
// Digest &
// Digest::operator << (INT value)
// {
// update (&value, sizeof (INT));
// return *this;
// }
struct DigestPtrHash : public std::unary_function<Digest, std::size_t>
{
std::size_t
operator() (DigestConstPtr digest) const
{
// std::cout << "digest->getHash: " << digest->getHash () << " (" << *digest << ")" << std::endl;
return digest->getHash ();
}
};
struct DigestPtrEqual : public std::unary_function<Digest, std::size_t>
{
bool
operator() (DigestConstPtr digest1, DigestConstPtr digest2) const
{
// std::cout << boost::cref(*digest1) << " == " << boost::cref(*digest2) << " : " << (*digest1 == *digest2) << std::endl;
return *digest1 == *digest2;
}
};
} // Sync
#endif // SYNC_DIGEST_H
-35
View File
@@ -1,35 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_EVENT_H
#define SYNC_EVENT_H
#include "sync-common.h"
namespace Sync
{
typedef function< void ( ) > Event;
} // Sync
#endif // SYNC_EVENT_H
-49
View File
@@ -1,49 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-full-leaf.h"
namespace Sync {
FullLeaf::FullLeaf (NameInfoConstPtr info, const SeqNo &seq)
: Leaf (info, seq)
{
updateDigest ();
}
void
FullLeaf::updateDigest ()
{
m_digest.reset ();
m_digest << getInfo ()->getDigest () << *getSeq ().getDigest ();
m_digest.finalize ();
}
// from Leaf
void
FullLeaf::setSeq (const SeqNo &seq)
{
Leaf::setSeq (seq);
updateDigest ();
}
} // Sync
-71
View File
@@ -1,71 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_FULL_LEAF_H
#define SYNC_FULL_LEAF_H
#include "sync-leaf.h"
namespace Sync {
/**
* @ingroup sync
* @brief SYNC leaf for the full state (with support of Digest calculation)
*/
class FullLeaf : public Leaf
{
public:
/**
* @brief Constructor to create an UPDATE diff leaf
* @param info Smart pointer to leaf's name
* @param seq Initial sequence number of the pointer
*/
FullLeaf (NameInfoConstPtr info, const SeqNo &seq);
virtual ~FullLeaf () { }
/**
* @brief Get hash digest of the leaf
*
* The underlying Digest object is recalculated on every update or removal
* (including updates of child classes)
*/
const Digest &
getDigest () const { return m_digest; }
// from Leaf
virtual void
setSeq (const SeqNo &seq);
private:
void
updateDigest ();
private:
Digest m_digest;
};
typedef shared_ptr<FullLeaf> FullLeafPtr;
typedef shared_ptr<const FullLeaf> FullLeafConstPtr;
} // Sync
#endif // SYNC_FULL_LEAF_H
-118
View File
@@ -1,118 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-full-state.h"
#include <boost/assert.hpp>
#include "sync-full-leaf.h"
namespace Sync {
FullState::FullState ()
// m_lastUpdated is initialized to "not_a_date_time" in normal lib mode and to "0" time in NS-3 mode
{
}
FullState::~FullState ()
{
}
ndn::time::system_clock::Duration
FullState::getTimeFromLastUpdate () const
{
return ndn::time::system_clock::now() - m_lastUpdated;
}
DigestConstPtr
FullState::getDigest ()
{
if (!m_digest)
{
m_digest = make_shared<Digest> ();
if (m_leaves.get<ordered> ().size () > 0)
{
for (LeafConstPtr leaf : m_leaves.get<ordered> ())
{
FullLeafConstPtr fullLeaf = dynamic_pointer_cast<const FullLeaf> (leaf);
BOOST_ASSERT (fullLeaf != 0);
*m_digest << fullLeaf->getDigest ();
}
m_digest->finalize ();
}
else
{
std::istringstream is ("00"); //zero state
is >> *m_digest;
}
}
return m_digest;
}
// from State
tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
FullState::update (NameInfoConstPtr info, const SeqNo &seq)
{
m_lastUpdated = ndn::time::system_clock::now();
m_digest.reset ();
LeafContainer::iterator item = m_leaves.find (info);
if (item == m_leaves.end ())
{
m_leaves.insert (make_shared<FullLeaf> (info, seq));
return make_tuple (true, false, SeqNo ());
}
else
{
if ((*item)->getSeq () == seq || seq < (*item)->getSeq ())
{
return make_tuple (false, false, SeqNo ());
}
SeqNo old = (*item)->getSeq ();
m_leaves.modify (item, [&seq](LeafPtr data){ data->setSeq(seq); });
return make_tuple (false, true, old);
}
}
bool
FullState::remove (NameInfoConstPtr info)
{
m_lastUpdated = ndn::time::system_clock::now();
m_digest.reset ();
LeafContainer::iterator item = m_leaves.find (info);
if (item != m_leaves.end ())
{
m_leaves.erase (item);
return true;
}
else
return false;
}
} // Sync
-79
View File
@@ -1,79 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_FULL_STATE_H
#define SYNC_FULL_STATE_H
#include <ndn-cxx/util/time.hpp>
#include "sync-state.h"
namespace Sync {
class FullState;
typedef shared_ptr<FullState> FullStatePtr;
typedef shared_ptr<FullState> FullStateConstPtr;
/**
* \ingroup sync
* @brief Cumulative SYNC state
*/
class FullState : public State
{
public:
/**
* @brief Default constructor
*/
FullState ();
virtual ~FullState ();
/**
* @brief Get time period since last state update
*
* This value can be used to randomize reconciliation waiting time in SyncApp
*/
ndn::time::system_clock::Duration
getTimeFromLastUpdate () const;
/**
* @brief Obtain a read-only copy of the digest
*
* If m_digest is 0, then it is automatically created. On every update and removal, m_digest is reset to 0
*/
DigestConstPtr
getDigest ();
// from State
virtual tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
update (NameInfoConstPtr info, const SeqNo &seq);
virtual bool
remove (NameInfoConstPtr info);
private:
ndn::time::system_clock::TimePoint m_lastUpdated; ///< @brief Time when state was updated last time
DigestPtr m_digest;
};
} // Sync
#endif // SYNC_STATE_H
-99
View File
@@ -1,99 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_INTEREST_CONTAINER_H
#define SYNC_INTEREST_CONTAINER_H
#include <ndn-cxx/util/time.hpp>
#include "sync-digest.h"
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/tag.hpp>
// #include <boost/multi_index/ordered_index.hpp>
// #include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
// #include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
namespace mi = boost::multi_index;
namespace Sync {
struct Interest
{
Interest (DigestConstPtr digest, const std::string &name, bool unknown=false)
: m_digest (digest)
, m_name (name)
, m_time (ndn::time::system_clock::now())
, m_unknown (unknown)
{
}
DigestConstPtr m_digest;
std::string m_name;
ndn::time::system_clock::TimePoint m_time;
bool m_unknown;
};
/// @cond include_hidden
struct named { };
struct hashed;
struct timed;
/// @endcond
/**
* \ingroup sync
* @brief Container for interests (application PIT)
*/
struct InterestContainer : public mi::multi_index_container<
Interest,
mi::indexed_by<
mi::hashed_unique<
mi::tag<named>,
BOOST_MULTI_INDEX_MEMBER(Interest, std::string, m_name)
>
,
mi::hashed_non_unique<
mi::tag<hashed>,
BOOST_MULTI_INDEX_MEMBER(Interest, DigestConstPtr, m_digest),
DigestPtrHash,
DigestPtrEqual
>
,
mi::ordered_non_unique<
mi::tag<timed>,
BOOST_MULTI_INDEX_MEMBER(Interest, ndn::time::system_clock::TimePoint, m_time)
>
>
>
{
};
} // Sync
#endif // SYNC_INTEREST_CONTAINER_H
-126
View File
@@ -1,126 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-interest-table.h"
#include "sync-logging.h"
using namespace std;
INIT_LOGGER("SyncInterestTable");
namespace Sync
{
SyncInterestTable::SyncInterestTable(boost::asio::io_service& io, ndn::time::system_clock::Duration lifetime)
: m_entryLifetime(lifetime)
, m_scheduler(io)
{
m_scheduler.scheduleEvent(ndn::time::seconds(4),
ndn::bind(&SyncInterestTable::expireInterests, this));
}
SyncInterestTable::~SyncInterestTable()
{
}
Interest
SyncInterestTable::pop()
{
if (m_table.size() == 0)
BOOST_THROW_EXCEPTION(Error::InterestTableIsEmpty());
Interest ret = *m_table.begin();
m_table.erase(m_table.begin());
return ret;
}
bool
SyncInterestTable::insert(DigestConstPtr digest, const string &name, bool unknownState/*=false*/)
{
bool existent = false;
InterestContainer::index<named>::type::iterator it = m_table.get<named>().find(name);
if (it != m_table.end())
{
existent = true;
m_table.erase(it);
}
m_table.insert(Interest(digest, name, unknownState));
return existent;
}
uint32_t
SyncInterestTable::size() const
{
return m_table.size();
}
bool
SyncInterestTable::remove(const string &name)
{
InterestContainer::index<named>::type::iterator item = m_table.get<named>().find(name);
if (item != m_table.get<named>().end())
{
m_table.get<named>().erase(name);
return true;
}
return false;
}
bool
SyncInterestTable::remove(DigestConstPtr digest)
{
InterestContainer::index<hashed>::type::iterator item = m_table.get<hashed>().find(digest);
if (item != m_table.get<hashed>().end())
{
m_table.get<hashed>().erase(digest); // erase all records associated with the digest
return true;
}
return false;
}
void SyncInterestTable::expireInterests()
{
uint32_t count = 0;
ndn::time::system_clock::TimePoint expireTime = ndn::time::system_clock::now() - m_entryLifetime;
while (m_table.size() > 0)
{
InterestContainer::index<timed>::type::iterator item = m_table.get<timed>().begin();
if (item->m_time <= expireTime)
{
m_table.get<timed>().erase(item);
count ++;
}
else
break;
}
m_scheduler.scheduleEvent(ndn::time::seconds(4),
ndn::bind(&SyncInterestTable::expireInterests, this));
}
}
-96
View File
@@ -1,96 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_INTEREST_TABLE_H
#define SYNC_INTEREST_TABLE_H
#include <ndn-cxx/util/scheduler.hpp>
#include <string>
#include <vector>
#include "sync-digest.h"
#include "sync-interest-container.h"
namespace Sync {
/**
* \ingroup sync
* @brief A table to keep unanswered Sync Interest
* all access operation to the table should grab the
* mutex first
*/
class SyncInterestTable
{
public:
SyncInterestTable (boost::asio::io_service& io, ndn::time::system_clock::Duration lifetime);
~SyncInterestTable ();
/**
* @brief Insert an interest, if interest already exists, update the
* timestamp
*/
bool
insert (DigestConstPtr interest, const std::string &name, bool unknownState=false);
/**
* @brief Remove interest by digest (e.g., when it was satisfied)
*/
bool
remove (DigestConstPtr interest);
/**
* @brief Remove interest by name (e.g., when it was satisfied)
*/
bool
remove (const std::string &name);
/**
* @brief pop a non-expired Interest from PIT
*/
Interest
pop ();
uint32_t
size () const;
private:
/**
* @brief periodically called to expire Interest
*/
void
expireInterests ();
private:
ndn::time::system_clock::Duration m_entryLifetime;
InterestContainer m_table;
ndn::Scheduler m_scheduler;
};
namespace Error {
struct InterestTableIsEmpty : virtual boost::exception, virtual std::exception { };
}
} // Sync
#endif // SYNC_INTEREST_TABLE_H
-43
View File
@@ -1,43 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-leaf.h"
namespace Sync {
Leaf::Leaf (NameInfoConstPtr info, const SeqNo &seq)
: m_info (info)
, m_seq (seq)
{
}
Leaf::~Leaf ()
{
}
void
Leaf::setSeq (const SeqNo &seq)
{
m_seq = std::max (m_seq, seq);
}
} // Sync
-84
View File
@@ -1,84 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_LEAF_H
#define SYNC_LEAF_H
#include "sync-seq-no.h"
#include "sync-name-info.h"
namespace Sync {
/**
* \ingroup sync
* @brief Sync tree leaf
*/
class Leaf
{
public:
/**
* @brief Constructor
* @param info Smart pointer to leaf's name
* @param seq Initial sequence number of the pointer
*/
Leaf (NameInfoConstPtr info, const SeqNo &seq);
virtual ~Leaf ();
/**
* @brief Get name of the leaf
*/
NameInfoConstPtr
getInfo () const { return m_info; }
/**
* @brief Get sequence number of the leaf
*/
const SeqNo&
getSeq () const { return m_seq; }
/**
* @brief Update sequence number of the leaf
* @param seq Sequence number
*
* Sequence number is updated to the largest value among this->m_seq and seq
*/
virtual void
setSeq (const SeqNo &seq);
private:
NameInfoConstPtr m_info;
SeqNo m_seq;
};
typedef shared_ptr<Leaf> LeafPtr;
typedef shared_ptr<const Leaf> LeafConstPtr;
inline std::ostream &
operator << (std::ostream &os, const Leaf &leaf)
{
os << *leaf.getInfo () << "(" << leaf.getSeq () << ")";
return os;
}
} // Sync
#endif // SYNC_LEAF_H
-61
View File
@@ -1,61 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-logging.h"
#ifdef HAVE_LOG4CXX
#include <log4cxx/logger.h>
#include <log4cxx/basicconfigurator.h>
#include <log4cxx/consoleappender.h>
#include <log4cxx/patternlayout.h>
#include <log4cxx/level.h>
#include <log4cxx/propertyconfigurator.h>
#include <log4cxx/defaultconfigurator.h>
#include <log4cxx/helpers/exception.h>
using namespace log4cxx;
using namespace log4cxx::helpers;
#include <unistd.h>
void
INIT_LOGGERS ()
{
static bool configured = false;
if (configured) return;
if (access ("log4cxx.properties", R_OK)==0)
PropertyConfigurator::configureAndWatch ("log4cxx.properties");
else
{
PatternLayoutPtr layout (new PatternLayout ("%d{HH:mm:ss} %p %c{1} - %m%n"));
ConsoleAppenderPtr appender (new ConsoleAppender (layout));
BasicConfigurator::configure( appender );
Logger::getRootLogger()->setLevel (log4cxx::Level::getInfo ());
}
configured = true;
}
#endif
-74
View File
@@ -1,74 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_LOG_H
#define SYNC_LOG_H
#ifdef HAVE_LOG4CXX
#include <log4cxx/logger.h>
#define INIT_LOGGER(name) \
static log4cxx::LoggerPtr staticModuleLogger = log4cxx::Logger::getLogger (name)
#define _LOG_DEBUG(x) \
LOG4CXX_DEBUG(staticModuleLogger, x);
#define _LOG_TRACE(x) \
LOG4CXX_TRACE(staticModuleLogger, x);
#define _LOG_FUNCTION(x) \
LOG4CXX_TRACE(staticModuleLogger, __FUNCTION__ << "(" << x << ")");
#define _LOG_FUNCTION_NOARGS \
LOG4CXX_TRACE(staticModuleLogger, __FUNCTION__ << "()");
#define _LOG_ERROR(x) \
LOG4CXX_ERROR(staticModuleLogger, x);
void
INIT_LOGGERS ();
#else
#define INIT_LOGGER(name)
#define _LOG_FUNCTION(x)
#define _LOG_FUNCTION_NOARGS
#define _LOG_TRACE(x)
#define INIT_LOGGERS(x)
#define _LOG_ERROR(x)
#ifdef _DEBUG
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
#define _LOG_DEBUG(x) \
std::clog << boost::get_system_time () << " " << boost::this_thread::get_id () << " " << x << endl;
#else
#define _LOG_DEBUG(x)
#endif
#endif // HAVE_LOG4CXX
#endif // SYNC_LOG_H
-84
View File
@@ -1,84 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_LOGIC_EVENT_CONTAINER_H
#define SYNC_LOGIC_EVENT_CONTAINER_H
#include "sync-event.h"
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/multi_index_container.hpp>
// #include <boost/multi_index/tag.hpp>
#include <boost/multi_index/ordered_index.hpp>
// #include <boost/multi_index/composite_key.hpp>
// #include <boost/multi_index/hashed_index.hpp>
// #include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/member.hpp>
// #include <boost/multi_index/mem_fun.hpp>
namespace mi = boost::multi_index;
namespace Sync
{
struct LogicEvent
{
LogicEvent (const boost::system_time &_time, Event _event, uint32_t _label)
: time (_time)
, event (_event)
, lbl (_label)
{ }
boost::system_time time;
Event event;
uint32_t lbl;
};
/// @cond include_hidden
struct byLabel { } ;
/// @endcond
/**
* \ingroup sync
* @brief ???
*/
struct EventsContainer : public mi::multi_index_container<
LogicEvent,
mi::indexed_by<
mi::ordered_non_unique<
mi::member<LogicEvent, boost::system_time, &LogicEvent::time>
>,
mi::ordered_non_unique<
mi::tag<byLabel>,
mi::member<LogicEvent, uint32_t, &LogicEvent::lbl>
>
>
>
{
};
} // Sync
#endif // SYNC_LOGIC_EVENT_CONTAINER_H
-750
View File
@@ -1,750 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
* Yingdi Yu <yingdi@cs.ucla.edu>
*/
#include "sync-logic.h"
#include "sync-diff-leaf.h"
#include "sync-full-leaf.h"
#include "sync-logging.h"
#include "sync-state.h"
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
#include <vector>
using namespace std;
using ndn::Data;
using ndn::EventId;
using ndn::KeyChain;
using ndn::Face;
using ndn::Name;
using ndn::OnDataValidated;
using ndn::OnDataValidationFailed;
using ndn::Validator;
INIT_LOGGER ("SyncLogic");
#ifdef _DEBUG
#define _LOG_DEBUG_ID(v) _LOG_DEBUG(m_instanceId << " " << v)
#else
#define _LOG_DEBUG_ID(v) _LOG_DEBUG(v)
#endif
#define GET_RANDOM(var) var ()
#define TIME_SECONDS_WITH_JITTER(sec) \
(ndn::time::seconds(sec) + ndn::time::milliseconds(GET_RANDOM (m_reexpressionJitter)))
#define TIME_MILLISECONDS_WITH_JITTER(ms) \
(ndn::time::seconds(ms) + ndn::time::milliseconds(GET_RANDOM (m_reexpressionJitter)))
namespace Sync {
using ndn::shared_ptr;
int SyncLogic::m_instanceCounter = 0;
const int SyncLogic::m_syncResponseFreshness = 1000; // MUST BE dividable by 1000!!!
const int SyncLogic::m_syncInterestReexpress = 4; // seconds
SyncLogic::SyncLogic (const Name& syncPrefix,
shared_ptr<Validator> validator,
shared_ptr<Face> face,
LogicUpdateCallback onUpdate,
LogicRemoveCallback onRemove)
: m_state (new FullState)
, m_syncInterestTable (face->getIoService(), ndn::time::seconds(m_syncInterestReexpress))
, m_syncPrefix (syncPrefix)
, m_onUpdate (onUpdate)
, m_onRemove (onRemove)
, m_perBranch (false)
, m_validator(validator)
, m_keyChain(new KeyChain())
, m_face(face)
, m_scheduler(face->getIoService())
, m_randomGenerator (static_cast<unsigned int> (std::time (0)))
, m_rangeUniformRandom (m_randomGenerator, boost::uniform_int<> (200,1000))
, m_reexpressionJitter (m_randomGenerator, boost::uniform_int<> (100,500))
, m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
{
m_syncRegisteredPrefixId = m_face->setInterestFilter (m_syncPrefix,
bind(&SyncLogic::onSyncInterest,
this, _1, _2),
bind(&SyncLogic::onSyncRegisterSucceed,
this, _1),
bind(&SyncLogic::onSyncRegisterFailed,
this, _1, _2));
m_reexpressingInterestId = m_scheduler.scheduleEvent (ndn::time::seconds (0),
bind (&SyncLogic::sendSyncInterest, this));
m_instanceId = string("Instance " + boost::lexical_cast<string>(m_instanceCounter++) + " ");
}
SyncLogic::SyncLogic (const Name& syncPrefix,
shared_ptr<Validator> validator,
shared_ptr<Face> face,
LogicPerBranchCallback onUpdateBranch)
: m_state (new FullState)
, m_syncInterestTable (face->getIoService(), ndn::time::seconds (m_syncInterestReexpress))
, m_syncPrefix (syncPrefix)
, m_onUpdateBranch (onUpdateBranch)
, m_perBranch(true)
, m_validator(validator)
, m_keyChain(new KeyChain())
, m_face(face)
, m_scheduler(face->getIoService())
, m_randomGenerator (static_cast<unsigned int> (std::time (0)))
, m_rangeUniformRandom (m_randomGenerator, boost::uniform_int<> (200,1000))
, m_reexpressionJitter (m_randomGenerator, boost::uniform_int<> (100,500))
, m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
{
m_syncRegisteredPrefixId = m_face->setInterestFilter (m_syncPrefix,
bind(&SyncLogic::onSyncInterest,
this, _1, _2),
bind(&SyncLogic::onSyncRegisterSucceed,
this, _1),
bind(&SyncLogic::onSyncRegisterFailed,
this, _1, _2));
m_reexpressingInterestId = m_scheduler.scheduleEvent (ndn::time::seconds (0),
bind (&SyncLogic::sendSyncInterest, this));
}
SyncLogic::~SyncLogic ()
{
m_face->unsetInterestFilter(m_syncRegisteredPrefixId);
m_scheduler.cancelEvent (m_reexpressingInterestId);
m_scheduler.cancelEvent (m_delayedInterestProcessingId);
}
/**
* Two types of intersts
*
* Normal name: .../<hash>
* Recovery name: .../recovery/<hash>
*/
tuple<DigestConstPtr, std::string>
SyncLogic::convertNameToDigestAndType (const Name &name)
{
BOOST_ASSERT (m_syncPrefix.isPrefixOf(name));
int nameLengthDiff = name.size() - m_syncPrefix.size();
BOOST_ASSERT (nameLengthDiff > 0);
BOOST_ASSERT (nameLengthDiff < 3);
string hash = name.get(-1).toUri();
string interestType;
if(nameLengthDiff == 1)
interestType = "normal";
else
interestType = name.get(-2).toUri();
_LOG_DEBUG_ID (hash << ", " << interestType);
DigestPtr digest = make_shared<Digest> ();
istringstream is (hash);
is >> *digest;
return make_tuple(digest, interestType);
}
void
SyncLogic::onSyncInterest (const Name& prefix, const ndn::Interest& interest)
{
Name name = interest.getName();
_LOG_DEBUG_ID("respondSyncInterest: " << name);
try
{
_LOG_DEBUG_ID ("<< I " << name);
DigestConstPtr digest;
string type;
tie (digest, type) = convertNameToDigestAndType (name);
if (type == "normal") // kind of ineffective...
{
processSyncInterest (name, digest);
}
else if (type == "recovery")
{
processSyncRecoveryInterest (name, digest);
}
}
catch (Error::DigestCalculationError &e)
{
_LOG_DEBUG_ID ("Something fishy happened...");
// log error. ignoring it for now, later we should log it
return ;
}
}
void
SyncLogic::onSyncRegisterSucceed(const Name& prefix)
{
_LOG_DEBUG_ID("Sync prefix registration succeeded! " << prefix);
}
void
SyncLogic::onSyncRegisterFailed(const Name& prefix, const string& msg)
{
_LOG_DEBUG_ID("Sync prefix registration failed! " << msg);
}
void
SyncLogic::onSyncData(const ndn::Interest& interest, Data& data)
{
OnDataValidated onValidated = bind(&SyncLogic::onSyncDataValidated, this, _1);
OnDataValidationFailed onValidationFailed = bind(&SyncLogic::onSyncDataValidationFailed, this, _1);
m_validator->validate(data, onValidated, onValidationFailed);
}
void
SyncLogic::onSyncTimeout(const ndn::Interest& interest)
{
// It is OK. Others will handle the time out situation.
}
void
SyncLogic::onSyncDataValidationFailed(const shared_ptr<const Data>& data)
{
_LOG_DEBUG_ID("Sync data cannot be verified!");
}
void
SyncLogic::onSyncDataValidated(const shared_ptr<const Data>& data)
{
Name name = data->getName();
const char* wireData = (const char*)data->getContent().value();
size_t len = data->getContent().value_size();
try
{
_LOG_DEBUG_ID ("<< D " << name);
DigestConstPtr digest;
string type;
tie (digest, type) = convertNameToDigestAndType (name);
if (type == "normal")
{
processSyncData (name, digest, wireData, len);
}
else
{
// timer is always restarted when we schedule recovery
m_scheduler.cancelEvent (m_reexpressingRecoveryInterestId);
processSyncData (name, digest, wireData, len);
}
}
catch (Error::DigestCalculationError &e)
{
_LOG_DEBUG_ID ("Something fishy happened...");
// log error. ignoring it for now, later we should log it
return;
}
}
void
SyncLogic::processSyncInterest (const Name &name, DigestConstPtr digest,
bool timedProcessing/*=false*/)
{
_LOG_DEBUG_ID("processSyncInterest");
DigestConstPtr rootDigest;
{
rootDigest = m_state->getDigest();
}
// Special case when state is not empty and we have received request with zero-root digest
if (digest->isZero () && !rootDigest->isZero ())
{
SyncStateMsg ssm;
{
ssm << (*m_state);
}
sendSyncData (name, digest, ssm);
return;
}
if (*rootDigest == *digest)
{
_LOG_DEBUG_ID ("processSyncInterest (): Same state. Adding to PIT");
m_syncInterestTable.insert (digest, name.toUri(), false);
return;
}
DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
if (stateInDiffLog != m_log.end ())
{
DiffStateConstPtr stateDiff = (*stateInDiffLog)->diff ();
sendSyncData (name, digest, stateDiff);
return;
}
if (!timedProcessing)
{
bool exists = m_syncInterestTable.insert (digest, name.toUri(), true);
if (exists) // somebody else replied, so restart random-game timer
{
_LOG_DEBUG_ID("Unknown digest, but somebody may have already replied, " <<
"so restart our timer");
m_scheduler.cancelEvent (m_delayedInterestProcessingId);
}
uint32_t waitDelay = GET_RANDOM (m_rangeUniformRandom);
_LOG_DEBUG_ID("Digest is not in the log. Schedule processing after small delay: " <<
ndn::time::milliseconds (waitDelay));
m_delayedInterestProcessingId =
m_scheduler.scheduleEvent(ndn::time::milliseconds (waitDelay),
bind (&SyncLogic::processSyncInterest, this, name, digest, true));
}
else
{
_LOG_DEBUG_ID(" (timed processing)");
m_recoveryRetransmissionInterval = m_defaultRecoveryRetransmitInterval;
sendSyncRecoveryInterests (digest);
}
}
void
SyncLogic::processSyncData (const Name &name, DigestConstPtr digest,
const char *wireData, size_t len)
{
DiffStatePtr diffLog = make_shared<DiffState> ();
bool ownInterestSatisfied = false;
try
{
m_syncInterestTable.remove (name.toUri()); // Remove satisfied interest from PIT
ownInterestSatisfied = (name == m_outstandingInterestName);
DiffState diff;
SyncStateMsg msg;
if (!msg.ParseFromArray(wireData, len) || !msg.IsInitialized())
{
//Throw
BOOST_THROW_EXCEPTION (Error::SyncStateMsgDecodingFailure () );
}
msg >> diff;
vector<MissingDataInfo> v;
BOOST_FOREACH (LeafConstPtr leaf, diff.getLeaves().get<ordered>())
{
DiffLeafConstPtr diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
BOOST_ASSERT (diffLeaf != 0);
NameInfoConstPtr info = diffLeaf->getInfo();
if (diffLeaf->getOperation() == UPDATE)
{
SeqNo seq = diffLeaf->getSeq();
bool inserted = false;
bool updated = false;
SeqNo oldSeq;
{
tie (inserted, updated, oldSeq) = m_state->update (info, seq);
}
if (inserted || updated)
{
diffLog->update (info, seq);
if (!oldSeq.isValid())
{
oldSeq = SeqNo(seq.getSession(), 0);
}
else
{
++oldSeq;
}
// there is no need for application to process update on forwarder node
if (info->toString() != forwarderPrefix)
{
MissingDataInfo mdi = {info->toString(), oldSeq, seq};
{
ostringstream interestName;
interestName << mdi.prefix <<
"/" << mdi.high.getSession() <<
"/" << mdi.high.getSeq();
_LOG_DEBUG_ID("+++++++++++++++ " + interestName.str());
}
if (m_perBranch)
{
ostringstream interestName;
interestName << mdi.prefix <<
"/" << mdi.high.getSession() <<
"/" << mdi.high.getSeq();
m_onUpdateBranch(interestName.str());
}
else
{
v.push_back(mdi);
}
}
}
}
else if (diffLeaf->getOperation() == REMOVE)
{
if (m_state->remove (info))
{
diffLog->remove (info);
if (!m_perBranch)
{
m_onRemove (info->toString ());
}
}
}
else
{
}
}
if (!v.empty())
{
if (!m_perBranch)
{
m_onUpdate(v);
}
}
insertToDiffLog (diffLog);
}
catch (Error::SyncStateMsgDecodingFailure &e)
{
_LOG_DEBUG_ID ("Something really fishy happened during state decoding " <<
diagnostic_information (e));
diffLog.reset ();
// don't do anything
}
if ((diffLog != 0 && diffLog->getLeaves ().size () > 0) ||
ownInterestSatisfied)
{
_LOG_DEBUG_ID(" +++++++++++++++ state changed!!!");
// Do it only if everything went fine and state changed
// this is kind of wrong
// satisfyPendingSyncInterests (diffLog); // if there are interests in PIT,
// // there is a point to satisfy them using new state
// if state has changed, then it is safe to express a new interest
ndn::time::system_clock::Duration after =
ndn::time::milliseconds(GET_RANDOM (m_reexpressionJitter));
// cout << "------------ reexpress interest after: " << after << endl;
EventId eventId = m_scheduler.scheduleEvent (after,
bind (&SyncLogic::sendSyncInterest, this));
m_scheduler.cancelEvent (m_reexpressingInterestId);
m_reexpressingInterestId = eventId;
}
}
void
SyncLogic::processSyncRecoveryInterest (const Name &name, DigestConstPtr digest)
{
_LOG_DEBUG_ID("processSyncRecoveryInterest");
DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
if (stateInDiffLog == m_log.end ())
{
_LOG_DEBUG_ID ("Could not find " << *digest << " in digest log");
return;
}
SyncStateMsg ssm;
{
ssm << (*m_state);
}
sendSyncData (name, digest, ssm);
}
void
SyncLogic::satisfyPendingSyncInterests (DiffStateConstPtr diffLog)
{
DiffStatePtr fullStateLog = make_shared<DiffState> ();
{
BOOST_FOREACH (LeafConstPtr leaf, m_state->getLeaves ()/*.get<timed> ()*/)
{
fullStateLog->update (leaf->getInfo (), leaf->getSeq ());
/// @todo Impose limit on how many state info should be send out
}
}
try
{
uint32_t counter = 0;
while (m_syncInterestTable.size () > 0)
{
Sync::Interest interest = m_syncInterestTable.pop ();
if (!interest.m_unknown)
{
_LOG_DEBUG_ID (">> D " << interest.m_name);
sendSyncData (interest.m_name, interest.m_digest, diffLog);
}
else
{
_LOG_DEBUG_ID (">> D (unknown)" << interest.m_name);
sendSyncData (interest.m_name, interest.m_digest, fullStateLog);
}
counter ++;
}
_LOG_DEBUG_ID ("Satisfied " << counter << " pending interests");
}
catch (Error::InterestTableIsEmpty &e)
{
// ok. not really an error
}
}
void
SyncLogic::insertToDiffLog (DiffStatePtr diffLog)
{
diffLog->setDigest (m_state->getDigest());
if (m_log.size () > 0)
{
m_log.get<sequenced> ().front ()->setNext (diffLog);
}
m_log.erase (m_state->getDigest()); // remove diff state with the same digest.
// next pointers are still valid
/// @todo Optimization
m_log.get<sequenced> ().push_front (diffLog);
}
void
SyncLogic::addLocalNames (const Name &prefix, uint64_t session, uint64_t seq)
{
DiffStatePtr diff;
{
//cout << "Add local names" <<endl;
NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix.toUri());
_LOG_DEBUG_ID ("addLocalNames (): old state " << *m_state->getDigest ());
SeqNo seqN (session, seq);
m_state->update(info, seqN);
_LOG_DEBUG_ID ("addLocalNames (): new state " << *m_state->getDigest ());
diff = make_shared<DiffState>();
diff->update(info, seqN);
insertToDiffLog (diff);
}
// _LOG_DEBUG_ID ("PIT size: " << m_syncInterestTable.size ());
satisfyPendingSyncInterests (diff);
}
void
SyncLogic::remove(const Name &prefix)
{
DiffStatePtr diff;
{
NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix.toUri());
m_state->remove(info);
// increment the sequence number for the forwarder node
NameInfoConstPtr forwarderInfo = StdNameInfo::FindOrCreate(forwarderPrefix);
LeafContainer::iterator item = m_state->getLeaves ().find (forwarderInfo);
SeqNo seqNo (0);
if (item != m_state->getLeaves ().end ())
{
seqNo = (*item)->getSeq ();
++seqNo;
}
m_state->update (forwarderInfo, seqNo);
diff = make_shared<DiffState>();
diff->remove(info);
diff->update(forwarderInfo, seqNo);
insertToDiffLog (diff);
}
satisfyPendingSyncInterests (diff);
}
void
SyncLogic::sendSyncInterest ()
{
_LOG_DEBUG_ID("sendSyncInterest");
{
m_outstandingInterestName = m_syncPrefix;
ostringstream os;
os << *m_state->getDigest();
m_outstandingInterestName.append(os.str());
_LOG_DEBUG_ID (">> I " << m_outstandingInterestName);
}
_LOG_DEBUG_ID("sendSyncInterest: " << m_outstandingInterestName);
EventId eventId =
m_scheduler.scheduleEvent(ndn::time::seconds(m_syncInterestReexpress) +
ndn::time::milliseconds(GET_RANDOM(m_reexpressionJitter)),
bind (&SyncLogic::sendSyncInterest, this));
m_scheduler.cancelEvent (m_reexpressingInterestId);
m_reexpressingInterestId = eventId;
ndn::Interest interest(m_outstandingInterestName);
interest.setMustBeFresh(true);
m_face->expressInterest(interest,
bind(&SyncLogic::onSyncData, this, _1, _2),
bind(&SyncLogic::onSyncTimeout, this, _1));
}
void
SyncLogic::sendSyncRecoveryInterests (DigestConstPtr digest)
{
ostringstream os;
os << *digest;
Name interestName = m_syncPrefix;
interestName.append("recovery").append(os.str());
ndn::time::system_clock::Duration nextRetransmission =
ndn::time::milliseconds(m_recoveryRetransmissionInterval + GET_RANDOM (m_reexpressionJitter));
m_recoveryRetransmissionInterval <<= 1;
m_scheduler.cancelEvent (m_reexpressingRecoveryInterestId);
if (m_recoveryRetransmissionInterval < 100*1000) // <100 seconds
m_reexpressingRecoveryInterestId =
m_scheduler.scheduleEvent (nextRetransmission,
bind (&SyncLogic::sendSyncRecoveryInterests, this, digest));
ndn::Interest interest(interestName);
interest.setMustBeFresh(true);
m_face->expressInterest(interest,
bind(&SyncLogic::onSyncData, this, _1, _2),
bind(&SyncLogic::onSyncTimeout, this, _1));
}
void
SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, StateConstPtr state)
{
SyncStateMsg msg;
msg << (*state);
sendSyncData(name, digest, msg);
}
// pass in state msg instead of state, so that there is no need to lock the state until
// this function returns
void
SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, SyncStateMsg &ssm)
{
_LOG_DEBUG_ID (">> D " << name);
int size = ssm.ByteSize();
char *wireData = new char[size];
ssm.SerializeToArray(wireData, size);
//Data syncData(name);
ndn::shared_ptr<ndn::Data> syncData = ndn::make_shared<ndn::Data>();
syncData->setName(name);
syncData->setContent(reinterpret_cast<const uint8_t*>(wireData), size);
syncData->setFreshnessPeriod(ndn::time::seconds(m_syncResponseFreshness));
m_keyChain->sign(*syncData);
m_face->put(*syncData);
delete []wireData;
// checking if our own interest got satisfied
bool satisfiedOwnInterest = false;
{
satisfiedOwnInterest = (m_outstandingInterestName == name);
}
if (satisfiedOwnInterest)
{
_LOG_DEBUG_ID ("Satisfied our own Interest. Re-expressing (hopefully with a new digest)");
ndn::time::system_clock::Duration after =
ndn::time::milliseconds(GET_RANDOM(m_reexpressionJitter));
// cout << "------------ reexpress interest after: " << after << endl;
EventId eventId = m_scheduler.scheduleEvent (after,
bind (&SyncLogic::sendSyncInterest, this));
m_scheduler.cancelEvent (m_reexpressingInterestId);
m_reexpressingInterestId = eventId;
}
}
string
SyncLogic::getRootDigest()
{
ostringstream os;
os << *m_state->getDigest();
return os.str();
}
size_t
SyncLogic::getNumberOfBranches () const
{
return m_state->getLeaves ().size ();
}
void
SyncLogic::printState () const
{
BOOST_FOREACH (const shared_ptr<Sync::Leaf> leaf, m_state->getLeaves ())
{
std::cout << *leaf << std::endl;
}
}
std::map<std::string, bool>
SyncLogic::getBranchPrefixes() const
{
std::map<std::string, bool> m;
BOOST_FOREACH (const shared_ptr<Sync::Leaf> leaf, m_state->getLeaves ())
{
std::string prefix = leaf->getInfo()->toString();
// do not return forwarder prefix
if (prefix != forwarderPrefix)
{
m.insert(pair<std::string, bool>(prefix, false));
}
}
return m;
}
}
-223
View File
@@ -1,223 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
* Yingdi Yu <yingdi@cs.ucla.edu>
*/
#ifndef SYNC_LOGIC_H
#define SYNC_LOGIC_H
#include <boost/random.hpp>
#include <memory>
#include <map>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/validator.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include "sync-interest-table.h"
#include "sync-diff-state.h"
#include "sync-full-state.h"
#include "sync-std-name-info.h"
#include "sync-diff-state-container.h"
#ifdef _DEBUG
#ifdef HAVE_LOG4CXX
#include <log4cxx/logger.h>
#endif
#endif
namespace Sync {
struct MissingDataInfo {
std::string prefix;
SeqNo low;
SeqNo high;
};
/**
* \ingroup sync
* @brief A wrapper for SyncApp, which handles ccnx related things (process
* interests and data)
*/
class SyncLogic
{
public:
typedef function< void (const std::vector<MissingDataInfo> & ) > LogicUpdateCallback;
typedef function< void (const std::string &/*prefix*/ ) > LogicRemoveCallback;
typedef function< void (const std::string &)> LogicPerBranchCallback;
/**
* @brief Constructor
* @param syncPrefix the name prefix to use for the Sync Interest
* @param onUpdate function that will be called when new state is detected
* @param onRemove function that will be called when state is removed
* @param ccnxHandle ccnx handle
* the app data when new remote names are learned
*/
SyncLogic (const ndn::Name& syncPrefix,
ndn::shared_ptr<ndn::Validator> validator,
ndn::shared_ptr<ndn::Face> face,
LogicUpdateCallback onUpdate,
LogicRemoveCallback onRemove);
SyncLogic (const ndn::Name& syncPrefix,
ndn::shared_ptr<ndn::Validator> validator,
ndn::shared_ptr<ndn::Face> face,
LogicPerBranchCallback onUpdateBranch);
~SyncLogic ();
/**
* a wrapper for the same func in SyncApp
*/
void addLocalNames (const ndn::Name &prefix, uint64_t session, uint64_t seq);
/**
* @brief remove a participant's subtree from the sync tree
* @param prefix the name prefix for the participant
*/
void remove (const ndn::Name &prefix);
std::string
getRootDigest();
#ifdef _DEBUG
ndn::Scheduler &
getScheduler () { return m_scheduler; }
#endif
void
printState () const;
std::map<std::string, bool>
getBranchPrefixes() const;
private:
void
delayedChecksLoop ();
void
onSyncInterest (const ndn::Name& prefix, const ndn::Interest& interest);
void
onSyncRegisterSucceed(const ndn::Name& prefix);
void
onSyncRegisterFailed(const ndn::Name& prefix, const std::string& msg);
void
onSyncData(const ndn::Interest& interest, ndn::Data& data);
void
onSyncTimeout(const ndn::Interest& interest);
void
onSyncDataValidationFailed(const ndn::shared_ptr<const ndn::Data>& data);
void
onSyncDataValidated(const ndn::shared_ptr<const ndn::Data>& data);
void
processSyncInterest (const ndn::Name &name,
DigestConstPtr digest, bool timedProcessing=false);
void
processSyncData (const ndn::Name &name,
DigestConstPtr digest, const char *wireData, size_t len);
void
processSyncRecoveryInterest (const ndn::Name &name,
DigestConstPtr digest);
void
insertToDiffLog (DiffStatePtr diff);
void
satisfyPendingSyncInterests (DiffStateConstPtr diff);
tuple<DigestConstPtr, std::string>
convertNameToDigestAndType (const ndn::Name &name);
void
sendSyncInterest ();
void
sendSyncRecoveryInterests (DigestConstPtr digest);
void
sendSyncData (const ndn::Name &name,
DigestConstPtr digest, StateConstPtr state);
void
sendSyncData (const ndn::Name &name,
DigestConstPtr digest, SyncStateMsg &msg);
size_t
getNumberOfBranches () const;
private:
FullStatePtr m_state;
DiffStateContainer m_log;
ndn::Name m_outstandingInterestName;
SyncInterestTable m_syncInterestTable;
ndn::Name m_syncPrefix;
LogicUpdateCallback m_onUpdate;
LogicRemoveCallback m_onRemove;
LogicPerBranchCallback m_onUpdateBranch;
bool m_perBranch;
std::shared_ptr<ndn::Validator> m_validator;
std::shared_ptr<ndn::KeyChain> m_keyChain;
std::shared_ptr<ndn::Face> m_face;
const ndn::RegisteredPrefixId* m_syncRegisteredPrefixId;
ndn::Scheduler m_scheduler;
boost::mt19937 m_randomGenerator;
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_rangeUniformRandom;
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_reexpressionJitter;
static const int m_unknownDigestStoreTime = 10; // seconds
static const int m_syncResponseFreshness; // MUST BE dividable by 1000!!!
static const int m_syncInterestReexpress; // seconds
static const int m_defaultRecoveryRetransmitInterval = 200; // milliseconds
uint32_t m_recoveryRetransmissionInterval; // milliseconds
ndn::EventId m_delayedInterestProcessingId;
ndn::EventId m_reexpressingInterestId;
ndn::EventId m_reexpressingRecoveryInterestId;
std::string m_instanceId;
static int m_instanceCounter;
};
} // Sync
#endif // SYNC_APP_WRAPPER_H
-32
View File
@@ -1,32 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-name-info.h"
// #include <boost/lexical_cast.hpp>
namespace Sync {
NameInfo::NameMap NameInfo::m_names;
size_t NameInfo::m_ids = 0;
} // Sync
-102
View File
@@ -1,102 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_NAME_INFO_H
#define SYNC_NAME_INFO_H
#include "sync-common.h"
#include <map>
#include <string>
#include "sync-digest.h"
namespace Sync {
/**
* @ingroup sync
* @brief Templated class for the leaf name
*/
class NameInfo
{
private:
typedef weak_ptr<const NameInfo> const_weak_ptr;
public:
virtual ~NameInfo () { };
/**
* @brief Get ID of the record (should be locally-unique, but not really necessary---this is be used for hashing purposes)
*/
size_t
getHashId () const { return m_id; }
/**
* @brief Check if two names are equal
* @param info name to check with
*/
virtual bool
operator == (const NameInfo &info) const = 0;
/**
* @brief Check if two names are in order
* @param info name to check with
*/
virtual bool
operator < (const NameInfo &info) const = 0;
/**
* @brief Calculates digest of the name
*/
const Digest &
getDigest () const { return m_digest; }
/**
* @brief Convert prefix to string
* @returns string representation of prefix
*/
virtual std::string
toString () const = 0;
protected:
// actual stuff
size_t m_id; ///< @brief Identifies NameInfo throughout the library (for hash container, doesn't need to be strictly unique)
Digest m_digest;
// static stuff
typedef std::map<std::string, const_weak_ptr> NameMap;
static size_t m_ids;
static NameMap m_names;
};
typedef shared_ptr<NameInfo> NameInfoPtr;
typedef shared_ptr<const NameInfo> NameInfoConstPtr;
inline std::ostream &
operator << (std::ostream &os, const NameInfo &info)
{
os << info.toString ();
return os;
}
} // Sync
#endif // SYNC_NAME_INFO_H
-36
View File
@@ -1,36 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-seq-no.h"
namespace Sync {
DigestConstPtr
SeqNo::getDigest () const
{
DigestPtr digest = make_shared<Digest> ();
*digest << m_session << m_seq;
digest->finalize ();
return digest;
}
} // Sync
-198
View File
@@ -1,198 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
* Yingdi Yu <yingdi@cs.ucla.edu>
*/
#ifndef SYNC_SEQ_NO_H
#define SYNC_SEQ_NO_H
#include <boost/cstdint.hpp>
#include "sync-digest.h"
namespace Sync {
/**
* @ingroup sync
* @brief Sequence number abstraction
*/
class SeqNo
{
public:
/**
* @brief Default constructor. Creates an zero sequence number with zero session ID (basically is an invalid object)
*/
SeqNo ()
: m_valid (false)
, m_session (0)
, m_seq (0)
{
}
/**
* @brief Copy constructor
* @param seq sequence number object to copy from
*/
SeqNo (const SeqNo &seq)
{
*this = seq;
}
/**
* @brief Assignment operator
* @param seq sequence number object to copy from
*/
SeqNo &
operator = (const SeqNo &seq)
{
m_valid = seq.m_valid;
m_session = seq.m_session;
m_seq = seq.m_seq;
return *this;
}
/**
* @brief Constructor with just sequence number. Session assumed to be zero
* @param seq Sequence number
*/
SeqNo (uint64_t seq)
: m_valid (true)
, m_session (0)
, m_seq (seq)
{ }
/**
* @brief Constructor with session and sequence id
* @param session Session ID
* @param seq Sequence number
*/
SeqNo (uint64_t session, uint64_t seq)
: m_valid (true)
, m_session (session)
, m_seq (seq)
{ }
/**
* @brief Get sequence number digest
*
* Digest will be calculated every time it is requested
*/
DigestConstPtr
getDigest () const;
/**
* @brief Compare if one sequence number is lower
* @param seq Another sequence number to compare with
*
* tuple (session1, seq1) is less than (session2, seq2) in two cases:
* 1. session1 < session2
* 2. session1 == session2 and seq1 < seq2
*/
bool
operator < (const SeqNo &seq) const
{
return m_session < seq.m_session || (m_session == seq.m_session && m_seq < seq.m_seq);
}
/**
* @brief Compare if two sequence numbers are equal
* @param seq Another sequence number to compare with
*/
bool
operator == (const SeqNo &seq) const
{
return m_session == seq.m_session && m_seq == seq.m_seq;
}
bool
operator <= (const SeqNo &seq) const
{
return m_session == seq.m_session && m_seq <= seq.m_seq;
}
SeqNo &
operator ++ ()
{
if (m_valid) {
m_seq ++;
}
else {
m_valid = true;
}
return *this;
}
bool
isValid () const
{
return m_valid;
}
/**
* @brief Get session id
*/
uint64_t getSession () const
{ return m_session; }
/**
* @brief Get sequence number
*/
uint64_t getSeq () const
{ return m_seq; }
/**
* @brief Set sequence number
*/
void
setSeq(uint64_t seq)
{ m_seq = seq; }
private:
bool m_valid;
/**
* @brief Session ID (e.g., after crash, application will choose new session ID.
*
* Note that session IDs for the same name should always increase. So, the good choice
* for the session ID is client's timestamp
*/
uint64_t m_session;
/**
* @brief Sequence number
*
* Sequence number for a session always starts with 0 and goes to max value.
*
* For now, wrapping sequence number after max to zero is not supported
*/
uint64_t m_seq;
};
inline std::ostream &
operator << (std::ostream &os, const SeqNo &seqno)
{
os << "<session>" << seqno.getSession () << "</session><seqno>" << seqno.getSeq () << "</seqno>";
return os;
}
} // Sync
#endif // SYNC_SEQ_NO_H
-176
View File
@@ -1,176 +0,0 @@
/* -*- Mode: C32++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
*/
#include "sync-socket.h"
#include "sync-logging.h"
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
using namespace std;
using ndn::Data;
using ndn::Face;
using ndn::KeyChain;
using ndn::Name;
using ndn::OnDataValidated;
using ndn::OnDataValidationFailed;
using ndn::Validator;
INIT_LOGGER ("SyncSocket");
namespace Sync {
using ndn::shared_ptr;
using ndn::make_shared;
SyncSocket::SyncSocket (const Name &syncPrefix,
shared_ptr<Validator> validator,
shared_ptr<Face> face,
NewDataCallback dataCallback,
RemoveCallback rmCallback )
: m_newDataCallback(dataCallback)
, m_validator(validator)
, m_keyChain(new KeyChain())
, m_face(face)
, m_syncLogic (syncPrefix,
validator,
face,
bind(&SyncSocket::passCallback, this, _1),
rmCallback)
{
}
SyncSocket::~SyncSocket()
{
}
bool
SyncSocket::publishData(const Name &prefix, uint64_t session,
const char *buf, size_t len,
int freshness,uint64_t seq)
{
shared_ptr<Data> data = make_shared<Data>();
data->setContent(reinterpret_cast<const uint8_t*>(buf), len);
data->setFreshnessPeriod(ndn::time::seconds(freshness));
m_face->getIoService().post(bind(&SyncSocket::publishDataInternal, this,
data, prefix, session,seq));
return true;
}
void
SyncSocket::publishDataInternal(shared_ptr<Data> data,
const Name &prefix, uint64_t session, uint64_t seq)
{
uint64_t sequence = seq;
Name dataName = prefix;
dataName.append(boost::lexical_cast<string>(session))
.append(boost::lexical_cast<string>(sequence));
data->setName(dataName);
m_keyChain->sign(*data);
m_face->put(*data);
SeqNo s(session, sequence + 1);
m_sequenceLog[prefix] = s;
m_syncLogic.addLocalNames (prefix, session, sequence);
}
void
SyncSocket::fetchData(const Name &prefix, const SeqNo &seq,
const OnDataValidated& onValidated, int retry)
{
Name interestName = prefix;
interestName.append(boost::lexical_cast<string>(seq.getSession()))
.append(boost::lexical_cast<string>(seq.getSeq()));
const OnDataValidationFailed& onValidationFailed =
bind(&SyncSocket::onDataValidationFailed, this, _1);
ndn::Interest interest(interestName);
interest.setMustBeFresh(true);
m_face->expressInterest(interest,
bind(&SyncSocket::onData, this, _1, _2,
onValidated, onValidationFailed),
bind(&SyncSocket::onDataTimeout, this, _1, retry,
onValidated, onValidationFailed));
}
void
SyncSocket::onData(const ndn::Interest& interest, Data& data,
const OnDataValidated& onValidated,
const OnDataValidationFailed& onValidationFailed)
{
m_validator->validate(data, onValidated, onValidationFailed);
}
void
SyncSocket::onDataTimeout(const ndn::Interest& interest,
int retry,
const OnDataValidated& onValidated,
const OnDataValidationFailed& onValidationFailed)
{
if(retry > 0)
{
m_face->expressInterest(interest,
bind(&SyncSocket::onData,
this,
_1,
_2,
onValidated,
onValidationFailed),
bind(&SyncSocket::onDataTimeout,
this,
_1,
retry - 1,
onValidated,
onValidationFailed));
}
else
_LOG_DEBUG("interest eventually time out!");
}
void
SyncSocket::onDataValidationFailed(const shared_ptr<const Data>& data)
{
_LOG_DEBUG("data cannot be verified!");
}
uint64_t
SyncSocket::getNextSeq (const Name &prefix, uint64_t session)
{
SequenceLog::iterator i = m_sequenceLog.find (prefix);
if (i != m_sequenceLog.end ())
{
SeqNo s = i->second;
if (s.getSession() == session)
return s.getSeq();
}
return 0;
}
}//Sync
-134
View File
@@ -1,134 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
*/
#ifndef _SYNC_SOCKET_H
#define _SYNC_SOCKET_H
#include "sync-common.h"
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/validator.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include "sync-logic.h"
#include "sync-seq-no.h"
#include <utility>
#include <map>
#include <vector>
#include <sstream>
namespace Sync {
/**
* \ingroup sync
* @brief A simple interface to interact with client code
*/
class SyncSocket
{
public:
typedef ndn::function<void(const std::vector<MissingDataInfo> &, SyncSocket *)> NewDataCallback;
typedef ndn::function<void(const std::string &/*prefix*/)> RemoveCallback;
/**
* @brief the constructor for SyncAppSocket; the parameter syncPrefix
* should be passed to the constructor of m_syncAppWrapper; the other
* parameter should be passed to the constructor of m_fetcher; furthermore,
* the fetch function of m_fetcher should be a second paramter passed to
* the constructor of m_syncAppWrapper, so that m_syncAppWrapper can tell
* m_fetcher to fetch the actual app data after it learns the names
*
* @param syncPrefix the name prefix for Sync Interest
* @param dataCallback the callback to process data
*/
SyncSocket (const ndn::Name &syncPrefix,
ndn::shared_ptr<ndn::Validator> validator,
ndn::shared_ptr<ndn::Face> face,
NewDataCallback dataCallback,
RemoveCallback rmCallback);
~SyncSocket ();
bool
publishData(const ndn::Name &prefix, uint64_t session, const char *buf, size_t len,
int freshness,uint64_t seq);
void
remove (const ndn::Name &prefix)
{ m_syncLogic.remove(prefix); }
void
fetchData(const ndn::Name &prefix, const SeqNo &seq,
const ndn::OnDataValidated& onValidated, int retry = 0);
std::string
getRootDigest()
{ return m_syncLogic.getRootDigest(); }
uint64_t
getNextSeq (const ndn::Name &prefix, uint64_t session);
SyncLogic &
getLogic ()
{ return m_syncLogic; }
// make this a static function so we don't have to create socket instance without
// knowing the local prefix. it's a wrong place for this function anyway
static std::string
GetLocalPrefix ();
private:
void
publishDataInternal(ndn::shared_ptr<ndn::Data> data,
const ndn::Name &prefix, uint64_t session,uint64_t seq);
void
passCallback(const std::vector<MissingDataInfo> &v)
{
m_newDataCallback(v, this);
}
void
onData(const ndn::Interest& interest, ndn::Data& data,
const ndn::OnDataValidated& onValidated,
const ndn::OnDataValidationFailed& onValidationFailed);
void
onDataTimeout(const ndn::Interest& interest,
int retry,
const ndn::OnDataValidated& onValidated,
const ndn::OnDataValidationFailed& onValidationFailed);
void
onDataValidationFailed(const ndn::shared_ptr<const ndn::Data>& data);
private:
typedef std::map<ndn::Name, SeqNo> SequenceLog;
NewDataCallback m_newDataCallback;
SequenceLog m_sequenceLog;
ndn::shared_ptr<ndn::Validator> m_validator;
ndn::shared_ptr<ndn::KeyChain> m_keyChain;
ndn::shared_ptr<ndn::Face> m_face;
SyncLogic m_syncLogic;
};
} // Sync
#endif // SYNC_SOCKET_H
-101
View File
@@ -1,101 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_STATE_LEAF_CONTAINER
#define SYNC_STATE_LEAF_CONTAINER
#include "sync-leaf.h"
#include "sync-name-info.h"
#include <boost/multi_index_container.hpp>
// #include <boost/multi_index/tag.hpp>
#include <boost/multi_index/ordered_index.hpp>
// #include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/hashed_index.hpp>
// #include <boost/multi_index/random_access_index.hpp>
// #include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
namespace mi = boost::multi_index;
namespace Sync {
struct NameInfoHash : public std::unary_function<NameInfo, std::size_t>
{
std::size_t
operator() (NameInfoConstPtr prefix) const
{
return prefix->getHashId ();
}
};
struct NameInfoEqual : public std::unary_function<NameInfo, std::size_t>
{
bool
operator() (NameInfoConstPtr prefix1, NameInfoConstPtr prefix2) const
{
return *prefix1 == *prefix2;
}
};
struct NameInfoCompare : public std::unary_function<NameInfo, std::size_t>
{
bool
operator() (NameInfoConstPtr prefix1, NameInfoConstPtr prefix2) const
{
return *prefix1 < *prefix2;
}
};
/// @cond include_hidden
struct hashed { };
struct ordered { };
/// @endcond
/**
* \ingroup sync
* @brief Container for SYNC leaves
*/
struct LeafContainer : public mi::multi_index_container<
LeafPtr,
mi::indexed_by<
// For fast access to elements using NameInfo
mi::hashed_unique<
mi::tag<hashed>,
mi::const_mem_fun<Leaf, NameInfoConstPtr, &Leaf::getInfo>,
NameInfoHash,
NameInfoEqual
>,
mi::ordered_unique<
mi::tag<ordered>,
mi::const_mem_fun<Leaf, NameInfoConstPtr, &Leaf::getInfo>,
NameInfoCompare
>
>
>
{
};
} // Sync
#endif // SYNC_STATE_LEAF_CONTAINER
-169
View File
@@ -1,169 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-state.h"
#include "sync-diff-leaf.h"
#include "sync-std-name-info.h"
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/throw_exception.hpp>
#include <boost/lexical_cast.hpp>
typedef boost::error_info<struct tag_errmsg, std::string> info_str;
using namespace Sync::Error;
using boost::lexical_cast;
namespace Sync {
/*
std::ostream &
operator << (std::ostream &os, const State &state)
{
os << "<state>"; DEBUG_ENDL;
BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
{
shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
if (diffLeaf != 0)
{
os << "<item action=\"" << diffLeaf->getOperation () << "\">"; DEBUG_ENDL;
}
else
{
os << "<item>"; DEBUG_ENDL;
}
os << "<name>" << *leaf->getInfo () << "</name>"; DEBUG_ENDL;
if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
{
os << "<seq>" << leaf->getSeq () << "</seq>"; DEBUG_ENDL;
}
os << "</item>"; DEBUG_ENDL;
}
os << "</state>";
}
*/
SyncStateMsg &
operator << (SyncStateMsg &ossm, const State &state)
{
BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
{
SyncState *oss = ossm.add_ss();
shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
if (diffLeaf != 0 && diffLeaf->getOperation() != UPDATE)
{
oss->set_type(SyncState::DELETE);
}
else
{
oss->set_type(SyncState::UPDATE);
}
std::ostringstream os;
os << *leaf->getInfo();
oss->set_name(os.str());
if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
{
SyncState::SeqNo *seqNo = oss->mutable_seqno();
seqNo->set_session(leaf->getSeq().getSession());
seqNo->set_seq(leaf->getSeq().getSeq());
}
}
return ossm;
}
/*
std::istream &
operator >> (std::istream &in, State &state)
{
TiXmlDocument doc;
in >> doc;
if (doc.RootElement() == 0)
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("Empty XML"));
for (TiXmlElement *iterator = doc.RootElement()->FirstChildElement ("item");
iterator != 0;
iterator = iterator->NextSiblingElement("item"))
{
TiXmlElement *name = iterator->FirstChildElement ("name");
if (name == 0 || name->GetText() == 0)
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<name> element is missing"));
NameInfoConstPtr info = StdNameInfo::FindOrCreate (name->GetText());
if (iterator->Attribute("action") == 0 || strcmp(iterator->Attribute("action"), "update") == 0)
{
TiXmlElement *seq = iterator->FirstChildElement ("seq");
if (seq == 0)
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seq> element is missing"));
TiXmlElement *session = seq->FirstChildElement ("session");
TiXmlElement *seqno = seq->FirstChildElement ("seqno");
if (session == 0 || session->GetText() == 0)
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<session> element is missing"));
if (seqno == 0 || seqno->GetText() == 0)
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seqno> element is missing"));
state.update (info, SeqNo (
lexical_cast<uint32_t> (session->GetText()),
lexical_cast<uint32_t> (seqno->GetText())
));
}
else
{
state.remove (info);
}
}
return in;
}
*/
SyncStateMsg &
operator >> (SyncStateMsg &issm, State &state)
{
int n = issm.ss_size();
for (int i = 0; i < n; i++)
{
const SyncState &ss = issm.ss(i);
NameInfoConstPtr info = StdNameInfo::FindOrCreate (ss.name());
if (ss.type() == SyncState::UPDATE)
{
uint64_t session = lexical_cast<uint64_t>(ss.seqno().session());
uint64_t seq = lexical_cast<uint64_t>(ss.seqno().seq());
SeqNo seqNo(session, seq);
state.update(info, seqNo);
}
else
{
state.remove(info);
}
}
return issm;
}
}
-116
View File
@@ -1,116 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_STATE_H
#define SYNC_STATE_H
#include "sync-state-leaf-container.h"
#include <boost/exception/all.hpp>
#include "sync-state.pb.h"
/**
* \defgroup sync SYNC protocol
*
* Implementation of SYNC protocol
*/
namespace Sync {
/**
* \ingroup sync
* @brief this prefix will be used for the dummy node which increases its sequence number whenever
* a remove operation happens; this is to prevent the reversion of root digest when we prune
* a branch, i.e. help the root digest to be forward only
* No corresponding data msg would be published and no attempt would be made to retrieve the
* data msg
*/
const std::string forwarderPrefix = "/d0n0t18ak/t0ps8cr8t";
class State;
typedef shared_ptr<State> StatePtr;
typedef shared_ptr<State> StateConstPtr;
/**
* \ingroup sync
* @brief Container for state leaves and definition of the abstract interface to work with State objects
*/
class State
{
public:
virtual ~State () { };
/**
* @brief Add or update leaf to the state tree
*
* @param info name of the leaf
* @param seq sequence number of the leaf
*/
virtual tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
update (NameInfoConstPtr info, const SeqNo &seq) = 0;
/**
* @brief Remove leaf from the state tree
* @param info name of the leaf
*/
virtual bool
remove (NameInfoConstPtr info) = 0;
/**
* @brief Get state leaves
*/
const LeafContainer &
getLeaves () const
{ return m_leaves; }
protected:
LeafContainer m_leaves;
};
/**
* @brief Formats a protobuf SyncStateMsg msg
* @param oss output SyncStateMsg msg
* @param state state
* @returns output SyncStateMsg msg
*/
SyncStateMsg &
operator << (SyncStateMsg &ossm, const State &state);
/**
* @brief Parse a protobuf SyncStateMsg msg
* @param iss input SyncStateMsg msg
* @param state state
* @returns SyncStateMsg msg
*/
SyncStateMsg &
operator >> (SyncStateMsg &issm, State &state);
namespace Error {
/**
* @brief Will be thrown when data cannot be properly decoded to SyncStateMsg
*/
struct SyncStateMsgDecodingFailure : virtual boost::exception, virtual std::exception { };
}
} // Sync
#endif // SYNC_STATE_H
-24
View File
@@ -1,24 +0,0 @@
package Sync;
message SyncState
{
required string name = 1;
enum ActionType
{
UPDATE = 0;
DELETE = 1;
OTHER = 2;
}
required ActionType type = 2;
message SeqNo
{
required uint64 seq = 1;
required uint64 session = 2;
}
optional SeqNo seqno = 3;
}
message SyncStateMsg
{
repeated SyncState ss = 1;
}
-89
View File
@@ -1,89 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "sync-std-name-info.h"
namespace Sync {
NameInfoConstPtr
StdNameInfo::FindOrCreate (const std::string &key)
{
// std::cout << "FindOrCreate: " << m_names.size () << "\n";
NameInfoConstPtr ret;
NameMap::iterator item = m_names.find (key);
if (item != m_names.end ())
{
ret = item->second.lock ();
BOOST_ASSERT (ret != 0);
}
else
{
ret = NameInfoPtr (new StdNameInfo (key));
weak_ptr<const NameInfo> value (ret);
std::pair<NameMap::iterator,bool> inserted =
m_names.insert (make_pair (key, value));
BOOST_ASSERT (inserted.second); // previous call has to insert value
item = inserted.first;
}
return ret;
}
StdNameInfo::StdNameInfo (const std::string &name)
: m_name (name)
{
m_id = m_ids ++; // set ID for a newly inserted element
m_digest << name;
m_digest.finalize ();
// std::cout << "StdNameInfo: " << name << " = " << m_id << "\n";
}
StdNameInfo::~StdNameInfo ()
{
// cout << "Destructor for " << m_name << "\n";
m_names.erase (toString ());
}
std::string
StdNameInfo::toString () const
{
return m_name;
}
bool
StdNameInfo::operator == (const NameInfo &info) const
{
return m_name == dynamic_cast<const StdNameInfo&> (info).m_name;
}
bool
StdNameInfo::operator < (const NameInfo &info) const
{
return m_name < dynamic_cast<const StdNameInfo&> (info).m_name;
}
} // Sync
-74
View File
@@ -1,74 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef SYNC_STD_NAME_INFO_H
#define SYNC_STD_NAME_INFO_H
#include "sync-name-info.h"
#include <string>
namespace Sync {
class StdNameInfo : public NameInfo
{
public:
/**
* @brief Lookup existing or create new NameInfo object
* @param name routable prefix
*/
static NameInfoConstPtr
FindOrCreate (const std::string &name);
/**
* @brief Destructor which will clean up m_names structure
*/
virtual ~StdNameInfo ();
// from NameInfo
virtual bool
operator == (const NameInfo &info) const;
virtual bool
operator < (const NameInfo &info) const;
virtual std::string
toString () const;
private:
// implementing a singleton pattern.
/**
* @brief Disabled default constructor. NameInfo object should be created through FindOrCreate static call.
*/
/**
* @brief Disabled default
*/
StdNameInfo () {}
StdNameInfo& operator = (const StdNameInfo &info) { (void)info; return *this; }
StdNameInfo (const std::string &name);
std::string m_name;
};
} // Sync
#endif // SYNC_CCNX_NAME_INFO_H
+58 -84
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2016, The University of Memphis,
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -29,9 +29,7 @@
namespace nlsr {
INIT_LOGGER("AdjacencyList");
using namespace std;
INIT_LOGGER(AdjacencyList);
AdjacencyList::AdjacencyList()
{
@@ -61,20 +59,6 @@ AdjacencyList::addAdjacents(AdjacencyList& adl)
}
}
bool
AdjacencyList::updateAdjacentStatus(const ndn::Name& adjName, Adjacent::Status s)
{
std::list<Adjacent>::iterator it = find(adjName);
if (it == m_adjList.end()) {
return false;
}
else {
it->setStatus(s);
return true;
}
}
Adjacent
AdjacencyList::getAdjacent(const ndn::Name& adjName)
{
@@ -86,49 +70,23 @@ AdjacencyList::getAdjacent(const ndn::Name& adjName)
return adj;
}
static bool
compareAdjacent(const Adjacent& adjacent1, const Adjacent& adjacent2)
{
return adjacent1.getName() < adjacent2.getName();
}
bool
AdjacencyList::operator==(AdjacencyList& adl)
AdjacencyList::operator==(const AdjacencyList& adl) const
{
if (getSize() != adl.getSize()) {
if (m_adjList.size() != adl.getAdjList().size()) {
return false;
}
m_adjList.sort(compareAdjacent);
adl.getAdjList().sort(compareAdjacent);
uint32_t equalAdjCount = 0;
std::list<Adjacent>& adjList2 = adl.getAdjList();
std::list<Adjacent>::iterator it1;
std::list<Adjacent>::iterator it2;
for (it1 = m_adjList.begin(), it2 = adjList2.begin();
it1 != m_adjList.end(); it1++, it2++) {
if (!((*it1) == (*it2))) {
break;
}
equalAdjCount++;
}
return equalAdjCount == getSize();
}
int32_t
AdjacencyList::updateAdjacentLinkCost(const ndn::Name& adjName, double lc)
{
std::list<Adjacent>::iterator it = find(adjName);
if (it == m_adjList.end()) {
return -1;
}
(*it).setLinkCost(lc);
return 0;
std::set<Adjacent> ourList(m_adjList.cbegin(), m_adjList.cend());
std::set<Adjacent> theirList(adl.getAdjList().cbegin(), adl.getAdjList().cend());
return ourList == theirList;
}
bool
AdjacencyList::isNeighbor(const ndn::Name& adjName)
AdjacencyList::isNeighbor(const ndn::Name& adjName) const
{
std::list<Adjacent>::iterator it = find(adjName);
std::list<Adjacent>::const_iterator it = find(adjName);
if (it == m_adjList.end())
{
return false;
@@ -157,9 +115,9 @@ AdjacencyList::setTimedOutInterestCount(const ndn::Name& neighbor,
}
int32_t
AdjacencyList::getTimedOutInterestCount(const ndn::Name& neighbor)
AdjacencyList::getTimedOutInterestCount(const ndn::Name& neighbor) const
{
std::list<Adjacent>::iterator it = find(neighbor);
std::list<Adjacent>::const_iterator it = find(neighbor);
if (it == m_adjList.end()) {
return -1;
}
@@ -167,9 +125,9 @@ AdjacencyList::getTimedOutInterestCount(const ndn::Name& neighbor)
}
Adjacent::Status
AdjacencyList::getStatusOfNeighbor(const ndn::Name& neighbor)
AdjacencyList::getStatusOfNeighbor(const ndn::Name& neighbor) const
{
std::list<Adjacent>::iterator it = find(neighbor);
std::list<Adjacent>::const_iterator it = find(neighbor);
if (it == m_adjList.end()) {
return Adjacent::STATUS_UNKNOWN;
@@ -194,6 +152,12 @@ AdjacencyList::getAdjList()
return m_adjList;
}
const std::list<Adjacent>&
AdjacencyList::getAdjList() const
{
return m_adjList;
}
bool
AdjacencyList::isAdjLsaBuildable(const uint32_t interestRetryNo) const
{
@@ -218,10 +182,10 @@ AdjacencyList::isAdjLsaBuildable(const uint32_t interestRetryNo) const
}
int32_t
AdjacencyList::getNumOfActiveNeighbor()
AdjacencyList::getNumOfActiveNeighbor() const
{
int32_t actNbrCount = 0;
for (std::list<Adjacent>::iterator it = m_adjList.begin(); it != m_adjList.end(); it++) {
for (std::list<Adjacent>::const_iterator it = m_adjList.begin(); it != m_adjList.end(); it++) {
if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
actNbrCount++;
@@ -235,45 +199,55 @@ AdjacencyList::find(const ndn::Name& adjName)
{
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
m_adjList.end(),
ndn::bind(&Adjacent::compare,
_1, ndn::cref(adjName)));
std::bind(&Adjacent::compare,
_1, std::cref(adjName)));
return it;
}
Adjacent *
AdjacencyList::findAdjacent(const ndn::Name& adjName)
std::list<Adjacent>::const_iterator
AdjacencyList::find(const ndn::Name& adjName) const
{
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
m_adjList.end(),
ndn::bind(&Adjacent::compare,
_1, ndn::cref(adjName)));
if (it != m_adjList.end()) {
return &(*it);
}
return 0;
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;
}
Adjacent *
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)));
}
AdjacencyList::iterator
AdjacencyList::findAdjacent(uint64_t faceId)
{
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
m_adjList.end(),
ndn::bind(&Adjacent::compareFaceId,
_1, faceId));
if (it != m_adjList.end()) {
return &(*it);
}
return std::find_if(m_adjList.begin(),
m_adjList.end(),
std::bind(&Adjacent::compareFaceId,
_1, faceId));
}
return 0;
AdjacencyList::iterator
AdjacencyList::findAdjacent(const ndn::FaceUri& faceUri)
{
return std::find_if(m_adjList.begin(),
m_adjList.end(),
std::bind(&Adjacent::compareFaceUri,
_1, faceUri));
}
uint64_t
AdjacencyList::getFaceId(const std::string& faceUri)
AdjacencyList::getFaceId(const ndn::FaceUri& faceUri)
{
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
m_adjList.end(),
ndn::bind(&Adjacent::compareFaceUri,
std::bind(&Adjacent::compareFaceUri,
_1, faceUri));
if (it != m_adjList.end()) {
return it->getFaceId();
@@ -285,11 +259,11 @@ AdjacencyList::getFaceId(const std::string& faceUri)
void
AdjacencyList::writeLog()
{
_LOG_DEBUG("-------Adjacency List--------");
NLSR_LOG_DEBUG("-------Adjacency List--------");
for (std::list<Adjacent>::iterator it = m_adjList.begin();
it != m_adjList.end(); it++) {
(*it).writeLog();
}
}
} //namespace nlsr
} // namespace nlsr
+69 -21
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2016, The University of Memphis,
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -22,11 +22,11 @@
#ifndef NLSR_ADJACENCY_LIST_HPP
#define NLSR_ADJACENCY_LIST_HPP
#include "adjacent.hpp"
#include "common.hpp"
#include <list>
#include <boost/cstdint.hpp>
#include <ndn-cxx/common.hpp>
#include "adjacent.hpp"
namespace nlsr {
@@ -39,29 +39,36 @@ public:
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
updateAdjacentStatus(const ndn::Name& adjName, Adjacent::Status s);
int32_t
updateAdjacentLinkCost(const ndn::Name& adjName, double lc);
std::list<Adjacent>&
getAdjList();
const std::list<Adjacent>&
getAdjList() const;
bool
isNeighbor(const ndn::Name& adjName);
isNeighbor(const ndn::Name& adjName) const;
void
incrementTimedOutInterestCount(const ndn::Name& neighbor);
int32_t
getTimedOutInterestCount(const ndn::Name& neighbor);
getTimedOutInterestCount(const ndn::Name& neighbor) const;
Adjacent::Status
getStatusOfNeighbor(const ndn::Name& neighbor);
getStatusOfNeighbor(const ndn::Name& neighbor) const;
void
setStatusOfNeighbor(const ndn::Name& neighbor, Adjacent::Status status);
@@ -69,23 +76,45 @@ 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.
\return Returns a boolean indicating whether this list can be used
to build an adj. LSA.
Determines whether this adjacency list object could be used to
build an adjacency LSA. An LSA is buildable when the status of all
neighbors is known. A neighbor's status is known when their status
is ACTIVE, or INACTIVE and some number of hello interests
(specified by nlsr::ConfParameter::getInterestRetryNumber()) have
failed. To be explicit, a neighbor's status is unknown if we are
still sending hello interests.
*/
bool
isAdjLsaBuildable(const uint32_t interestRetryNo) const;
int32_t
getNumOfActiveNeighbor();
getNumOfActiveNeighbor() const;
Adjacent
getAdjacent(const ndn::Name& adjName);
bool
operator==(AdjacencyList& adl);
operator==(const AdjacencyList& adl) const;
size_t
getSize()
size() const
{
return m_adjList.size();
}
@@ -98,14 +127,30 @@ public:
}
}
Adjacent*
AdjacencyList::iterator
findAdjacent(const ndn::Name& adjName);
Adjacent*
AdjacencyList::iterator
findAdjacent(uint64_t faceId);
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 std::string& faceUri);
getFaceId(const ndn::FaceUri& faceUri);
void
writeLog();
@@ -127,9 +172,12 @@ private:
iterator
find(const ndn::Name& adjName);
const_iterator
find(const ndn::Name& adjName) const;
private:
std::list<Adjacent> m_adjList;
};
} //namespace nlsr
#endif //NLSR_ADJACENCY_LIST_HPP
} // namespace nlsr
#endif // NLSR_ADJACENCY_LIST_HPP
+31 -25
View File
@@ -1,7 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 University of Memphis,
* Regents of the University of California
* 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.
@@ -16,30 +16,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/>.
*
* \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
*
**/
#include "adjacent.hpp"
#include "logger.hpp"
#include <iostream>
#include <string>
#include <cmath>
#include <limits>
#include "adjacent.hpp"
#include "logger.hpp"
namespace nlsr {
INIT_LOGGER("Adjacent");
using namespace std;
INIT_LOGGER(Adjacent);
const float Adjacent::DEFAULT_LINK_COST = 10.0;
Adjacent::Adjacent()
: m_name()
, m_connectingFaceUri()
, m_faceUri()
, m_linkCost(DEFAULT_LINK_COST)
, m_status(STATUS_INACTIVE)
, m_interestTimedOutNo(0)
@@ -49,7 +44,7 @@ Adjacent::Adjacent()
Adjacent::Adjacent(const ndn::Name& an)
: m_name(an)
, m_connectingFaceUri()
, m_faceUri()
, m_linkCost(DEFAULT_LINK_COST)
, m_status(STATUS_INACTIVE)
, m_interestTimedOutNo(0)
@@ -57,35 +52,46 @@ Adjacent::Adjacent(const ndn::Name& an)
{
}
Adjacent::Adjacent(const ndn::Name& an, const std::string& cfu, double lc,
Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
Status s, uint32_t iton, uint64_t faceId)
: m_name(an)
, m_connectingFaceUri(cfu)
, m_faceUri(faceUri)
, m_linkCost(lc)
, m_status(s)
, m_interestTimedOutNo(iton)
, m_faceId(faceId)
{
}
bool
Adjacent::operator==(const Adjacent& adjacent) const
{
return (m_name == adjacent.getName()) &&
(m_connectingFaceUri == adjacent.getConnectingFaceUri()) &&
(m_faceUri == adjacent.getFaceUri()) &&
(std::abs(m_linkCost - adjacent.getLinkCost()) <
std::numeric_limits<double>::epsilon()) ;
std::numeric_limits<double>::epsilon());
}
bool
Adjacent::operator<(const Adjacent& adjacent) const
{
return (m_name < adjacent.getName()) ||
(m_linkCost < adjacent.getLinkCost());
}
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;
return os;
}
void
Adjacent::writeLog()
{
_LOG_DEBUG("Adjacent : " << m_name);
_LOG_DEBUG("Connecting FaceUri: " << m_connectingFaceUri);
_LOG_DEBUG("Link Cost: " << m_linkCost);
_LOG_DEBUG("Status: " << m_status);
_LOG_DEBUG("Interest Timed out: " << m_interestTimedOutNo);
NLSR_LOG_DEBUG(*this);
}
} //namespace nlsr
} // namespace nlsr
+46 -18
View File
@@ -1,7 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 University of Memphis,
* Regents of the University of California
* 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.
@@ -16,20 +16,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/>.
*
* \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
*
**/
#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
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.
*/
class Adjacent
{
@@ -45,7 +50,7 @@ public:
Adjacent(const ndn::Name& an);
Adjacent(const ndn::Name& an, const std::string& cfu, double lc,
Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
Status s, uint32_t iton, uint64_t faceId);
const ndn::Name&
@@ -60,16 +65,16 @@ public:
m_name = an;
}
const std::string&
getConnectingFaceUri() const
const ndn::FaceUri&
getFaceUri() const
{
return m_connectingFaceUri;
return m_faceUri;
}
void
setConnectingFaceUri(const std::string& cfu)
setFaceUri(const ndn::FaceUri& faceUri)
{
m_connectingFaceUri = cfu;
m_faceUri = faceUri;
}
uint64_t
@@ -116,30 +121,40 @@ public:
}
uint64_t
getFaceId()
getFaceId() const
{
return m_faceId;
}
/*! \brief Equality is when name, Face URI, and link cost are all equal. */
bool
operator==(const Adjacent& adjacent) const;
bool
operator!=(const Adjacent& adjacent) const
{
return !(*this == adjacent);
}
bool
operator<(const Adjacent& adjacent) const;
inline bool
compare(const ndn::Name& adjacencyName)
compare(const ndn::Name& adjacencyName) const
{
return m_name == adjacencyName;
}
inline bool
compareFaceId(uint64_t faceId)
compareFaceId(const uint64_t faceId) const
{
return m_faceId == faceId;
}
inline bool
compareFaceUri(std::string& faceUri)
compareFaceUri(const ndn::FaceUri& faceUri) const
{
return m_connectingFaceUri == faceUri;
return m_faceUri == faceUri;
}
void
@@ -149,14 +164,27 @@ public:
static const float DEFAULT_LINK_COST;
private:
/*! m_name The NLSR-configured router name of the neighbor */
ndn::Name m_name;
std::string m_connectingFaceUri;
/*! m_faceUri The NFD-level specification of the Face*/
ndn::FaceUri m_faceUri;
/*! 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;
/*! m_interestTimedOutNo How many failed Hello interests we have sent since the last reply */
uint32_t m_interestTimedOutNo;
/*! m_faceId The NFD-assigned ID for the neighbor, used to
* determine whether a Face is available */
uint64_t m_faceId;
friend std::ostream&
operator<<(std::ostream& os, const Adjacent& adjacent);
};
std::ostream&
operator<<(std::ostream& os, const Adjacent& adjacent);
} // namespace nlsr
#endif //NLSR_ADJACENT_HPP
#endif // NLSR_ADJACENT_HPP
+28 -3
View File
@@ -1,7 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 University of Memphis,
* Regents of the University of California
* 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.
@@ -19,10 +19,17 @@
*
**/
/*! \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 <ndn-cxx/name.hpp>
namespace nlsr {
@@ -31,6 +38,24 @@ using std::make_shared;
using std::shared_ptr;
using std::function;
}
const ndn::time::seconds TIME_ALLOWED_FOR_CANONIZATION = ndn::time::seconds(4);
template<typename T, typename = void>
struct is_iterator
{
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>
{
static constexpr bool value = true;
};
} // namespace nlsr
#endif // NLSR_COMMON_HPP
+101 -199
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2016, The University of Memphis,
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -20,101 +20,18 @@
**/
#include "sync-logic-handler.hpp"
#include "common.hpp"
#include "conf-parameter.hpp"
#include "logger.hpp"
#include "lsa.hpp"
#include "lsdb.hpp"
#include "sequencing-manager.hpp"
#include "utility/name-helper.hpp"
#include "logger.hpp"
namespace nlsr {
INIT_LOGGER("SyncLogicHandler");
INIT_LOGGER(SyncLogicHandler);
using namespace ndn;
using namespace std;
class SyncUpdate
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
public:
SyncUpdate(const ndn::Name& name, uint64_t seqNo)
: m_name(name)
, m_seqManager(seqNo)
{
}
const ndn::Name&
getName() const
{
return m_name;
}
const ndn::Name
getOriginRouter() const
{
int32_t nlsrPosition = util::getNameComponentPosition(m_name, NLSR_COMPONENT);
int32_t lsaPosition = util::getNameComponentPosition(m_name, LSA_COMPONENT);
if (nlsrPosition < 0 || lsaPosition < 0) {
throw Error("Cannot parse update name because expected components are missing");
}
ndn::Name networkName = m_name.getSubName(0, nlsrPosition);
ndn::Name routerName = m_name.getSubName(lsaPosition + 1);
ndn::Name originRouter = networkName;
originRouter.append(routerName);
return originRouter;
}
uint64_t
getNameLsaSeqNo() const
{
return m_seqManager.getNameLsaSeq();
}
uint64_t
getAdjLsaSeqNo() const
{
return m_seqManager.getAdjLsaSeq();
}
uint64_t
getCorLsaSeqNo() const
{
return m_seqManager.getCorLsaSeq();
}
const SequencingManager&
getSequencingManager() const
{
return m_seqManager;
}
private:
const ndn::Name m_name;
SequencingManager m_seqManager;
static const std::string NLSR_COMPONENT;
static const std::string LSA_COMPONENT;
};
const std::string SyncUpdate::NLSR_COMPONENT = "NLSR";
const std::string SyncUpdate::LSA_COMPONENT = "LSA";
const std::string NLSR_COMPONENT = "NLSR";
const std::string LSA_COMPONENT = "LSA";
template<class T>
class NullDeleter
@@ -126,22 +43,20 @@ public:
}
};
SyncLogicHandler::SyncLogicHandler(ndn::Face& face,
Lsdb& lsdb, ConfParameter& conf,
SequencingManager& seqManager)
: m_validator(new ndn::ValidatorNull())
SyncLogicHandler::SyncLogicHandler(ndn::Face& face, const IsLsaNew& isLsaNew,
const ConfParameter& conf)
: onNewLsa(ndn::make_unique<OnNewLsa>())
, m_syncFace(face)
, m_lsdb(lsdb)
, m_isLsaNew(isLsaNew)
, m_confParam(conf)
, m_sequencingManager(seqManager)
{
}
void
SyncLogicHandler::createSyncSocket(const ndn::Name& syncPrefix)
SyncLogicHandler::createSyncSocket(const ndn::Name& syncPrefix, const ndn::time::milliseconds& syncInterestLifetime)
{
if (m_syncSocket != nullptr) {
_LOG_WARN("Trying to create Sync socket, but Sync socket already exists");
NLSR_LOG_WARN("Trying to create Sync socket, but Sync socket already exists");
return;
}
@@ -150,156 +65,143 @@ SyncLogicHandler::createSyncSocket(const ndn::Name& syncPrefix)
// Build LSA sync update prefix
buildUpdatePrefix();
_LOG_DEBUG("Creating Sync socket. Sync Prefix: " << m_syncPrefix);
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
ndn::shared_ptr<ndn::Face> facePtr(&m_syncFace, NullDeleter<ndn::Face>());
std::shared_ptr<ndn::Face> facePtr(&m_syncFace, NullDeleter<ndn::Face>());
m_syncSocket = ndn::make_shared<Sync::SyncSocket>(m_syncPrefix, m_validator, facePtr,
ndn::bind(&SyncLogicHandler::onNsyncUpdate,
this, _1, _2),
ndn::bind(&SyncLogicHandler::onNsyncRemoval,
this, _1));
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::onNsyncUpdate(const vector<Sync::MissingDataInfo>& v, Sync::SyncSocket* socket)
SyncLogicHandler::onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& v)
{
_LOG_DEBUG("Received Nsync update event");
NLSR_LOG_DEBUG("Received ChronoSync update event");
for (size_t i = 0; i < v.size(); i++){
_LOG_DEBUG("Update Name: " << v[i].prefix << " Seq no: " << v[i].high.getSeq());
ndn::Name updateName = v[i].session.getPrefix(-1);
SyncUpdate update(v[i].prefix, v[i].high.getSeq());
NLSR_LOG_DEBUG("Update Name: " << updateName << " Seq no: " << v[i].high);
processUpdateFromSync(update);
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);
}
}
void
SyncLogicHandler::onNsyncRemoval(const string& prefix)
SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
const ndn::Name& updateName, const uint64_t& seqNo)
{
_LOG_DEBUG("Received Nsync removal event");
}
void
SyncLogicHandler::processUpdateFromSync(const SyncUpdate& update)
{
ndn::Name originRouter;
try {
originRouter = update.getOriginRouter();
}
catch (std::exception& e) {
_LOG_WARN("Received malformed sync update");
return;
}
NLSR_LOG_DEBUG("Origin Router of update: " << originRouter);
// A router should not try to fetch its own LSA
if (originRouter != m_confParam.getRouterPrefix()) {
update.getSequencingManager().writeLog();
Lsa::Type lsaType;
std::istringstream(updateName.get(updateName.size()-1).toUri()) >> lsaType;
if (isLsaNew(originRouter, NameLsa::TYPE_STRING, update.getNameLsaSeqNo())) {
_LOG_DEBUG("Received sync update with higher Name LSA sequence number than entry in LSDB");
NLSR_LOG_DEBUG("Received sync update with higher " << lsaType
<< " sequence number than entry in LSDB");
expressInterestForLsa(update, NameLsa::TYPE_STRING, update.getNameLsaSeqNo());
if (m_isLsaNew(originRouter, lsaType, seqNo)) {
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.");
return;
}
if (isLsaNew(originRouter, AdjLsa::TYPE_STRING, update.getAdjLsaSeqNo())) {
_LOG_DEBUG("Received sync update with higher Adj LSA sequence number than entry in LSDB");
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
if (update.getAdjLsaSeqNo() != 0) {
_LOG_ERROR("Tried to fetch an adjacency LSA when hyperbolic routing"
<< " is enabled.");
}
}
else {
expressInterestForLsa(update, AdjLsa::TYPE_STRING, update.getAdjLsaSeqNo());
}
}
if (isLsaNew(originRouter, CoordinateLsa::TYPE_STRING, update.getCorLsaSeqNo())) {
_LOG_DEBUG("Received sync update with higher Cor LSA sequence number than entry in LSDB");
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
if (update.getCorLsaSeqNo() != 0) {
_LOG_ERROR("Tried to fetch a coordinate LSA when link-state"
<< " is enabled.");
}
}
else {
expressInterestForLsa(update, CoordinateLsa::TYPE_STRING, update.getCorLsaSeqNo());
}
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.");
return;
}
(*onNewLsa)(updateName, seqNo);
}
}
}
bool
SyncLogicHandler::isLsaNew(const ndn::Name& originRouter, const std::string& lsaType,
uint64_t seqNo)
{
ndn::Name lsaKey = originRouter;
lsaKey.append(lsaType);
if (lsaType == NameLsa::TYPE_STRING)
{
return m_lsdb.isNameLsaNew(lsaKey, seqNo);
}
else if (lsaType == AdjLsa::TYPE_STRING)
{
return m_lsdb.isAdjLsaNew(lsaKey, seqNo);
}
else if (lsaType == CoordinateLsa::TYPE_STRING)
{
return m_lsdb.isCoordinateLsaNew(lsaKey, seqNo);
}
return false;
}
void
SyncLogicHandler::expressInterestForLsa(const SyncUpdate& update, std::string lsaType,
uint64_t seqNo)
{
ndn::Name interest(update.getName());
interest.append(lsaType);
interest.appendNumber(seqNo);
m_lsdb.expressInterest(interest, 0);
}
void
SyncLogicHandler::publishRoutingUpdate()
SyncLogicHandler::publishRoutingUpdate(const Lsa::Type& type, const uint64_t& seqNo)
{
if (m_syncSocket == nullptr) {
_LOG_FATAL("Cannot publish routing update; SyncSocket does not exist");
NLSR_LOG_FATAL("Cannot publish routing update; SyncSocket does not exist");
throw SyncLogicHandler::Error("Cannot publish routing update; SyncSocket does not exist");
BOOST_THROW_EXCEPTION(SyncLogicHandler::Error("Cannot publish routing update; SyncSocket does not exist"));
}
m_sequencingManager.writeSeqNoToFile();
publishSyncUpdate(m_updatePrefix, m_sequencingManager.getCombinedSeqNo());
switch (type) {
case Lsa::Type::ADJACENCY:
publishSyncUpdate(m_adjLsaUserPrefix, seqNo);
break;
case Lsa::Type::COORDINATE:
publishSyncUpdate(m_coorLsaUserPrefix, seqNo);
break;
case Lsa::Type::NAME:
publishSyncUpdate(m_nameLsaUserPrefix, seqNo);
break;
default:
break;
}
}
void
SyncLogicHandler::buildUpdatePrefix()
{
m_updatePrefix = m_confParam.getLsaPrefix();
m_updatePrefix.append(m_confParam.getSiteName());
m_updatePrefix.append(m_confParam.getRouterName());
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)
{
_LOG_DEBUG("Publishing Sync Update. Prefix: " << updatePrefix << " Seq No: " << seqNo);
NLSR_LOG_DEBUG("Publishing Sync Update. Prefix: " << updatePrefix << " Seq No: " << seqNo);
ndn::Name updateName(updatePrefix);
string data("NoData");
std::string data("NoData");
m_syncSocket->publishData(updateName.toUri(), 0, data.c_str(), data.size(), 1000, seqNo);
m_syncSocket->publishData(reinterpret_cast<const uint8_t*>(data.c_str()), data.size(),
ndn::time::milliseconds(1000), seqNo, updateName);
}
}//namespace nlsr
} // namespace nlsr
+82 -38
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2016, The University of Memphis,
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -22,28 +22,36 @@
#ifndef NLSR_SYNC_LOGIC_HANDLER_HPP
#define NLSR_SYNC_LOGIC_HANDLER_HPP
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/validator-null.hpp>
#include <nsync/sync-socket.h>
#include <iostream>
#include <unistd.h>
#include <boost/cstdint.hpp>
#include "conf-parameter.hpp"
#include "test-access-control.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;
namespace nlsr {
class ConfParameter;
class Lsdb;
class SequencingManager;
class SyncUpdate;
/*! \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:
@@ -54,49 +62,85 @@ public:
}
};
SyncLogicHandler(ndn::Face& face, Lsdb& lsdb, ConfParameter& conf, SequencingManager& seqManager);
SyncLogicHandler(ndn::Face& face, const IsLsaNew& isLsaNew, const ConfParameter& conf);
/*! \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
onNsyncUpdate(const std::vector<Sync::MissingDataInfo>& v, Sync::SyncSocket* socket);
onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& v);
/*! \brief Instruct ChronoSync to publish an update.
*
* This function instructs sync to push an update into the network,
* based on whatever the state of the sequencing manager is when
* this is called. Since each ChronoSync instance maintains its own
* PIT, doing this satisfies those interests so that other routers
* know a sync update is available.
* \sa publishSyncUpdate
*/
void
onNsyncRemoval(const std::string& prefix);
publishRoutingUpdate(const Lsa::Type& type, const uint64_t& seqNo);
/*! \brief Create and configure a socket to enable ChronoSync for this NLSR.
*
* 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
*/
void
publishRoutingUpdate();
createSyncSocket(const ndn::Name& syncPrefix,
const ndn::time::milliseconds& syncInterestLifetime =
ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT));
void
createSyncSocket(const ndn::Name& syncPrefix);
private:
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,
* and then inspects the update to determine which kind of LSA the
* update is for. Finally, it expresses interest for the correct LSA
* type.
* \throws SyncUpdate::Error If the sync update doesn't look like a sync LSA update.
*/
void
processUpdateFromSync(const SyncUpdate& updateName);
bool
isLsaNew(const ndn::Name& originRouter, const std::string& lsaType, uint64_t seqNo);
void
expressInterestForLsa(const SyncUpdate& updateName, std::string lsaType, uint64_t seqNo);
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);
private:
ndn::shared_ptr<ndn::ValidatorNull> m_validator;
ndn::Face& m_syncFace;
ndn::shared_ptr<Sync::SyncSocket> m_syncSocket;
ndn::Name m_syncPrefix;
public:
std::unique_ptr<OnNewLsa> onNewLsa;
private:
Lsdb& m_lsdb;
ConfParameter& m_confParam;
const SequencingManager& m_sequencingManager;
ndn::Face& m_syncFace;
std::shared_ptr<chronosync::Socket> m_syncSocket;
ndn::Name m_syncPrefix;
IsLsaNew m_isLsaNew;
const ConfParameter& m_confParam;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
ndn::Name m_updatePrefix;
ndn::Name m_nameLsaUserPrefix;
ndn::Name m_adjLsaUserPrefix;
ndn::Name m_coorLsaUserPrefix;
private:
static const std::string NLSR_COMPONENT;
@@ -104,6 +148,6 @@ private:
};
} //namespace nlsr
} // namespace nlsr
#endif //NLSR_SYNC_LOGIC_HANDLER_HPP
#endif // NLSR_SYNC_LOGIC_HANDLER_HPP
+91 -116
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2016, The University of Memphis,
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -19,33 +19,27 @@
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include <iostream>
#include <fstream>
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/util/face-uri.hpp>
// boost needs to be included after ndn-cxx, otherwise there will be conflict with _1, _2, ...
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/filesystem.hpp>
#include "conf-parameter.hpp"
#include "conf-file-processor.hpp"
#include "conf-parameter.hpp"
#include "adjacent.hpp"
#include "utility/name-helper.hpp"
#include "update/prefix-update-processor.hpp"
namespace nlsr {
#include <boost/cstdint.hpp>
using namespace std;
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/net/face-uri.hpp>
#include <iostream>
#include <fstream>
namespace nlsr {
template <class T>
class ConfigurationVariable
{
public:
typedef ndn::function<void(T)> ConfParameterCallback;
typedef std::function<void(T)> ConfParameterCallback;
typedef boost::property_tree::ptree ConfigSection;
ConfigurationVariable(const std::string& key, const ConfParameterCallback& setter)
@@ -144,12 +138,12 @@ bool
ConfFileProcessor::processConfFile()
{
bool ret = true;
ifstream inputFile;
std::ifstream inputFile;
inputFile.open(m_confFileName.c_str());
if (!inputFile.is_open()) {
string msg = "Failed to read configuration file: ";
std::string msg = "Failed to read configuration file: ";
msg += m_confFileName;
cerr << msg << endl;
std::cerr << msg << std::endl;
return false;
}
ret = load(inputFile);
@@ -158,7 +152,7 @@ ConfFileProcessor::processConfFile()
}
bool
ConfFileProcessor::load(istream& input)
ConfFileProcessor::load(std::istream& input)
{
ConfigSection pt;
bool ret = true;
@@ -166,7 +160,7 @@ ConfFileProcessor::load(istream& input)
boost::property_tree::read_info(input, pt);
}
catch (const boost::property_tree::info_parser_error& error) {
stringstream msg;
std::stringstream msg;
std::cerr << "Failed to parse configuration file " << std::endl;
std::cerr << m_confFileName << std::endl;
return false;
@@ -221,15 +215,15 @@ bool
ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
{
try {
std::string network = section.get<string>("network");
std::string site = section.get<string>("site");
std::string router = section.get<string>("router");
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);
}
else {
cerr << " Network can not be null or empty or in bad URI format :(!" << endl;
std::cerr << " Network can not be null or empty or in bad URI format :(!" << std::endl;
return false;
}
ndn::Name siteName(site);
@@ -237,7 +231,7 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
m_nlsr.getConfParameter().setSiteName(siteName);
}
else {
cerr << "Site can not be null or empty or in bad URI format:( !" << endl;
std::cerr << "Site can not be null or empty or in bad URI format:( !" << std::endl;
return false;
}
ndn::Name routerName(router);
@@ -245,12 +239,12 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
m_nlsr.getConfParameter().setRouterName(routerName);
}
else {
cerr << " Router name can not be null or empty or in bad URI format:( !" << endl;
std::cerr << " Router name can not be null or empty or in bad URI format:( !" << std::endl;
return false;
}
}
catch (const std::exception& ex) {
cerr << ex.what() << endl;
std::cerr << ex.what() << std::endl;
return false;
}
@@ -293,58 +287,25 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
return false;
}
// log-level
std::string logLevel = section.get<string>("log-level", "INFO");
if (isValidLogLevel(logLevel)) {
m_nlsr.getConfParameter().setLogLevel(logLevel);
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);
}
else {
std::cerr << "Invalid value for log-level ";
std::cerr << "Valid values: ALL, TRACE, DEBUG, INFO, WARN, ERROR, NONE" << std::endl;
std::cerr << "Wrong value for sync-interest-lifetime. "
<< "Allowed value:" << SYNC_INTEREST_LIFETIME_MIN << "-"
<< SYNC_INTEREST_LIFETIME_MAX << std::endl;
return false;
}
try {
std::string logDir = section.get<string>("log-dir");
if (boost::filesystem::exists(logDir)) {
if (boost::filesystem::is_directory(logDir)) {
std::string testFileName=logDir+"/test.log";
ofstream testOutFile;
testOutFile.open(testFileName.c_str());
if (testOutFile.is_open() && testOutFile.good()) {
m_nlsr.getConfParameter().setLogDir(logDir);
}
else {
std::cerr << "User does not have read and write permission on the directory";
std::cerr << std::endl;
return false;
}
testOutFile.close();
remove(testFileName.c_str());
}
else {
std::cerr << "Provided path is not a directory" << std::endl;
return false;
}
}
else {
std::cerr << "Provided log directory <" << logDir << "> does not exist" << std::endl;
return false;
}
}
catch (const std::exception& ex) {
std::cerr << "You must configure log directory" << std::endl;
std::cerr << ex.what() << std::endl;
return false;
}
try {
std::string seqDir = section.get<string>("seq-dir");
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";
ofstream testOutFile;
std::ofstream testOutFile;
testOutFile.open(testFileName.c_str());
if (testOutFile.is_open() && testOutFile.good()) {
m_nlsr.getConfParameter().setSeqFileDir(seqDir);
@@ -373,28 +334,6 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
return false;
}
try {
std::string log4cxxPath = section.get<string>("log4cxx-conf");
if (log4cxxPath == "") {
std::cerr << "No value provided for log4cxx-conf" << std::endl;
return false;
}
if (boost::filesystem::exists(log4cxxPath)) {
m_nlsr.getConfParameter().setLog4CxxConfPath(log4cxxPath);
}
else {
std::cerr << "Provided path for log4cxx-conf <" << log4cxxPath
<< "> does not exist" << std::endl;
return false;
}
}
catch (const std::exception& ex) {
// Variable is optional so default configuration will be used; continue processing file
}
return true;
}
@@ -446,7 +385,7 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
// Event intervals
// adj-lsa-build-interval
ConfigurationVariable<uint32_t> adjLsaBuildInterval("adj-lsa-build-interval",
bind(&ConfParameter::setAdjLsaBuildInterval,
std::bind(&ConfParameter::setAdjLsaBuildInterval,
&m_nlsr.getConfParameter(), _1));
adjLsaBuildInterval.setMinAndMaxValue(ADJ_LSA_BUILD_INTERVAL_MIN, ADJ_LSA_BUILD_INTERVAL_MAX);
adjLsaBuildInterval.setOptional(ADJ_LSA_BUILD_INTERVAL_DEFAULT);
@@ -454,10 +393,37 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
if (!adjLsaBuildInterval.parseFromConfigSection(section)) {
return false;
}
// 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));
faceDatasetFetchTries.setMinAndMaxValue(FACE_DATASET_FETCH_TRIES_MIN,
FACE_DATASET_FETCH_TRIES_MAX);
faceDatasetFetchTries.setOptional(FACE_DATASET_FETCH_TRIES_DEFAULT);
if (!faceDatasetFetchTries.parseFromConfigSection(section)) {
return false;
}
// Set the interval between FaceStatus dataset fetch attempts.
ConfigurationVariable<uint32_t> faceDatasetFetchInterval("face-dataset-fetch-interval",
bind(&ConfParameter::setFaceDatasetFetchInterval,
&m_nlsr.getConfParameter(),
_1));
faceDatasetFetchInterval.setMinAndMaxValue(FACE_DATASET_FETCH_INTERVAL_MIN,
FACE_DATASET_FETCH_INTERVAL_MAX);
faceDatasetFetchInterval.setOptional(FACE_DATASET_FETCH_INTERVAL_DEFAULT);
if (!faceDatasetFetchInterval.parseFromConfigSection(section)) {
return false;
}
// first-hello-interval
ConfigurationVariable<uint32_t> firstHelloInterval("first-hello-interval",
bind(&ConfParameter::setFirstHelloInterval,
std::bind(&ConfParameter::setFirstHelloInterval,
&m_nlsr.getConfParameter(), _1));
firstHelloInterval.setMinAndMaxValue(FIRST_HELLO_INTERVAL_MIN, FIRST_HELLO_INTERVAL_MAX);
firstHelloInterval.setOptional(FIRST_HELLO_INTERVAL_DEFAULT);
@@ -469,17 +435,15 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
for (ConfigSection::const_iterator tn =
section.begin(); tn != section.end(); ++tn) {
if (tn->first == "neighbor")
{
if (tn->first == "neighbor") {
try {
ConfigSection CommandAttriTree = tn->second;
std::string name = CommandAttriTree.get<std::string>("name");
std::string faceUri = CommandAttriTree.get<std::string>("face-uri");
std::string uriString = CommandAttriTree.get<std::string>("face-uri");
ndn::util::FaceUri uri;
if (!uri.parse(faceUri)) {
std::cerr << "Malformed face-uri <" << faceUri << "> for " << name << std::endl;
ndn::FaceUri faceUri;
if (! faceUri.parse(uriString)) {
std::cerr << "parsing failed!" << std::endl;
return false;
}
@@ -508,7 +472,7 @@ bool
ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
{
// state
std::string state = section.get<string>("state", "off");
std::string state = section.get<std::string>("state", "off");
if (boost::iequals(state, "off")) {
m_nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_OFF);
@@ -527,17 +491,29 @@ ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
}
try {
/* Radius and angle is mandatory configuration parameter in hyperbolic section.
* Even if router can have hyperbolic routing calculation off but other router
* in the network may use hyperbolic routing calculation for FIB generation.
* So each router need to advertise its hyperbolic coordinates in the network
*/
// Radius and angle(s) are mandatory configuration parameters in hyperbolic section.
// Even if router can have hyperbolic routing calculation off but other router
// in the network may use hyperbolic routing calculation for FIB generation.
// So each router need to advertise its hyperbolic coordinates in the network
double radius = section.get<double>("radius");
double angle = section.get<double>("angle");
std::string angleString = section.get<std::string>("angle");
std::stringstream ss(angleString);
std::vector<double> angles;
double angle;
while (ss >> angle) {
angles.push_back(angle);
if (ss.peek() == ',' || ss.peek() == ' ') {
ss.ignore();
}
}
if (!m_nlsr.getConfParameter().setCorR(radius)) {
return false;
}
m_nlsr.getConfParameter().setCorTheta(angle);
m_nlsr.getConfParameter().setCorTheta(angles);
}
catch (const std::exception& ex) {
std::cerr << ex.what() << std::endl;
@@ -569,7 +545,7 @@ ConfFileProcessor::processConfSectionFib(const ConfigSection& section)
// routing-calc-interval
ConfigurationVariable<uint32_t> routingCalcInterval("routing-calc-interval",
bind(&ConfParameter::setRoutingCalcInterval,
std::bind(&ConfParameter::setRoutingCalcInterval,
&m_nlsr.getConfParameter(), _1));
routingCalcInterval.setMinAndMaxValue(ROUTING_CALC_INTERVAL_MIN, ROUTING_CALC_INTERVAL_MAX);
routingCalcInterval.setOptional(ROUTING_CALC_INTERVAL_DEFAULT);
@@ -621,7 +597,6 @@ ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
it++;
if (it != section.end() && it->first == "prefix-update-validator") {
m_nlsr.getPrefixUpdateProcessor().enable();
m_nlsr.getPrefixUpdateProcessor().loadValidator(it->second, m_confFileName);
it++;
@@ -635,15 +610,15 @@ ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
std::string file = it->second.data();
path certfilePath = absolute(file, path(m_confFileName).parent_path());
shared_ptr<ndn::IdentityCertificate> idCert =
ndn::io::load<ndn::IdentityCertificate>(certfilePath.string());
std::shared_ptr<ndn::security::v2::Certificate> idCert =
ndn::io::load<ndn::security::v2::Certificate>(certfilePath.string());
if (idCert == nullptr) {
std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
return false;
}
m_nlsr.loadCertToPublish(idCert);
m_nlsr.loadCertToPublish(*idCert);
}
}
+66 -13
View File
@@ -1,7 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 University of Memphis,
* Regents of the University of California
* 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.
@@ -16,22 +16,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/>.
*
* \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
* \author Minsheng Zhang <mzhang4@memphis.edu>
*
**/
#ifndef CONF_PROCESSOR_HPP
#define CONF_PROCESSOR_HPP
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/cstdint.hpp>
#ifndef NLSR_CONF_FILE_PROCESSOR_HPP
#define NLSR_CONF_FILE_PROCESSOR_HPP
#include "common.hpp"
#include "nlsr.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <boost/filesystem.hpp>
namespace nlsr {
/*! \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:
@@ -41,40 +52,82 @@ public:
{
}
/*! \brief Load and parse the configuration file, then populate NLSR.
*
* Entry-point function that chains all the necessary steps together
* to configure an NLSR object.
*
* \return A boolean for whether configuration was successful.
*/
bool
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
* over them, attempting to parse each node. The nodes themselves
* are passed to another function that determines what kind of
* section it is and handles it appropriately. On any error in
* reading the file, return false.
*
* \return Whether configuration was successful.
*/
bool
load(std::istream& input);
/*! \brief A dispatcher-like function to send configuration tree nodes to the right subfunction.
*/
bool
processSection(const std::string& sectionName, const ConfigSection& section);
/*! \brief Parse general options, including router name, LSA refresh.
*/
bool
processConfSectionGeneral(const ConfigSection& section);
/*! \brief Configure options relating to neighbor configuration and detection.
*
* Parse options that control NLSR's behavior about neighbors. Such
* things include how many hello interests are sent and what their
* timeout is, as well as parsing neighbor specifications. Neighbor
* Face URIs are parsed and confirmed as valid here by ndn-cxx.
*/
bool
processConfSectionNeighbors(const ConfigSection& section);
/*! \brief Set the state of hyperbolic routing: off, on, dry-run.
*/
bool
processConfSectionHyperbolic(const ConfigSection& section);
/*! \brief Set options for the FIB: nexthops per prefix, routing calculation interval.
*/
bool
processConfSectionFib(const ConfigSection& section);
/*! \brief Set prefixes that NLSR is supposed to advertise immediately.
*/
bool
processConfSectionAdvertising(const ConfigSection& section);
/*! \brief Parse and set rules for the validator.
*
* This section parses and sets rules for the validators, which
* control what criteria Interest and Data need to follow to be
* considered valid by this NLSR.
*/
bool
processConfSectionSecurity(const ConfigSection& section);
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;
};
} //namespace nlsr
#endif //CONF_PROCESSOR_HPP
} // namespace nlsr
#endif // NLSR_CONF_FILE_PROCESSOR_HPP
+47 -24
View File
@@ -1,7 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 University of Memphis,
* Regents of the University of California
* 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.
@@ -26,34 +26,57 @@
namespace nlsr {
INIT_LOGGER("ConfParameter");
INIT_LOGGER(ConfParameter);
// To be changed when breaking changes are made to sync
const uint64_t ConfParameter::SYNC_VERSION = 4;
void
ConfParameter::writeLog()
{
_LOG_DEBUG("Router Name: " << m_routerName);
_LOG_DEBUG("Site Name: " << m_siteName);
_LOG_DEBUG("Network: " << m_network);
_LOG_DEBUG("Router Prefix: " << m_routerPrefix);
_LOG_DEBUG("ChronoSync sync Prefix: " << m_chronosyncPrefix);
_LOG_DEBUG("ChronoSync LSA prefix: " << m_lsaPrefix);
_LOG_DEBUG("Hello Interest retry number: " << m_interestRetryNumber);
_LOG_DEBUG("Hello Interest resend second: " << m_interestResendTime);
_LOG_DEBUG("Info Interest interval: " << m_infoInterestInterval);
_LOG_DEBUG("LSA refresh time: " << m_lsaRefreshTime);
_LOG_DEBUG("LSA Interest lifetime: " << getLsaInterestLifetime());
_LOG_DEBUG("Router dead interval: " << getRouterDeadInterval());
_LOG_DEBUG("Max Faces Per Prefix: " << m_maxFacesPerPrefix);
_LOG_DEBUG("Hyperbolic Routing: " << m_hyperbolicState);
_LOG_DEBUG("Hyp R: " << m_corR);
_LOG_DEBUG("Hyp theta: " << m_corTheta);
_LOG_DEBUG("Log Directory: " << m_logDir);
_LOG_DEBUG("Seq Directory: " << m_seqFileDir);
NLSR_LOG_INFO("Router Name: " << m_routerName);
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("Hello Interest retry number: " << m_interestRetryNumber);
NLSR_LOG_INFO("Hello Interest resend second: " << m_interestResendTime);
NLSR_LOG_INFO("Info Interest interval: " << m_infoInterestInterval);
NLSR_LOG_INFO("LSA refresh time: " << m_lsaRefreshTime);
NLSR_LOG_INFO("FIB Entry refresh time: " << m_lsaRefreshTime * 2);
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);
}
NLSR_LOG_INFO("Seq Directory: " << m_seqFileDir);
// Event Intervals
_LOG_DEBUG("Adjacency LSA build interval: " << m_adjLsaBuildInterval);
_LOG_DEBUG("First Hello Interest interval: " << m_firstHelloInterval);
_LOG_DEBUG("Routing calculation interval: " << m_routingCalcInterval);
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);
}
void
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);
m_lsaPrefix.append("localhop");
m_lsaPrefix.append(m_network);
m_lsaPrefix.append("NLSR");
m_lsaPrefix.append("LSA");
}
} // namespace nlsr
+72 -55
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2016, The University of Memphis,
* Copyright (c) 2014-2018, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -19,17 +19,18 @@
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef CONF_PARAMETER_HPP
#define CONF_PARAMETER_HPP
#ifndef NLSR_CONF_PARAMETER_HPP
#define NLSR_CONF_PARAMETER_HPP
#include "common.hpp"
#include "logger.hpp"
#include "test-access-control.hpp"
#include <iostream>
#include <boost/cstdint.hpp>
#include <ndn-cxx/common.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/util/time.hpp>
#include "logger.hpp"
namespace nlsr {
enum {
@@ -62,6 +63,19 @@ enum {
ROUTING_CALC_INTERVAL_MAX = 15
};
enum {
FACE_DATASET_FETCH_TRIES_MIN = 1,
FACE_DATASET_FETCH_TRIES_MAX = 10,
FACE_DATASET_FETCH_TRIES_DEFAULT = 3
};
enum {
FACE_DATASET_FETCH_INTERVAL_MIN = 1800,
FACE_DATASET_FETCH_INTERVAL_MAX = 5400,
FACE_DATASET_FETCH_INTERVAL_DEFAULT = 3600
};
enum {
HELLO_RETRIES_MIN = 1,
HELLO_RETRIES_DEFAULT = 3,
@@ -93,6 +107,23 @@ enum HyperbolicState {
HYPERBOLIC_STATE_DEFAULT = 0
};
enum {
SYNC_INTEREST_LIFETIME_MIN = 1000,
SYNC_INTEREST_LIFETIME_DEFAULT = 60000,
SYNC_INTEREST_LIFETIME_MAX = 120000,
};
/*! \brief A class to house all the configuration parameters for NLSR.
*
* This class is conceptually a singleton (but not mechanically) which
* is just a collection of attributes that serve as a
* separation-of-data for NLSR's configuration variables. NLSR refers
* to an instance of this class for all its configuration
* parameters. This object is typically populated by a
* ConfFileProcessor reading a configuration file.
*
* \sa nlsr::ConfFileProcessor
*/
class ConfParameter
{
@@ -102,6 +133,7 @@ public:
, 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")
@@ -110,24 +142,13 @@ public:
, m_infoInterestInterval(HELLO_INTERVAL_DEFAULT)
, m_hyperbolicState(HYPERBOLIC_STATE_OFF)
, m_corR(0)
, m_corTheta(0)
, m_maxFacesPerPrefix(MAX_FACES_PER_PREFIX_MIN)
, m_isLog4cxxConfAvailable(false)
, m_syncInterestLifetime(ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT))
{
}
void
setNetwork(const ndn::Name& networkName)
{
m_network = networkName;
m_chronosyncPrefix = m_network;
m_chronosyncPrefix.append("NLSR");
m_chronosyncPrefix.append("sync");
m_lsaPrefix = m_network;
m_lsaPrefix.append("NLSR");
m_lsaPrefix.append("LSA");
}
setNetwork(const ndn::Name& networkName);
const ndn::Name&
getNetwork() const
@@ -259,15 +280,27 @@ public:
}
void
setLogLevel(const std::string& logLevel)
setFaceDatasetFetchTries(uint32_t count)
{
m_logLevel = logLevel;
m_faceDatasetFetchTries = count;
}
const std::string&
getLogLevel() const
uint32_t
getFaceDatasetFetchTries() const
{
return m_logLevel;
return m_faceDatasetFetchTries;
}
void
setFaceDatasetFetchInterval(uint32_t interval)
{
m_faceDatasetFetchInterval = ndn::time::seconds(interval);
}
const ndn::time::seconds
getFaceDatasetFetchInterval() const
{
return m_faceDatasetFetchInterval;
}
void
@@ -335,12 +368,12 @@ public:
}
void
setCorTheta(double ct)
setCorTheta(const std::vector<double>& ct)
{
m_corTheta = ct;
}
double
std::vector<double>
getCorTheta() const
{
return m_corTheta;
@@ -358,18 +391,6 @@ public:
return m_maxFacesPerPrefix;
}
void
setLogDir(const std::string& logDir)
{
m_logDir = logDir;
}
const std::string&
getLogDir() const
{
return m_logDir;
}
void
setSeqFileDir(const std::string& ssfd)
{
@@ -382,23 +403,16 @@ public:
return m_seqFileDir;
}
bool
isLog4CxxConfAvailable() const
{
return m_isLog4cxxConfAvailable;
}
void
setLog4CxxConfPath(const std::string& path)
setSyncInterestLifetime(uint32_t syncInterestLifetime)
{
m_log4CxxConfPath = path;
m_isLog4cxxConfAvailable = true;
m_syncInterestLifetime = ndn::time::milliseconds(syncInterestLifetime);
}
const std::string&
getLog4CxxConfPath() const
const ndn::time::milliseconds&
getSyncInterestLifetime() const
{
return m_log4CxxConfPath;
return m_syncInterestLifetime;
}
void
@@ -421,6 +435,9 @@ private:
uint32_t m_firstHelloInterval;
uint32_t m_routingCalcInterval;
uint32_t m_faceDatasetFetchTries;
ndn::time::seconds m_faceDatasetFetchInterval;
ndn::time::seconds m_lsaInterestLifetime;
uint32_t m_routerDeadInterval;
std::string m_logLevel;
@@ -432,17 +449,17 @@ private:
int32_t m_hyperbolicState;
double m_corR;
double m_corTheta;
std::vector<double> m_corTheta;
uint32_t m_maxFacesPerPrefix;
std::string m_logDir;
std::string m_seqFileDir;
ndn::time::milliseconds m_syncInterestLifetime;
bool m_isLog4cxxConfAvailable;
std::string m_log4CxxConfPath;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
static const uint64_t SYNC_VERSION;
};
} // namespace nlsr
#endif //CONF_PARAMETER_HPP
#endif // NLSR_CONF_PARAMETER_HPP
+87 -126
View File
@@ -1,7 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014 University of Memphis,
* Regents of the University of California
* 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.
@@ -16,36 +16,46 @@
*
* 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 "hello-protocol.hpp"
#include "hello-protocol.hpp"
#include "nlsr.hpp"
#include "lsdb.hpp"
#include "hello-protocol.hpp"
#include "utility/name-helper.hpp"
#include "logger.hpp"
namespace nlsr {
INIT_LOGGER("HelloProtocol");
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)
{
}
void
HelloProtocol::expressInterest(const ndn::Name& interestName, uint32_t seconds)
{
_LOG_DEBUG("Expressing Interest :" << interestName);
NLSR_LOG_DEBUG("Expressing Interest :" << interestName);
ndn::Interest i(interestName);
i.setInterestLifetime(ndn::time::seconds(seconds));
i.setMustBeFresh(true);
m_nlsr.getNlsrFace().expressInterest(i,
ndn::bind(&HelloProtocol::onContent,
std::bind(&HelloProtocol::onContent,
this,
_1, _2),
ndn::bind(&HelloProtocol::processInterestTimedOut,
std::bind(&HelloProtocol::processInterestTimedOut, // Nack
this, _1),
std::bind(&HelloProtocol::processInterestTimedOut,
this, _1));
// increment SENT_HELLO_INTEREST
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_INTEREST);
}
void
@@ -54,18 +64,16 @@ HelloProtocol::sendScheduledInterest(uint32_t seconds)
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> */
// 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());
}
else {
registerPrefixes((*it).getName(), (*it).getConnectingFaceUri(),
(*it).getLinkCost(), ndn::time::milliseconds::max());
NLSR_LOG_DEBUG("Sending scheduled interest: " << interestName);
}
}
scheduleInterest(m_nlsr.getConfParameter().getInfoInterestInterval());
@@ -74,38 +82,53 @@ HelloProtocol::sendScheduledInterest(uint32_t seconds)
void
HelloProtocol::scheduleInterest(uint32_t seconds)
{
_LOG_DEBUG("Scheduling HELLO Interests in " << ndn::time::seconds(seconds));
NLSR_LOG_DEBUG("Scheduling HELLO Interests in " << ndn::time::seconds(seconds));
m_scheduler.scheduleEvent(ndn::time::seconds(seconds),
ndn::bind(&HelloProtocol::sendScheduledInterest, this, seconds));
std::bind(&HelloProtocol::sendScheduledInterest, this, seconds));
}
void
HelloProtocol::processInterest(const ndn::Name& name,
const ndn::Interest& interest)
{
/* interest name: /<neighbor>/NLSR/INFO/<router> */
// interest name: /<neighbor>/NLSR/INFO/<router>
const ndn::Name interestName = interest.getName();
_LOG_DEBUG("Interest Received for Name: " << interestName);
// increment RCV_HELLO_INTEREST
hpIncrementSignal(Statistics::PacketType::RCV_HELLO_INTEREST);
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");
return;
}
ndn::Name neighbor;
neighbor.wireDecode(interestName.get(-1).blockFromValue());
_LOG_DEBUG("Neighbor: " << neighbor);
NLSR_LOG_DEBUG("Neighbor: " << neighbor);
if (m_nlsr.getAdjacencyList().isNeighbor(neighbor)) {
ndn::shared_ptr<ndn::Data> data = ndn::make_shared<ndn::Data>();
std::shared_ptr<ndn::Data> 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());
m_nlsr.getKeyChain().sign(*data, m_nlsr.getDefaultCertName());
_LOG_DEBUG("Sending out data for name: " << interest.getName());
m_nlsr.getKeyChain().sign(*data, m_nlsr.getSigningInfo());
NLSR_LOG_DEBUG("Sending out data for name: " << interest.getName());
m_nlsr.getNlsrFace().put(*data);
Adjacent *adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
// increment SENT_HELLO_DATA
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_DATA);
auto adjacent = m_nlsr.getAdjacencyList().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.
if(adjacent->getFaceId() != 0){
/* interest name: /<neighbor>/NLSR/INFO/<router> */
// interest name: /<neighbor>/NLSR/INFO/<router>
ndn::Name interestName(neighbor);
interestName.append(NLSR_COMPONENT);
interestName.append(INFO_COMPONENT);
@@ -113,10 +136,6 @@ HelloProtocol::processInterest(const ndn::Name& name,
expressInterest(interestName,
m_nlsr.getConfParameter().getInterestResendTime());
}
else {
registerPrefixes(adjacent->getName(), adjacent->getConnectingFaceUri(),
adjacent->getLinkCost(), ndn::time::milliseconds::max());
}
}
}
}
@@ -124,28 +143,29 @@ HelloProtocol::processInterest(const ndn::Name& name,
void
HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
{
/* interest name: /<neighbor>/NLSR/INFO/<router> */
// interest name: /<neighbor>/NLSR/INFO/<router>
const ndn::Name interestName(interest.getName());
_LOG_DEBUG("Interest timed out for Name: " << interestName);
NLSR_LOG_DEBUG("Interest timed out for Name: " << interestName);
if (interestName.get(-2).toUri() != INFO_COMPONENT) {
return;
}
ndn::Name neighbor = interestName.getPrefix(-3);
_LOG_DEBUG("Neighbor: " << neighbor);
NLSR_LOG_DEBUG("Neighbor: " << neighbor);
m_nlsr.getAdjacencyList().incrementTimedOutInterestCount(neighbor);
Adjacent::Status status = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
uint32_t infoIntTimedOutCount =
m_nlsr.getAdjacencyList().getTimedOutInterestCount(neighbor);
_LOG_DEBUG("Status: " << status);
_LOG_DEBUG("Info Interest Timed out: " << infoIntTimedOutCount);
if ((infoIntTimedOutCount < m_nlsr.getConfParameter().getInterestRetryNumber())) {
/* interest name: /<neighbor>/NLSR/INFO/<router> */
NLSR_LOG_DEBUG("Status: " << status);
NLSR_LOG_DEBUG("Info Interest Timed out: " << infoIntTimedOutCount);
if (infoIntTimedOutCount < m_nlsr.getConfParameter().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());
NLSR_LOG_DEBUG("Resending interest: " << interestName);
expressInterest(interestName,
m_nlsr.getConfParameter().getInterestResendTime());
}
@@ -153,31 +173,37 @@ HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
(infoIntTimedOutCount == m_nlsr.getConfParameter().getInterestRetryNumber())) {
m_nlsr.getAdjacencyList().setStatusOfNeighbor(neighbor, Adjacent::STATUS_INACTIVE);
NLSR_LOG_DEBUG("Neighbor: " << neighbor << " status changed to INACTIVE");
m_nlsr.getLsdb().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.
void
HelloProtocol::onContent(const ndn::Interest& interest, const ndn::Data& data)
{
_LOG_DEBUG("Received data for INFO(name): " << data.getName());
NLSR_LOG_DEBUG("Received data for INFO(name): " << data.getName());
if (data.getSignature().hasKeyLocator()) {
if (data.getSignature().getKeyLocator().getType() == ndn::KeyLocator::KeyLocator_Name) {
_LOG_DEBUG("Data signed with: " << data.getSignature().getKeyLocator().getName());
NLSR_LOG_DEBUG("Data signed with: " << data.getSignature().getKeyLocator().getName());
}
}
m_nlsr.getValidator().validate(data,
ndn::bind(&HelloProtocol::onContentValidated, this, _1),
ndn::bind(&HelloProtocol::onContentValidationFailed,
std::bind(&HelloProtocol::onContentValidated, this, _1),
std::bind(&HelloProtocol::onContentValidationFailed,
this, _1, _2));
}
void
HelloProtocol::onContentValidated(const ndn::shared_ptr<const ndn::Data>& data)
HelloProtocol::onContentValidated(const ndn::Data& data)
{
/* data name: /<neighbor>/NLSR/INFO/<router>/<version> */
ndn::Name dataName = data->getName();
_LOG_DEBUG("Data validation successful for INFO(name): " << dataName);
// data name: /<neighbor>/NLSR/INFO/<router>/<version>
ndn::Name dataName = data.getName();
NLSR_LOG_DEBUG("Data validation successful for INFO(name): " << dataName);
if (dataName.get(-3).toUri() == INFO_COMPONENT) {
ndn::Name neighbor = dataName.getPrefix(-4);
@@ -186,92 +212,27 @@ HelloProtocol::onContentValidated(const ndn::shared_ptr<const ndn::Data>& data)
m_nlsr.getAdjacencyList().setTimedOutInterestCount(neighbor, 0);
Adjacent::Status newStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
_LOG_DEBUG("Neighbor : " << neighbor);
_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) {
m_nlsr.getLsdb().scheduleAdjLsaBuild();
}
}
}
void
HelloProtocol::onContentValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
const std::string& msg)
{
_LOG_DEBUG("Validation Error: " << msg);
}
void
HelloProtocol::registerPrefixes(const ndn::Name& adjName, const std::string& faceUri,
double linkCost, const ndn::time::milliseconds& timeout)
{
m_nlsr.getFib().registerPrefix(adjName, faceUri, linkCost, timeout,
ndn::nfd::ROUTE_FLAG_CAPTURE, 0,
ndn::bind(&HelloProtocol::onRegistrationSuccess,
this, _1, adjName,timeout),
ndn::bind(&HelloProtocol::onRegistrationFailure,
this, _1, _2, adjName));
}
void
HelloProtocol::onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
const ndn::Name& neighbor,const ndn::time::milliseconds& timeout)
{
Adjacent *adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
if (adjacent != 0) {
adjacent->setFaceId(commandSuccessResult.getFaceId());
ndn::Name broadcastKeyPrefix = DEFAULT_BROADCAST_PREFIX;
broadcastKeyPrefix.append("KEYS");
std::string faceUri = adjacent->getConnectingFaceUri();
double linkCost = adjacent->getLinkCost();
m_nlsr.getFib().registerPrefix(m_nlsr.getConfParameter().getChronosyncPrefix(),
faceUri, linkCost, timeout,
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
m_nlsr.getFib().registerPrefix(m_nlsr.getConfParameter().getLsaPrefix(),
faceUri, linkCost, timeout,
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
m_nlsr.getFib().registerPrefix(broadcastKeyPrefix,
faceUri, linkCost, timeout,
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
m_nlsr.setStrategies();
/* 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());
expressInterest(interestName,
m_nlsr.getConfParameter().getInterestResendTime());
}
}
void
HelloProtocol::onRegistrationFailure(uint32_t code, const std::string& error,
const ndn::Name& name)
{
_LOG_DEBUG(error << " (code: " << code << ")");
/*
* If NLSR can not create face for given faceUri then it will treat this
* failure as one INFO interest timed out. So that NLSR can move on with
* building Adj Lsa and calculate routing table. NLSR does not build Adj
* Lsa unless all the neighbors are ACTIVE or DEAD. For considering the
* missconfigured(link) neighbour dead this is required.
*/
Adjacent *adjacent = m_nlsr.getAdjacencyList().findAdjacent(name);
if (adjacent != 0) {
adjacent->setInterestTimedOutNo(adjacent->getInterestTimedOutNo() + 1);
Adjacent::Status status = adjacent->getStatus();
uint32_t infoIntTimedOutCount = adjacent->getInterestTimedOutNo();
if (infoIntTimedOutCount == m_nlsr.getConfParameter().getInterestRetryNumber()) {
if (status == Adjacent::STATUS_ACTIVE) {
adjacent->setStatus(Adjacent::STATUS_INACTIVE);
if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
}
else {
m_nlsr.getLsdb().scheduleAdjLsaBuild();
}
m_nlsr.getLsdb().scheduleAdjLsaBuild();
}
}
// increment RCV_HELLO_DATA
hpIncrementSignal(Statistics::PacketType::RCV_HELLO_DATA);
}
} //namespace nlsr
void
HelloProtocol::onContentValidationFailed(const ndn::Data& data,
const ndn::security::v2::ValidationError& ve)
{
NLSR_LOG_DEBUG("Validation Error: " << ve);
}
} // namespace nlsr
+103 -12
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2016, The University of Memphis,
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -22,11 +22,15 @@
#ifndef NLSR_HELLO_PROTOCOL_HPP
#define NLSR_HELLO_PROTOCOL_HPP
#include "statistics.hpp"
#include "test-access-control.hpp"
#include <ndn-cxx/util/signal.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/management/nfd-control-parameters.hpp>
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <ndn-cxx/security/v2/validation-error.hpp>
namespace nlsr {
@@ -35,48 +39,135 @@ class Nlsr;
class HelloProtocol
{
public:
HelloProtocol(Nlsr& nlsr, ndn::Scheduler& scheduler)
: m_nlsr(nlsr)
, m_scheduler(scheduler)
{
}
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);
/*! \brief Sends a Hello Interest packet.
*
* \param interestNamePrefix The name of the router that has published the
* update we want. Here that should be: \<router name\>/NLSR/INFO
*
* \param seconds The lifetime of the Interest we construct, in seconds
*
* This function attempts to contact neighboring routers to
* determine their status (which currently is one of: ACTIVE,
* INACTIVE, or UNKNOWN)
*/
void
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.
*/
void
sendScheduledInterest(uint32_t seconds);
/*! \brief Processes a Hello Interest from a neighbor.
*
* \param name (ignored)
*
* \param interest The Interest object that we have received and need to
* process.
*
* Processes a Hello Interest that this router receives from one of
* its neighbors. If the neighbor that sent the Interest does not
* have a Face, NLSR will attempt to create one. Also, if the
* neighbor that sent the Interest was previously marked as
* INACTIVE, NLSR will attempt to contact it with its own Hello
* Interest.
*/
void
processInterest(const ndn::Name& name, const ndn::Interest& interest);
ndn::util::signal::Signal<HelloProtocol, Statistics::PacketType> hpIncrementSignal;
private:
/*! \brief Try to contact a neighbor via Hello protocol again
*
* This function will re-send Hello Interests a configured number
* of times. After that many failures, HelloProtocol will mark the neighbor as
* inactive and will not attempt to contact them until the next time
* HelloProtocol::sendScheduledInterest is called.
*
* \sa nlsr::ConfParameter::getInterestRetryNumber
*/
void
processInterestTimedOut(const ndn::Interest& interest);
/*! \brief Verify signatures and validate incoming Hello data.
*/
void
onContent(const ndn::Interest& interest, const ndn::Data& data);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/*! \brief Change a neighbor's status
*
* Whenever incoming Hello data is verified and validated, change
* the status of this neighbor and then schedule an adjacency LSA
* build for us. This also resets the number of times we've failed
* to contact this neighbor so that we will retry later.
*/
void
onContentValidated(const ndn::shared_ptr<const ndn::Data>& data);
onContentValidated(const ndn::Data& data);
private:
/*! \brief Log that incoming data couldn't be validated, but do nothing else.
*/
void
onContentValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
const std::string& msg);
onContentValidationFailed(const ndn::Data& data,
const ndn::security::v2::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(uint32_t code, const std::string& error,
onRegistrationFailure(const ndn::nfd::ControlResponse& response,
const ndn::Name& name);
/*! \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);
/*! \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);
@@ -88,6 +179,6 @@ private:
static const std::string NLSR_COMPONENT;
};
} //namespace nlsr
} // namespace nlsr
#endif // NLSR_HELLO_PROTOCOL_HPP
Loaded 100 of 264 files, more files were not shown because too many files have changed in this diff. Show more