BIND 10 experiments/fix-dhcp-test, updated. 08d87cd87663b46a6a7a85fa045fc065c12c52ef [experiments/fix-dhcp-test] Merge branch 'master' into experiments/fix-dhcp-test
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Nov 6 12:53:04 UTC 2012
The branch, experiments/fix-dhcp-test has been updated
via 08d87cd87663b46a6a7a85fa045fc065c12c52ef (commit)
via 36514ddc884c02a063e166d44319467ce6fb1d8f (commit)
via 18520152ce6097c22024bca864ec53643be3ef84 (commit)
via c19c1fff5013cec501f7c36fe272ecf2bc65d695 (commit)
via 1f2f8e9d497246e335dcbb9604521eb70ccd4524 (commit)
via 3cafab05e08e6aeb0eac010a3f12ffa3e8e734dc (commit)
via 81cf2b7ac4c5ee295c0d654c4ce24911dd23c2c4 (commit)
via 686594e391c645279cc4a95e0e0020d1c01fba7e (commit)
via b1b6e109cda0458811ab61be4263a51b5520ce0b (commit)
via 9a15250b2c74f8b637cf1f32f79cc626cb05d0e5 (commit)
via f2b5789e89f48e5a045f8c921f09b5c3caddea3a (commit)
via d12d0c3368d26ab81c5a3c63bad696ee2282530f (commit)
via 8df24b61c35bf2e4963c195e1c927980e16c4a9c (commit)
via 9f360b39c79ef71edb474fb6fe443ff30b479fb6 (commit)
via 5e97750478c1a655d85107bbbda556c8e8bcfec0 (commit)
via b1f95f0359a425b9d758cfacffc75a4517fb342f (commit)
via 82c05da76c188848bb0c0fa2e93c0e90178b5008 (commit)
via 5ee9df691d301f7a6b3c422013336f229292da35 (commit)
via 240c5dfdc3f777eb49b41423dbaec2f9479c4eb6 (commit)
via 6ad5fcf5b5bf4ca4f0295585ac8ad1521baf062a (commit)
via 42298cee62c386318f248bcae47d99a39094a10a (commit)
via 88a8de015f4652fd73164457414f72ab43dcf681 (commit)
via 0192fd73649d14ade8dc284c64f38d5e0d8b0705 (commit)
via e75c686cd9c14f4d6c2a242a0a0853314704fee9 (commit)
via cb8128c933f47c23596bce0dd4eaaf77c6af2b6e (commit)
via c8d6f38ab7cea07e3bc75a5b4cec8207c2db61fd (commit)
via 17749f1ef367d560e5b878e814352e8b8082542e (commit)
via 08baa5371d0939356ba56f24f2d537834f7e9bac (commit)
via 8b36f92a0e51a40702a2fa5db7eabe5344adfeaa (commit)
via fd51de64c1738d586791060e3855f414f3cdcdc7 (commit)
via cfcad4db4f9da2525f7c9cddcdd52660f60e4afa (commit)
via 127e416cb3b2d08b2cd9356ca7c8bd109dbef95d (commit)
via c4159fc5c746ee7df7aae8c590789e675050d75c (commit)
via b2d9be92c95432c92d4996bd999960e08edcc9bc (commit)
via d3bdb3c1c1dca514322fefdaac18a253364dfd2f (commit)
via 0be210a2f53811e07a7ff0aad0aa388c3ef6048c (commit)
via 8d2205ed3fc327862a0e3a7169e0432f221d514b (commit)
via 67500d3bd8ae816e5ad73cf475d49f34546db639 (commit)
via 698ad7c5546e6f0e44be3d9ee1ae57e541a9f968 (commit)
via 61d7c3959eb991b22bc1c0ef8f4ecb96b65d9325 (commit)
via 27e863962f01a9dc8ac5c756ff881cb585c00abf (commit)
via 1c12d2036d9e92d0475f421406bdca6839b04326 (commit)
via 7735c8e85cb8275ee5bd1918bff809612248c43d (commit)
via 59a449f506948e2371ffa87dcd19059388bd1657 (commit)
via 7ec750c09a3828d28362bc557816e24a6b2207cf (commit)
via 041dbf514a284b9c14f3a803dbaa8e4260b804f2 (commit)
via 7dff35a176bcf41d83a14eb5b3fbca6a7dcfafb8 (commit)
via 0187917d0b77b34997c4666d27f916cd8f6b4dd4 (commit)
via 7187c1bb9c1b8a1d01843b8b3328454a9bce4d4d (commit)
via 105208c1e8cd0a77cb8960013a391cc7b48f7a22 (commit)
via f4390da9f83529b6c3ed4383d7709e9ede1c3d5b (commit)
via 40ae159a7ae9c1c1049bd8c18e37ed086c1aafae (commit)
via 9281b972a87becd0f85b747d5d939f8f2e317247 (commit)
via 8a0af829c62d143ebb80f99131f7bcb2918add82 (commit)
via 61fc577d38615b1a25b5a94fa3bbaca9ec2f6ddf (commit)
via 4965591081ad8457f5ff0f3fe3c581f8e1a4da54 (commit)
via 83a6c4414e87db481e684f8b6757182a5b8a2cae (commit)
via 7b11fd33ba9b3b0548a1b0e72b337fe5e3843b3b (commit)
via 7151128386c71f20f2e51a156d1fb1746fcd7bfa (commit)
via 4163ddf6d718bc6239a92a592687701053a5cf06 (commit)
via 98947382e572f239b57f3f79a928636ea42d3696 (commit)
via b2964261a72d6eff164cafe4b24fd5bfce0fa469 (commit)
via fb8ce6a031254899bc2fdc101e5e279bed51829d (commit)
via 869e658fbc3e33c5037f3866beb2ff76c03cbdf4 (commit)
via 3271dcc47f185103c208585d1df8a92e50274f7a (commit)
via 7e2dedc024cd77a301d7e30d180e16fa2132cbf5 (commit)
via ce0a6a9742cd2c18cb4c33ad0f174690ed1cbfc9 (commit)
via 8aa188a10298e3a55b725db36502a99d2a8d638a (commit)
via 4e98f9c8aec4fbe707bf4f5aa8de9e3ce4737f79 (commit)
via 05dbb62986e1b0260156658896c051cde3c6d53f (commit)
via 5a9bc9bc1467bfd5d0be7de9db40824a967be9b0 (commit)
via e62b6417336ebdaeda560e47b177e617ee4551e5 (commit)
via a88ab93f5a8722d16f96a4e58952042ff2564751 (commit)
via 33fd1fb0ed8ebfceb01e8a84b1196af29dffde92 (commit)
via 844348f6a9c5d4670f96750a2c94ade6778891d9 (commit)
via 57b907eddc75241956102dd4de70d882c1b1fe63 (commit)
via a311ab52fe83d602a2ac3daa12314df7de258bae (commit)
via 85ccee0ac4c1397c8a5bf225470467c55623a28c (commit)
via f4dd53d74dfa8496e8f846960ac7424493858848 (commit)
via 1b63f7d9df1621053c71ec3ef546a8cae024dffb (commit)
via 84df8fb3d06ad81e04fee73b6a31890ddc03c33e (commit)
via b9afd797dee6f7ede5c387466547ac5a06277ecd (commit)
via dba0f070ef3f4a78db630b3002eef5fd2ba757e0 (commit)
via b77e7ed31d3121c8fb3826c9a8909044e0f4f6ab (commit)
via cf72f036909c786091f845a736bfd6fcfd15a7ac (commit)
via e4850b8e75f2d8fd4924b5060cbf3c4458d3513d (commit)
via aade8ac800d58c46dad9ab862cf0d6e85174b17d (commit)
via 7900248aec3191e202066f5dfaad98f6469c32df (commit)
via 0c8f4961f3f2b8884e5567e51bf629016a35e9d7 (commit)
via dcf59e93fadc2df047e4cb9dba138ffc0f619d3e (commit)
via 414a83fefbb7374f31f362e80efef262722660eb (commit)
via 9394d67b638a84409c3491fee821f347ca2acbcf (commit)
via 6a8228eb8556681c30c7163010f7fb354a9ef66c (commit)
via a5a98d2f3e44ebec0de30f4f0905b83ca3a5df75 (commit)
via a54864927bc88eebbfb0f9515207ba9a3cacaa3e (commit)
via f49a40682835963334f3d5f2014bfed6b0895400 (commit)
via 462af9f5a374d7c60c8ac2b38e6d663f2af41cc3 (commit)
via f48cb0979513b642ab8cea30be5a3caa10fff958 (commit)
via 30873bc3691ff9be1d9ce56dfb4c3dc30e4dabbc (commit)
via ab6215d2e93f0bc0206f4503a9e5b0ea62bf65f3 (commit)
via fd2e13361be9f4e4fb4e1098bae2058de33432f7 (commit)
via f6af1e6965348482deb45174ba7b4dcb6e9cef61 (commit)
via 1114159c5b113a98db20ecaed992022917300216 (commit)
via dc3884d6b3e3f80144d57a6edc0223d97f5a46af (commit)
via 195617a1fd88af3bfbb397263cd67a148d0e7d67 (commit)
via 6ead8f2bc21f09b34f842dda074d121a9f511ed5 (commit)
via bd8b562bcf016c70f229ba1cb7fa084035eff9e0 (commit)
via 653d1d854ad6574806ed09f6b42aaa4a17f27b57 (commit)
via d8b60408e4843a88d15e3cd95dfeb898cea2a8fd (commit)
via 99bdc7de647ee1abb8401cc1fd8337462173e7f8 (commit)
via a6ca17646b6bdf23f36d523bb56f3bb91e1dbf39 (commit)
via 4b1c96c8a9bba522a512d07b23e36feebaec10bd (commit)
via d12b460fbb26cfbd968bf0db25c1d0d3a8d5fb4a (commit)
via 3b3b42295d636901e0647d0bba3a4f3677af50a0 (commit)
via 0bc630b2e4ab6efd3f837f2dd6f5e771e6a71b3c (commit)
via c37eaa23d920b79d3f344c8fbafbdcda37231b47 (commit)
via a2224a3c4ea8bcfc685190d78e539608e76006f4 (commit)
via eac4d4fdbc978c037d83081a3a7d99db4a8135bd (commit)
via edcbc935eb6ddc4bb5fac1e76e8eac100e783e74 (commit)
via 7ff2ddee910f9a53bd1dd47c432c99a280a6d076 (commit)
via 3519306b1c9d4bcaf8d6758ca65ad4a371296346 (commit)
via 64b2a61c6d242b974169b72542be45a57630ec8d (commit)
via 03499b185e1dca3807f4c09cd36ba066f25bc918 (commit)
via ecabe80cbb2483d8057a83c84faeb84ce903b555 (commit)
via f609865c302b87caa3f5721557b0e5491c3eba3e (commit)
via 70473ce1f70543029936a6c5c6c055ea7a33581b (commit)
via 4475bf75419cba6488628a2eb6f3b19fc795ae05 (commit)
via 9e5e49a5c857b592cc08ba8e3db6a00c9a7fd179 (commit)
via 5da59e27b2f165d089a8a2a936b4e9eb21387fcc (commit)
via 0eb033a6b10eac2e2767923ccfe5e74f2d2b2680 (commit)
via 5744cc1cf3c348d120ef5dc3f1f97e23a0aa6fea (commit)
via 08e5c7f5394f449a3e5b7128eacdf5b7a096aa5e (commit)
via cb330a06847987bfacacc7a9333b70666750b66d (commit)
via c7123c288ebc9a1ac9aa86c43219877c86a6a032 (commit)
via 566ab87733df04e288749e8ab5fb7c1a2c1156cf (commit)
via f687a6f097f17344cdf298e33b6592fd41fc8e43 (commit)
via c6f40e97e8cde76793b79c54d3611fe9914bc166 (commit)
via 461164b527fd4b7f047820e7d1f7b22eb1b3458c (commit)
via 88259891ae9cdc24ac5e48b5c3b0cb6615f73d19 (commit)
via 3f3183672b5d824d03fb494dd0d21eaf5d1241cb (commit)
via 683f4b7420d46fe6a92d3e40225b427eaca1d9f7 (commit)
via d899142df0fe588d8f4fa02f4120993f69cdea31 (commit)
via ad46427a54b6169859924c37e3966625f3a3b0b4 (commit)
via 42c8b84a3fc7c45bfb3df671b5c4a7f7a9b3d376 (commit)
via 2c5059119b843646ca59612cf69c4439b04494c8 (commit)
via fa6cef4dfbadd457c75ef5fc5f7ffe42d916a2de (commit)
via e710685dced3b2f30ecda4ead1d0dc9f6ae64361 (commit)
via 059a2a175193e5c60a3a5e647acf95e0eb6b9a6a (commit)
via 6d1358617343e061a6b2ac16a7830853674d1c5c (commit)
via 29047b54a17c2bc1d27096ea21522e928b51989f (commit)
via dbabdcc3c8c103a56a6da5187a97f2748adfa467 (commit)
via 54ae641d1c1fa87baeb702ec0ee25b28c2b7aebd (commit)
via 1d4d9e796c10786417099a69e8c4e6e4c1cdfb8b (commit)
via 503a7b06ae96ef13d1f1a5344e07c06786b5eb83 (commit)
via 7eb5518a386019fd723fb2484eb40f13ff283515 (commit)
via 0aa3d59397af2c127758616bdd93c22d3176d28b (commit)
via a4560fb5f2093d4619fb159d77501dd7e6978d35 (commit)
via 01c85b2bf83b55be659ebe1526eaa1c5aa55b6aa (commit)
via 07085635d4c12c77ac979ea9755d38a2a40f77b4 (commit)
via 7d777cee74391169cd589dab1330eda699d2b8d6 (commit)
via 54a03955995437e3cb380ef5ffba44d61be04213 (commit)
via 0dfa29e875e3a668e7b6718b510c12df590faec7 (commit)
via b4a991767173f93daa5100909740413530c4445d (commit)
via a582a2143369f6848cae1bb82301f5a657293f17 (commit)
via 71a249c1564261f2643515451a68e388603eaf4c (commit)
via 718ab061bfe0fbad59c5d829d32d1fb71608c324 (commit)
via 265fc0cc3154f8963e5ab68fd2890eeec64e13be (commit)
via 3e189b431fd39c99aaf4fa8f78a3e41d722f37ed (commit)
via 4a9e338f845772c9a0888a276c30449f89beea9c (commit)
via daaa9544987cf61adb4a16fb955885019cce8885 (commit)
via 41fa47c50d302aa71e9aee629c28ed9cb4fcd065 (commit)
via c59f610bf61bbc374b401a0ac6f595240bd4c629 (commit)
via a92defd1deceebc13a7bcc93cee6579ed42be41e (commit)
via a09e57e212a102d719315aff8d0f3c4ce74268d8 (commit)
via 7c4e02c157bf7a4baaa81c448ff485e7dec31182 (commit)
via 2eaf01995b4c0d6c007afd51c94b8453cbb797ca (commit)
via 8b19f3a80a57b4a0c41e58460920924d5613e606 (commit)
via 98db15a31fea52ec2b1952846c61d20f9f373305 (commit)
via 4f4b3724e1e06933646dcbee14f31eb2713a514d (commit)
via 4ea73cff14dfd8c6898f1c79e7de860a2ca83b33 (commit)
via 77e32834470282fe08ae7fb8c8fb9a4afb163677 (commit)
via 1eda789420a1914f61ee720043a15516157f23b4 (commit)
via 61d475331f841b3d5f1b2461ae99fe45f5d554fe (commit)
via f0c56bb2f6bc3a8118acd5f27e0be45d23b6be21 (commit)
via 82d164c20e0dd8a359b8493a2bc1216436549a4d (commit)
via 2fa49003caec9837963fdee5c8ef7ca5ed1b6413 (commit)
via 61256f84ff903ba7f0bddd2569f9fddcdbb194d2 (commit)
via ee7d5cf20406b4ff00a52ce8218304c6623571ea (commit)
via d1c32c6bd6bb7621968266b09ca979ecce428530 (commit)
via c62976b616bd2b44a9f791c47afde5d89ef9913a (commit)
via 7161d9d899723f1be561125087e1daaf820e80ed (commit)
via 3ac353a5a561e5a0ecae750bd0d52afb2fa86037 (commit)
via d97fa9cb68dea0cf8873f9b28ac6671ee321a1f6 (commit)
via 3d7fea6b15278d8f66840bff3cc4f9a3b1d60d23 (commit)
via a82ee1d047fe786113491226f7e81a08ed58e8c4 (commit)
via 7c40eaf7779f7fb3b80ad141c58f60e69a2f3e4e (commit)
via fa78c4ba3aff851955576ec7e98f8fe98dacd889 (commit)
via 149df5a690bc874b8814669c19a8666e2cddf961 (commit)
via 2a6f0764001c25acb40eae27d7a2f7691d4c767b (commit)
via 4887037cd08e567596339dbb3d65557b8e25560d (commit)
via 7b598ee429c070c4c784e41822a4904ee71ebf95 (commit)
via 8334de9f905bc792b0ec866a03a2dde05e5330fe (commit)
via 667ecc41e7f8c0a47a1d701cb5cf16ecc7264205 (commit)
via 0c3a609fdde1fe14de8d2c032e1350c3f10c3058 (commit)
via ce585a075a28df8b5815b38cd461da1dce17406d (commit)
via b4f9ae7bf9569106d47a0ff227552eb6a956aa4e (commit)
via 8422f4dd15cbdd9bd33f3a570bdf40b991665ab9 (commit)
via 3f6ddec37ff9bb49440ce6ceaf02842c74d0b865 (commit)
via c638fb4e2776b24b7ecf3c071086056d5cc9d78f (commit)
via 43f01176f71c387638ff876b7ce31dd42f6bdb9d (commit)
via 124780d941405d05a2a2906160a3c479a8417abc (commit)
via 67a6dccbdd9fe5b08b80224fd395fab676cb704c (commit)
via fb4eb0b2229e58f19526247193c427fe7af8b9b2 (commit)
via c522619b6b3555c5fa0fc8367b6ebc4e72e9335d (commit)
via 35eb49f72a3dceb354e300469d0c4f342ddb3c8a (commit)
via a8a40b6805377c49a9671bd93cb510bfef946a87 (commit)
via 55ca986dc44bb8059712619dadb64c359356e00a (commit)
via c1d90c602c39b7b49e7c8ab802956118f8846cd7 (commit)
via 72941a64efbe4843657cbb05f8945f7c6dc0e3a0 (commit)
via 3c3bea55f38dac4d8fcc9c0cda55c6382d6c2cd7 (commit)
via 307071b44a3b5e5e3e8d3cc75b00c69d81fefaee (commit)
via a7adf4e4fe023903dd4ca362a6cfa6cafc06241d (commit)
via 98cdad7fa22451ef1ca067ee747c70a31262ee61 (commit)
via c76e3fc072e8b1b771b55b6547889863ba263f31 (commit)
via 50c395e0d786b2330919498c37149edf22808a52 (commit)
from 2acf5b5eaa615c6fb6d4015424ed89734b6b6808 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 08d87cd87663b46a6a7a85fa045fc065c12c52ef
Merge: 2acf5b5 36514dd
Author: Jelte Jansen <jelte at isc.org>
Date: Tue Nov 6 13:52:54 2012 +0100
[experiments/fix-dhcp-test] Merge branch 'master' into experiments/fix-dhcp-test
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 30 +
Makefile.am | 2 +-
configure.ac | 52 +-
doc/Doxyfile | 2 +-
doc/devel/02-dhcp.dox | 72 ---
doc/devel/mainpage.dox | 4 +
examples/README | 15 +
examples/configure.ac | 7 +
examples/m4/ax_boost_include.m4 | 4 +-
examples/m4/ax_isc_bind10.m4 | 40 +-
examples/m4/ax_isc_rpath.m4 | 46 ++
src/bin/auth/Makefile.am | 3 +-
src/bin/auth/auth.spec.pre.in | 140 ++---
src/bin/auth/auth_config.h | 6 +-
src/bin/auth/auth_log.h | 6 +-
src/bin/auth/auth_messages.mes | 19 +-
src/bin/auth/auth_srv.cc | 104 ++--
src/bin/auth/auth_srv.h | 52 +-
src/bin/auth/benchmarks/Makefile.am | 3 +-
src/bin/auth/command.cc | 46 +-
src/bin/auth/command.h | 6 +-
src/bin/auth/common.h | 6 +-
src/bin/auth/datasrc_clients_mgr.h | 206 ++++++-
src/bin/auth/datasrc_config.h | 6 +-
src/bin/auth/statistics.cc | 296 ++++++----
src/bin/auth/statistics.h | 229 +++++---
src/bin/auth/statistics_items.h | 609 ++++++++++++++++++++
src/bin/auth/tests/Makefile.am | 3 +-
src/bin/auth/tests/auth_srv_unittest.cc | 243 ++++++--
src/bin/auth/tests/command_unittest.cc | 275 ---------
.../auth/tests/datasrc_clients_builder_unittest.cc | 347 ++++++++++-
src/bin/auth/tests/datasrc_clients_mgr_unittest.cc | 49 ++
src/bin/auth/tests/datasrc_util.h | 6 +-
src/bin/auth/tests/statistics_unittest.cc | 372 ++----------
src/bin/auth/tests/test_datasrc_clients_mgr.cc | 2 +
src/bin/auth/tests/test_datasrc_clients_mgr.h | 3 +-
src/bin/bindctl/tests/bindctl_test.py | 5 +-
src/bin/cfgmgr/Makefile.am | 2 +-
src/bin/cfgmgr/local_plugins/Makefile.am | 11 +
src/bin/cfgmgr/plugins/Makefile.am | 2 +-
src/bin/cfgmgr/plugins/datasrc.spec.pre.in | 4 +-
src/bin/dhcp4/dhcp4_log.h | 6 +-
src/bin/dhcp6/Makefile.am | 1 +
src/bin/dhcp6/config_parser.cc | 434 +++++++++++++-
src/bin/dhcp6/dhcp6.dox | 8 +-
src/bin/dhcp6/dhcp6.spec | 69 ++-
src/bin/dhcp6/dhcp6_log.h | 6 +-
src/bin/dhcp6/dhcp6_messages.mes | 5 +
src/bin/dhcp6/tests/Makefile.am | 1 +
src/bin/dhcp6/tests/config_parser_unittest.cc | 430 +++++++++++++-
src/bin/resolver/resolver.h | 6 +-
src/bin/resolver/resolver_log.h | 6 +-
src/bin/resolver/response_scrubber.h | 6 +-
src/bin/sockcreator/sockcreator.h | 6 +-
src/bin/sysinfo/.gitignore | 3 +-
src/bin/sysinfo/Makefile.am | 1 +
.../run_sysinfo.sh.in} | 22 +-
src/bin/sysinfo/sysinfo.py.in | 6 +-
src/bin/tests/process_rename_test.py.in | 7 +
src/lib/acl/dnsname_check.h | 6 +-
src/lib/acl/ip_check.h | 6 +-
src/lib/acl/tests/sockaddr.h | 6 +-
src/lib/asiodns/asiodns.h | 6 +-
src/lib/asiodns/dns_answer.h | 6 +-
src/lib/asiodns/dns_lookup.h | 6 +-
src/lib/asiodns/dns_server.h | 6 +-
src/lib/asiodns/dns_service.h | 6 +-
src/lib/asiodns/io_fetch.h | 6 +-
src/lib/asiodns/sync_udp_server.h | 6 +-
src/lib/asiodns/tcp_server.h | 6 +-
src/lib/asiodns/udp_server.h | 6 +-
src/lib/asiolink/asiolink.h | 6 +-
src/lib/asiolink/dummy_io_cb.h | 6 +-
src/lib/asiolink/interval_timer.h | 6 +-
src/lib/asiolink/io_address.h | 6 +-
src/lib/asiolink/io_asio_socket.h | 6 +-
src/lib/asiolink/io_endpoint.h | 6 +-
src/lib/asiolink/io_error.h | 6 +-
src/lib/asiolink/io_message.h | 6 +-
src/lib/asiolink/io_service.h | 6 +-
src/lib/asiolink/io_socket.h | 6 +-
src/lib/asiolink/simple_callback.h | 6 +-
src/lib/asiolink/tcp_endpoint.h | 6 +-
src/lib/asiolink/tcp_socket.h | 6 +-
src/lib/asiolink/udp_endpoint.h | 6 +-
src/lib/asiolink/udp_socket.h | 6 +-
src/lib/bench/benchmark.h | 6 +-
src/lib/bench/benchmark_util.h | 6 +-
src/lib/bench/example/search_bench.cc | 1 -
src/lib/cache/cache_entry_key.h | 6 +-
src/lib/cache/local_zone_data.h | 6 +-
src/lib/cache/logger.h | 4 +-
src/lib/cache/message_cache.h | 6 +-
src/lib/cache/message_entry.h | 6 +-
src/lib/cache/message_utility.h | 6 +-
src/lib/cache/resolver_cache.h | 6 +-
src/lib/cache/rrset_cache.h | 6 +-
src/lib/cache/rrset_copy.h | 6 +-
src/lib/cache/rrset_entry.h | 6 +-
src/lib/cc/data.h | 6 +-
src/lib/cc/session.h | 6 +-
src/lib/config/ccsession.h | 6 +-
src/lib/config/config_data.h | 4 +-
src/lib/config/config_log.h | 6 +-
src/lib/config/module_spec.h | 4 +-
src/lib/config/tests/fake_session.h | 6 +-
src/lib/cryptolink/crypto_hmac.h | 6 +-
src/lib/cryptolink/cryptolink.h | 6 +-
src/lib/datasrc/client.h | 4 +-
src/lib/datasrc/client_list.cc | 123 +++-
src/lib/datasrc/client_list.h | 53 +-
src/lib/datasrc/data_source.h | 4 +-
src/lib/datasrc/database.h | 6 +-
src/lib/datasrc/datasrc_config.h.pre.in | 7 +-
src/lib/datasrc/factory.h | 4 +-
src/lib/datasrc/iterator.h | 6 +-
src/lib/datasrc/logger.h | 4 +-
.../memory/benchmarks/rdata_reader_bench.cc | 1 -
.../memory/benchmarks/rrset_render_bench.cc | 1 -
src/lib/datasrc/memory/domaintree.h | 6 +-
src/lib/datasrc/memory/memory_client.cc | 56 +-
src/lib/datasrc/memory/memory_client.h | 9 +-
src/lib/datasrc/memory/treenode_rrset.cc | 2 +-
src/lib/datasrc/memory/zone_data_loader.cc | 6 +-
src/lib/datasrc/memory/zone_data_loader.h | 4 +-
src/lib/datasrc/memory/zone_table.cc | 9 +-
src/lib/datasrc/memory/zone_table.h | 16 +-
src/lib/datasrc/memory/zone_table_segment.cc | 7 +-
src/lib/datasrc/memory/zone_table_segment.h | 55 +-
src/lib/datasrc/memory/zone_table_segment_local.cc | 17 +
src/lib/datasrc/memory/zone_table_segment_local.h | 13 +-
src/lib/datasrc/memory_datasrc.h | 6 +-
src/lib/datasrc/rbnode_rrset.h | 6 +-
src/lib/datasrc/rbtree.h | 6 +-
src/lib/datasrc/result.h | 4 +-
src/lib/datasrc/sqlite3_accessor.h | 6 +-
src/lib/datasrc/tests/client_list_unittest.cc | 175 ++++--
src/lib/datasrc/tests/memory/Makefile.am | 1 +
.../datasrc/tests/memory/memory_client_unittest.cc | 25 +-
.../datasrc/tests/memory/zone_table_segment_test.h | 116 ++++
.../tests/memory/zone_table_segment_unittest.cc | 54 +-
.../datasrc/tests/memory/zone_table_unittest.cc | 4 +-
.../datasrc/tests/memory/zone_writer_unittest.cc | 15 +-
src/lib/datasrc/tests/test_client.h | 6 +-
.../datasrc/tests/zone_finder_context_unittest.cc | 22 +-
src/lib/datasrc/zone.h | 6 +-
src/lib/datasrc/zonetable.h | 6 +-
src/lib/dhcp/Makefile.am | 3 +-
src/lib/dhcp/addr_utilities.cc | 13 +-
src/lib/dhcp/alloc_engine.cc | 274 +++++++++
src/lib/dhcp/alloc_engine.h | 228 ++++++++
src/lib/dhcp/duid.h | 12 +-
src/lib/dhcp/lease_mgr.cc | 47 +-
src/lib/dhcp/lease_mgr.h | 78 ++-
src/lib/dhcp/libdhcp++.dox | 79 +++
src/lib/dhcp/libdhcsrv.dox | 86 +++
src/lib/dhcp/pool.h | 2 +
src/lib/dhcp/subnet.cc | 37 +-
src/lib/dhcp/subnet.h | 94 ++-
src/lib/dhcp/tests/Makefile.am | 5 +-
src/lib/dhcp/tests/alloc_engine_unittest.cc | 343 +++++++++++
src/lib/dhcp/tests/cfgmgr_unittest.cc | 4 +-
src/lib/dhcp/tests/lease_mgr_unittest.cc | 344 ++++-------
src/lib/dhcp/tests/memfile_lease_mgr.cc | 113 ++++
.../{lease_mgr_unittest.cc => memfile_lease_mgr.h} | 188 ++----
src/lib/dhcp/tests/pool_unittest.cc | 1 -
src/lib/dhcp/tests/subnet_unittest.cc | 72 ++-
src/lib/dns/Makefile.am | 3 +
src/lib/dns/benchmarks/message_renderer_bench.cc | 1 -
src/lib/dns/benchmarks/oldmessagerenderer.h | 6 +-
src/lib/dns/character_string.h | 6 +-
src/lib/dns/edns.h | 6 +-
src/lib/dns/exceptions.h | 6 +-
src/lib/dns/gen-rdatacode.py.in | 2 +-
src/lib/dns/labelsequence.h | 4 +-
.../unittests/resource.cc => dns/master_lexer.cc} | 36 +-
src/lib/dns/master_lexer.h | 241 ++++++++
src/lib/dns/masterload.h | 6 +-
src/lib/dns/message.h | 6 +-
src/lib/dns/messagerenderer.h | 6 +-
src/lib/dns/name.cc | 135 ++++-
src/lib/dns/name.h | 48 +-
src/lib/dns/name_internal.h | 6 +-
src/lib/dns/nsec3hash.h | 6 +-
src/lib/dns/opcode.h | 4 +-
src/lib/dns/python/edns_python.h | 6 +-
src/lib/dns/python/message_python.h | 6 +-
src/lib/dns/python/messagerenderer_python.h | 6 +-
src/lib/dns/python/name_python.h | 6 +-
src/lib/dns/python/nsec3hash_python.h | 6 +-
src/lib/dns/python/opcode_python.h | 6 +-
src/lib/dns/python/pydnspp_common.h | 6 +-
src/lib/dns/python/pydnspp_towire.h | 6 +-
src/lib/dns/python/question_python.h | 6 +-
src/lib/dns/python/rcode_python.h | 6 +-
src/lib/dns/python/rdata_python.h | 6 +-
src/lib/dns/python/rrclass_python.h | 6 +-
src/lib/dns/python/rrset_python.h | 6 +-
src/lib/dns/python/rrttl_python.h | 6 +-
src/lib/dns/python/rrtype_python.h | 6 +-
src/lib/dns/python/serial_python.h | 6 +-
src/lib/dns/python/tsig_python.h | 6 +-
src/lib/dns/python/tsig_rdata_python.h | 6 +-
src/lib/dns/python/tsigerror_python.h | 6 +-
src/lib/dns/python/tsigkey_python.h | 6 +-
src/lib/dns/python/tsigrecord_python.h | 6 +-
src/lib/dns/question.h | 6 +-
src/lib/dns/rcode.h | 4 +-
src/lib/dns/rdata.h | 6 +-
src/lib/dns/rdata/generic/detail/ds_like.h | 6 +-
.../dns/rdata/generic/detail/nsec3param_common.h | 6 +-
src/lib/dns/rdata/generic/detail/nsec_bitmap.h | 6 +-
src/lib/dns/rdata/generic/detail/txt_like.h | 6 +-
src/lib/dns/rdatafields.h | 6 +-
src/lib/dns/rrclass-placeholder.h | 6 +-
src/lib/dns/rrparamregistry.h | 6 +-
src/lib/dns/rrset.cc | 6 +-
src/lib/dns/rrset.h | 11 +-
src/lib/dns/rrttl.h | 6 +-
src/lib/dns/rrtype-placeholder.h | 14 +-
src/lib/dns/serial.h | 6 +-
src/lib/dns/tests/Makefile.am | 1 +
src/lib/dns/tests/master_lexer_token_unittest.cc | 156 +++++
src/lib/dns/tests/name_unittest.cc | 124 +++-
src/lib/dns/tests/rdata_unittest.h | 6 +-
src/lib/dns/tests/rrset_unittest.cc | 8 +
src/lib/dns/tests/unittest_util.h | 6 +-
src/lib/dns/tsig.h | 6 +-
src/lib/dns/tsigerror.h | 6 +-
src/lib/dns/tsigkey.h | 6 +-
src/lib/dns/tsigrecord.h | 6 +-
src/lib/exceptions/exceptions.h | 6 +-
src/lib/log/compiler/message.cc | 4 +-
src/lib/log/dummylog.h | 6 +-
src/lib/log/log_dbglevels.h | 6 +-
src/lib/log/log_formatter.h | 4 +-
src/lib/log/log_messages.h | 6 +-
src/lib/log/logger.h | 6 +-
src/lib/log/logger_impl.h | 6 +-
src/lib/log/logger_level.h | 6 +-
src/lib/log/logger_level_impl.h | 6 +-
src/lib/log/logger_manager.h | 6 +-
src/lib/log/logger_manager_impl.h | 6 +-
src/lib/log/logger_name.h | 6 +-
src/lib/log/logger_specification.h | 8 +-
src/lib/log/logger_support.h | 6 +-
src/lib/log/logger_unittest_support.h | 6 +-
src/lib/log/logimpl_messages.h | 6 +-
src/lib/log/macros.h | 4 +-
src/lib/log/message_dictionary.h | 6 +-
src/lib/log/message_exception.h | 6 +-
src/lib/log/message_initializer.h | 6 +-
src/lib/log/message_reader.h | 6 +-
src/lib/log/message_types.h | 6 +-
src/lib/log/output_option.h | 6 +-
src/lib/log/tests/tempdir.h.in | 6 +-
src/lib/nsas/address_entry.h | 6 +-
src/lib/nsas/address_request_callback.h | 6 +-
src/lib/nsas/asiolink.h | 6 +-
src/lib/nsas/fetchable.h | 6 +-
src/lib/nsas/glue_hints.h | 6 +-
src/lib/nsas/hash.h | 6 +-
src/lib/nsas/hash_deleter.h | 6 +-
src/lib/nsas/hash_key.h | 6 +-
src/lib/nsas/hash_table.h | 6 +-
src/lib/nsas/nameserver_address.h | 6 +-
src/lib/nsas/nameserver_address_store.h | 6 +-
src/lib/nsas/nameserver_entry.h | 6 +-
src/lib/nsas/nsas_entry.h | 6 +-
src/lib/nsas/nsas_entry_compare.h | 6 +-
src/lib/nsas/nsas_log.h | 6 +-
src/lib/nsas/nsas_types.h | 6 +-
src/lib/nsas/tests/nsas_test.h | 6 +-
src/lib/nsas/zone_entry.h | 6 +-
src/lib/python/bind10_config.py.in | 4 +-
src/lib/python/isc/acl/dns.h | 6 +-
src/lib/python/isc/acl/dns_requestacl_python.h | 6 +-
src/lib/python/isc/acl/dns_requestcontext_python.h | 6 +-
src/lib/python/isc/acl/dns_requestloader_python.h | 6 +-
src/lib/python/isc/datasrc/client_python.h | 6 +-
.../isc/datasrc/configurableclientlist_python.h | 6 +-
src/lib/python/isc/datasrc/datasrc.h | 6 +-
src/lib/python/isc/datasrc/finder_python.h | 6 +-
src/lib/python/isc/datasrc/iterator_python.h | 6 +-
src/lib/python/isc/datasrc/journal_reader_python.h | 6 +-
src/lib/python/isc/datasrc/updater_python.h | 6 +-
src/lib/python/isc/sysinfo/sysinfo.py | 37 +-
src/lib/python/isc/sysinfo/tests/sysinfo_test.py | 65 ++-
src/lib/python/isc/util/cio/socketsession_python.h | 6 +-
.../isc/util/cio/socketsessionforwarder_python.h | 6 +-
.../isc/util/cio/socketsessionreceiver_python.h | 6 +-
src/lib/resolve/recursive_query.h | 6 +-
src/lib/resolve/resolve.h | 4 +-
src/lib/resolve/resolve_log.h | 6 +-
src/lib/resolve/resolver_callback.h | 4 +-
src/lib/resolve/resolver_interface.h | 6 +-
src/lib/resolve/response_classifier.h | 6 +-
src/lib/server_common/client.h | 6 +-
src/lib/server_common/logger.h | 4 +-
src/lib/server_common/socket_request.h | 6 +-
src/lib/statistics/Makefile.am | 11 +-
src/lib/statistics/counter.cc | 82 ---
src/lib/statistics/counter.h | 48 +-
src/lib/statistics/counter_dict.cc | 265 ---------
src/lib/statistics/counter_dict.h | 184 +++---
src/lib/statistics/tests/Makefile.am | 1 -
src/lib/testutils/dnsmessage_test.h | 6 +-
src/lib/testutils/mockups.h | 6 +-
src/lib/testutils/portconfig.h | 6 +-
src/lib/testutils/socket_request.h | 6 +-
src/lib/testutils/srv_test.h | 6 +-
src/lib/util/buffer.h | 6 +-
src/lib/util/encode/base32hex.h | 6 +-
src/lib/util/encode/base64.h | 6 +-
src/lib/util/encode/hex.h | 6 +-
src/lib/util/filename.h | 6 +-
src/lib/util/hash/sha1.h | 4 +-
src/lib/util/interprocess_sync.h | 6 +-
src/lib/util/interprocess_sync_file.h | 6 +-
src/lib/util/interprocess_sync_null.h | 6 +-
src/lib/util/io/fd.h | 6 +-
src/lib/util/io/pktinfo_utilities.h | 6 +-
src/lib/util/io/sockaddr_util.h | 6 +-
src/lib/util/io/socketsession.h | 6 +-
src/lib/util/io_utilities.h | 6 +-
src/lib/util/locks.h | 6 +-
src/lib/util/lru_list.h | 6 +-
src/lib/util/memory_segment.h | 6 +-
src/lib/util/memory_segment_local.h | 6 +-
src/lib/util/python/pycppwrapper_util.h | 6 +-
src/lib/util/python/wrapper_template.h | 6 +-
src/lib/util/random/qid_gen.h | 6 +-
src/lib/util/random/random_number_generator.h | 6 +-
src/lib/util/range_utilities.h | 25 +-
src/lib/util/strutil.h | 6 +-
src/lib/util/threads/sync.cc | 77 ++-
src/lib/util/threads/sync.h | 6 +
src/lib/util/threads/tests/condvar_unittest.cc | 11 +-
src/lib/util/threads/tests/lock_unittest.cc | 20 +-
src/lib/util/time_utilities.h | 8 +-
src/lib/util/unittests/check_valgrind.h | 6 +-
src/lib/util/unittests/fork.h | 6 +-
src/lib/util/unittests/mock_socketsession.h | 6 +-
src/lib/util/unittests/newhook.h | 6 +-
src/lib/util/unittests/resource.h | 6 +-
src/lib/util/unittests/run_all.h | 6 +-
src/lib/util/unittests/testdata.h | 6 +-
src/lib/util/unittests/textdata.h | 6 +-
src/lib/util/unittests/wiredata.h | 6 +-
src/lib/xfr/xfrout_client.h | 4 +-
tests/lettuce/configurations/auth/.gitignore | 1 +
.../auth_basic.config.orig} | 5 +-
tests/lettuce/features/auth_basic.feature | 20 +
tests/lettuce/features/ddns_system.feature | 7 +-
.../lettuce/features/inmemory_over_sqlite3.feature | 2 +-
tests/lettuce/features/terrain/terrain.py | 2 +
tests/tools/badpacket/command_options.h | 6 +-
tests/tools/badpacket/header_flags.h | 6 +-
tests/tools/badpacket/option_info.h | 6 +-
tests/tools/badpacket/scan.h | 6 +-
tests/tools/badpacket/version.h | 6 +-
tests/tools/perfdhcp/command_options.h | 6 +-
tests/tools/perfdhcp/localized_option.h | 6 +-
tests/tools/perfdhcp/perf_pkt4.h | 6 +-
tests/tools/perfdhcp/perf_pkt6.h | 6 +-
tests/tools/perfdhcp/pkt_transform.h | 6 +-
tests/tools/perfdhcp/stats_mgr.h | 6 +-
tests/tools/perfdhcp/test_control.h | 8 +-
.../tools/perfdhcp/tests/command_options_helper.h | 6 +-
369 files changed, 6922 insertions(+), 3264 deletions(-)
create mode 100644 examples/m4/ax_isc_rpath.m4
create mode 100644 src/bin/auth/statistics_items.h
create mode 100644 src/bin/cfgmgr/local_plugins/Makefile.am
copy src/bin/{loadzone/run_loadzone.sh.in => sysinfo/run_sysinfo.sh.in} (60%)
create mode 100644 src/lib/datasrc/tests/memory/zone_table_segment_test.h
create mode 100644 src/lib/dhcp/alloc_engine.cc
create mode 100644 src/lib/dhcp/alloc_engine.h
create mode 100644 src/lib/dhcp/libdhcp++.dox
create mode 100644 src/lib/dhcp/libdhcsrv.dox
create mode 100644 src/lib/dhcp/tests/alloc_engine_unittest.cc
create mode 100644 src/lib/dhcp/tests/memfile_lease_mgr.cc
copy src/lib/dhcp/tests/{lease_mgr_unittest.cc => memfile_lease_mgr.h} (62%)
copy src/lib/{util/unittests/resource.cc => dns/master_lexer.cc} (51%)
create mode 100644 src/lib/dns/master_lexer.h
create mode 100644 src/lib/dns/tests/master_lexer_token_unittest.cc
delete mode 100644 src/lib/statistics/counter.cc
delete mode 100644 src/lib/statistics/counter_dict.cc
create mode 100644 tests/lettuce/configurations/auth/.gitignore
copy tests/lettuce/configurations/{bindctl/bindctl.config.orig => auth/auth_basic.config.orig} (79%)
create mode 100644 tests/lettuce/features/auth_basic.feature
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index e31f44c..2b564e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+499. [func] team
+ The b10-auth 'loadzone' command now uses the internal thread
+ introduced in 495 to (re)load a zone in the background, so that
+ query processing isn't blocked while loading a zone.
+ (Trac #2213, git 686594e391c645279cc4a95e0e0020d1c01fba7e)
+
+498. [func] marcin
+ Implemented DHCPv6 option values configuration using configuration
+ manager. In order to set values for data fields carried by the
+ particular option, user specifies the string of hexadecimal digits
+ that is in turn converted to binary data and stored into option buffer.
+ More user friendly way of option content specification is planned.
+ (Trac #2318, git e75c686cd9c14f4d6c2a242a0a0853314704fee9)
+
+497. [bug] jinmei
+ Fixed several issues in isc-sysinfo:
+ - make sure it doesn't report a negative value for free memory
+ size (this happened on FreeBSD, but can possibly occur on other
+ BSD variants)
+ - correctly identifies the SMP support in kernel on FreeBSD
+ - print more human readable uptime as well as the time in seconds
+ (Trac #2297, git 59a449f506948e2371ffa87dcd19059388bd1657)
+
+496. [func] tomek
+ DHCPv6 Allocation Engine implemented. It allows address allocation
+ from the configured subnets/pools. It currently features a single
+ allocator: IterativeAllocator, which assigns addresses iteratively.
+ Other allocators (hashed, random) are planned.
+ (Trac #2324, git 8aa188a10298e3a55b725db36502a99d2a8d638a)
+
495. [func] team
b10-auth now handles reconfiguration of data sources in
background using a separate thread. This means even if the new
diff --git a/Makefile.am b/Makefile.am
index 1ed0d63..2f3ce85 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-ACLOCAL_AMFLAGS = -I m4macros ${ACLOCAL_FLAGS}
+ACLOCAL_AMFLAGS = -I m4macros -I examples/m4 ${ACLOCAL_FLAGS}
# ^^^^^^^^ This has to be the first line and cannot come later in this
# Makefile.am due to some bork in some versions of autotools.
diff --git a/configure.ac b/configure.ac
index 09de67f..754d667 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,6 +12,20 @@ AC_CONFIG_MACRO_DIR([m4macros])
# Checks for programs.
AC_PROG_CXX
+# Enable low-performing debugging facilities? This option optionally
+# enables some debugging aids that perform slowly and hence aren't built
+# by default.
+AC_ARG_ENABLE([debug],
+ AS_HELP_STRING([--enable-debug],
+ [enable debugging (default is no)]),
+ [case "${enableval}" in
+ yes) debug_enabled=yes ;;
+ no) debug_enabled=no ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
+ esac],[debug_enabled=no])
+AM_CONDITIONAL([DEBUG_ENABLED], [test x$debug_enabled = xyes])
+AM_COND_IF([DEBUG_ENABLED], [AC_DEFINE([ENABLE_DEBUG], [1], [Enable low-performing debugging facilities?])])
+
# Libtool configuration
#
@@ -50,25 +64,9 @@ AM_CONDITIONAL(USE_CLANGPP, test "X${CLANGPP}" = "Xyes")
# Linker options
-# check -R and -Wl,-R rather than gcc specific -rpath to be as portable
-# as possible.
-AC_MSG_CHECKING([whether -R flag is available in linker])
-LDFLAGS_SAVED="$LDFLAGS"
-LDFLAGS="$LDFLAGS -R/usr/lib"
-AC_TRY_LINK([],[],
- [ AC_MSG_RESULT(yes)
- rpath_flag=-R
- ],[ AC_MSG_RESULT(no)
- AC_MSG_CHECKING([whether -Wl,-R flag is available in linker])
- LDFLAGS="$LDFLAGS_SAVED -Wl,-R"
- AC_TRY_LINK([], [],
- [ AC_MSG_RESULT(yes)
- rpath_flag=-Wl,-R
- ],[ AC_MSG_RESULT(no)
- rpath_flag=no
- ])
- ])
-LDFLAGS=$LDFLAGS_SAVED
+# check -R, "-Wl,-R" or -rpath (we share the AX function defined in
+# examples/m4)
+AX_ISC_RPATH
# Compiler dependent settings: define some mandatory CXXFLAGS here.
# We also use a separate variable B10_CXXFLAGS. This will (and should) be
@@ -203,6 +201,10 @@ case "$host" in
CPPFLAGS="$CPPFLAGS -D_XPG4_2 -D__EXTENSIONS__"
# "now" binding is necessary to prevent deadlocks in C++ static initialization code
LDFLAGS="$LDFLAGS -z now"
+ # Destroying locked mutexes, condition variables being waited
+ # on, etc. are undefined behavior on Solaris, so we set it as
+ # such here.
+ AC_DEFINE([HAS_UNDEFINED_PTHREAD_BEHAVIOR], [1], [Does this platform have some undefined pthreads behavior?])
;;
*-apple-darwin*)
# Starting with OSX 10.7 (Lion) we must choose which IPv6 API to use
@@ -314,10 +316,10 @@ fi
# modules, we embed the path to the modules when possible. We do this even
# when the path is known in the common operational environment (e.g. when
# it's stored in a common "hint" file) for simplicity.
-if test $rpath_flag != no; then
+if test "x$ISC_RPATH_FLAG" != "x"; then
python_rpath=
for flag in ${PYTHON_LDFLAGS}; do
- python_rpath="${python_rpath} `echo $flag | sed -ne "s/^\(\-L\)/${rpath_flag}/p"`"
+ python_rpath="${python_rpath} `echo $flag | sed -ne "s/^\(\-L\)/${ISC_RPATH_FLAG}/p"`"
done
PYTHON_LDFLAGS="${PYTHON_LDFLAGS} ${python_rpath}"
fi
@@ -683,10 +685,10 @@ for flag in ${BOTAN_LIBS}; do
done
# See python_rpath for some info on why we do this
-if test $rpath_flag != no; then
+if test "x$ISC_RPATH_FLAG" != "x"; then
BOTAN_RPATH=
for flag in ${BOTAN_LIBS}; do
- BOTAN_RPATH="${BOTAN_RPATH} `echo $flag | sed -ne "s/^\(\-L\)/${rpath_flag}/p"`"
+ BOTAN_RPATH="${BOTAN_RPATH} `echo $flag | sed -ne "s/^\(\-L\)/${ISC_RPATH_FLAG}/p"`"
done
AC_SUBST(BOTAN_RPATH)
@@ -1112,6 +1114,7 @@ AC_CONFIG_FILES([Makefile
src/bin/bindctl/Makefile
src/bin/bindctl/tests/Makefile
src/bin/cfgmgr/Makefile
+ src/bin/cfgmgr/local_plugins/Makefile
src/bin/cfgmgr/plugins/Makefile
src/bin/cfgmgr/plugins/tests/Makefile
src/bin/cfgmgr/tests/Makefile
@@ -1280,6 +1283,7 @@ AC_OUTPUT([doc/version.ent
src/bin/zonemgr/tests/zonemgr_test
src/bin/zonemgr/run_b10-zonemgr.sh
src/bin/sysinfo/sysinfo.py
+ src/bin/sysinfo/run_sysinfo.sh
src/bin/stats/stats.py
src/bin/stats/stats_httpd.py
src/bin/bind10/bind10_src.py
@@ -1358,6 +1362,7 @@ AC_OUTPUT([doc/version.ent
chmod +x src/bin/loadzone/run_loadzone.sh
chmod +x src/bin/loadzone/tests/correct/correct_test.sh
chmod +x src/bin/loadzone/tests/error/error_test.sh
+ chmod +x src/bin/sysinfo/run_sysinfo.sh
chmod +x src/bin/usermgr/run_b10-cmdctl-usermgr.sh
chmod +x src/bin/msgq/run_msgq.sh
chmod +x src/bin/msgq/tests/msgq_test
@@ -1421,6 +1426,7 @@ Features:
$enable_features
Developer:
+ Enable Debugging: $debug_enabled
Google Tests: $enable_gtest
Valgrind: $found_valgrind
C++ Code Coverage: $USE_LCOV
diff --git a/doc/Doxyfile b/doc/Doxyfile
index f6b9fa0..cc3b595 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -580,7 +580,7 @@ INPUT = ../src/lib/exceptions ../src/lib/cc \
../src/lib/testutils ../src/lib/cache ../src/lib/server_common/ \
../src/bin/sockcreator/ ../src/lib/util/ ../src/lib/util/io/ \
../src/lib/util/threads/ ../src/lib/resolve ../src/lib/acl \
- ../src/bin/dhcp6 ../src/lib/dhcp ../src/bin/dhcp4 \
+ ../src/lib/statistics ../src/bin/dhcp6 ../src/lib/dhcp ../src/bin/dhcp4 \
../tests/tools/perfdhcp devel
# This tag can be used to specify the character encoding of the source files
diff --git a/doc/devel/02-dhcp.dox b/doc/devel/02-dhcp.dox
index a4bbff9..5c59daa 100644
--- a/doc/devel/02-dhcp.dox
+++ b/doc/devel/02-dhcp.dox
@@ -57,76 +57,4 @@
* that does not support msgq. That is useful for embedded environments.
* It may also be useful in validation.
*
- * @page libdhcp libdhcp++
- *
- * @section libdhcpIntro Libdhcp++ Library Introduction
- *
- * libdhcp++ is an all-purpose DHCP-manipulation library, written in
- * C++. It offers packet parsing and assembly, DHCPv4 and DHCPv6
- * options parsing and ssembly, interface detection (currently on
- * Linux systems only) and socket operations. Following classes are
- * implemented:
- *
- * - isc::dhcp::Pkt4 - represents DHCPv4 packet.
- * - isc::dhcp::Pkt6 - represents DHCPv6 packet.
- *
- * There are two pointer types defined: Pkt4Ptr and Pkt6Ptr. They are
- * smart pointer and are using boost::shared_ptr. There are not const
- * versions defined, as we assume that hooks can modify any aspect of
- * the packet at almost any stage of processing.
- *
- * Both packets use collection of Option objects to represent DHCPv4
- * and DHCPv6 options. The base class -- Option -- can be used to
- * represent generic option that contains collection of
- * bytes. Depending on if the option is instantiated as v4 or v6
- * option, it will adjust its header (DHCPv4 options use 1 octet for
- * type and 1 octet for length, while DHCPv6 options use 2 bytes for
- * each).
- *
- * There are many specialized classes that are intended to handle options with
- * specific content:
- * - isc::dhcp::Option4AddrLst -- DHCPv4 option, contains one or more IPv4 addresses;
- * - isc::dhcp::Option6AddrLst -- DHCPv6 option, contains one or more IPv6 addresses;
- * - isc::dhcp::Option6IAAddr -- DHCPv6 option, represents IAADDR_OPTION (an option that
- * contains IPv6 address with extra parameters);
- * - isc::dhcp::Option6IA -- DHCPv6 option used to store IA_NA and its suboptions.
- *
- * All options can store sub-options (i.e. options that are stored within option
- * rather than in a message directly). This functionality is commonly used in
- * DHCPv6, but is rarely used in DHCPv4. isc::dhcp::Option::addOption(),
- * isc::dhcp::Option::delOption(), isc::dhcp::Option::getOption() can be used
- * for that purpose.
- *
- * @section libdhcpIfaceMgr Interface Manager
- *
- * Interface Manager (or IfaceMgr) is an abstraction layer about low-level
- * network operations. In particlar, it provides information about existing
- * network interfaces See isc::dhcp::IfaceMgr::Iface class and
- * isc::dhcp::IfaceMgr::detectIfaces() and isc::dhcp::IfaceMgr::getIface().
- *
- * Currently there is interface detection is implemented in Linux only. There
- * are plans to implement such support for other OSes, but they remain low
- * priority for now.
- *
- * Generic parts of the code are isc::dhcp::IfaceMgr class in
- * src/lib/dhcp/iface_mgr.cc file. OS-specific code is located in separate
- * files, e.g. iface_mgr_linux.cc. Such separation should be maintained when
- * additional code will be developed.
- *
- * For systems that interface detection is not supported on, there is a stub
- * mechanism implemented. It assumes that interface name is read from a text
- * file. This is a temporary solution and will be removed as soon as proper
- * interface detection is implemented. It is not going to be developed further.
- * To use this feature, store interfaces.txt file. It uses a simple syntax.
- * Each line represents an interface name, followed by IPv4 or IPv6 address
- * that follows it. This is usually link-local IPv6 address that the server
- * should bind to. In theory this mechanism also supports IPv4, but it was
- * never tested. The code currently supports only a single interface defined
- * that way.
- *
- * Another useful methods are dedicated to transmission
- * (isc::dhcp::IfaceMgr::send(), 2 overloads) and reception
- * (isc::dhcp::IfaceMgr::receive4() and isc::dhcp::IfaceMgr::receive6()).
- * Note that receive4() and receive6() methods may return NULL, e.g.
- * when timeout is reached or if dhcp daemon receives a signal.
*/
\ No newline at end of file
diff --git a/doc/devel/mainpage.dox b/doc/devel/mainpage.dox
index 0da5287..e1761ec 100644
--- a/doc/devel/mainpage.dox
+++ b/doc/devel/mainpage.dox
@@ -29,6 +29,10 @@
* - @subpage libdhcp
* - @subpage libdhcpIntro
* - @subpage libdhcpIfaceMgr
+ * - @subpage libdhcpsrv
+ * - @subpage leasemgr
+ * - @subpage cfgmgr
+ * - @subpage allocengine
* - @subpage perfdhcpInternals
*
* @section misc Miscellaneous topics
diff --git a/examples/README b/examples/README
index 65f777b..08f53fa 100644
--- a/examples/README
+++ b/examples/README
@@ -30,3 +30,18 @@ to the configure.ac file:
sinclude(m4/ax_boost_include.m4)
sinclude(m4/ax_isc_bind10.m4)
(and same for other m4 files as they are added under m4/)
+
+On some systems, espeically if you have installed the BIND 10
+libraries in an uncommon path, programs linked with the BIND 10
+library may not work at run time due to the "missing" shared library.
+Normally, you should be able to avoid this problem by making sure
+to invoking the program explicitly specifying the path to the library,
+e.g., "LD_LIBRARY_PATH=/usr/local/lib/bind10 ./my_bind10_app", or
+you may not even notice the issue if you have installed BIND 10
+library in a common library path on your system (sometimes you may
+still need to run ldconfig(8) beforehand). Another option is to embed
+the path to the library in your program. While this approach is
+controversial, and some people rather choose the alternatives, we
+provide a helper tool in case you want to use this option: see the
+lines using BIND10_RPATH in the sample configure.ac file of this
+directory.
diff --git a/examples/configure.ac b/examples/configure.ac
index 9379687..ef9cce0 100644
--- a/examples/configure.ac
+++ b/examples/configure.ac
@@ -14,6 +14,13 @@ AC_LANG([C++])
# Checks for BIND 10 headers and libraries
AX_ISC_BIND10
+# We use -R, -rpath etc so the resulting program will be more likekly to
+# "just work" by default. Embedding a specific library path is a controversial
+# practice, though; if you don't like it you can remove the following setting.
+if test "x$BIND10_RPATH" != "x"; then
+ LDFLAGS="$LDFLAGS $BIND10_RPATH"
+fi
+
# For the example host program, we require the BIND 10 DNS library
if test "x$BIND10_DNS_LIB" = "x"; then
AC_MSG_ERROR([unable to find BIND 10 DNS library needed to build 'host'])
diff --git a/examples/m4/ax_boost_include.m4 b/examples/m4/ax_boost_include.m4
index e41614d..77d19ca 100644
--- a/examples/m4/ax_boost_include.m4
+++ b/examples/m4/ax_boost_include.m4
@@ -34,7 +34,7 @@ if test -z "$with_boost_include"; then
fi
done
fi
-CPPFLAGS_SAVES="$CPPFLAGS"
+CPPFLAGS_SAVED="$CPPFLAGS"
if test "${boost_include_path}" ; then
BOOST_CPPFLAGS="-I${boost_include_path}"
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
@@ -57,7 +57,7 @@ AC_TRY_COMPILE([
CPPFLAGS_BOOST_THREADCONF="-DBOOST_DISABLE_THREADS=1"],
[AC_MSG_RESULT(yes)])
-CPPFLAGS="$CPPFLAGS_SAVES $CPPFLAGS_BOOST_THREADCONF"
+CPPFLAGS="$CPPFLAGS_SAVED $CPPFLAGS_BOOST_THREADCONF"
AC_SUBST(BOOST_CPPFLAGS)
AC_LANG_RESTORE
diff --git a/examples/m4/ax_isc_bind10.m4 b/examples/m4/ax_isc_bind10.m4
index 63e028c..75c37c5 100644
--- a/examples/m4/ax_isc_bind10.m4
+++ b/examples/m4/ax_isc_bind10.m4
@@ -1,4 +1,4 @@
-dnl @synopsis AX_BIND10
+dnl @synopsis AX_ISC_BIND10
dnl
dnl @summary figure out how to build C++ programs using ISC BIND 10 libraries
dnl
@@ -20,9 +20,18 @@ dnl Checks for other BIND 10 module libraries are option, as not all
dnl applications need all libraries. The main configure.ac can handle any
dnl missing library as fatal by checking whether the corresponding
dnl BIND10_xxx_LIB is defined.
+dnl
+dnl In addition, it sets the BIND10_RPATH variable to a usable linker option
+dnl to embed the path to the BIND 10 library to the programs that are to be
+dnl linked with the library. If the developer wants to use the option,
+dnl it can be used as follows:
+dnl if test "x$BIND10_RPATH" != "x"; then
+dnl LDFLAGS="$LDFLAGS $BIND10_RPATH"
+dnl fi
AC_DEFUN([AX_ISC_BIND10], [
AC_REQUIRE([AX_BOOST_INCLUDE])
+AC_REQUIRE([AX_ISC_RPATH])
AC_LANG_SAVE
AC_LANG([C++])
@@ -42,19 +51,20 @@ if test "$bind10_inc_path" = "no"; then
fi
done
fi
-CPPFLAGS_SAVES="$CPPFLAGS"
+CPPFLAGS_SAVED="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" # boost headers will be used in buffer.h
if test "${bind10_inc_path}" != "no"; then
BIND10_CPPFLAGS="-I${bind10_inc_path}"
CPPFLAGS="$CPPFLAGS $BIND10_CPPFLAGS"
fi
AC_CHECK_HEADERS([util/buffer.h],,
- AC_MSG_ERROR([Missing a commonly used BIND 10 header files]))
-CPPFLAGS="$CPPFLAGS_SAVES"
+ AC_MSG_ERROR([Missing a commonly used BIND 10 header file]))
+CPPFLAGS="$CPPFLAGS_SAVED"
AC_SUBST(BIND10_CPPFLAGS)
# Check for BIND10 libraries
CPPFLAGS_SAVED="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS $BIND10_CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS $BIND10_CPPFLAGS"
AC_ARG_WITH(bind10-lib,
AS_HELP_STRING([--with-bind10-lib=PATH],
@@ -70,21 +80,25 @@ fi
# make sure we have buildable libraries
AC_MSG_CHECKING([for BIND 10 common library])
BIND10_COMMON_LIB="-lb10-util -lb10-exceptions"
-LDFLAGS="$LDFLAGS $BIND10_LDFLAGS"
+LDFLAGS_SAVED="$LDFLAGS"
+LDFLAGS_CHECK_COMMON="$LDFLAGS $BIND10_LDFLAGS"
+LIBS_SAVED="$LIBS"
LIBS="$LIBS $BIND10_COMMON_LIB"
for d in $bind10_lib_dirs
do
- LDFLAGS_SAVED="$LDFLAGS"
- LDFLAGS="$LDFLAGS -L$d"
+ LDFLAGS="$LDFLAGS_CHECK_COMMON -L$d"
AC_TRY_LINK([
#include <util/buffer.h>
],[
isc::util::OutputBuffer buffer(0);
-], [BIND10_LDFLAGS="-L${d}"])
+], [BIND10_LDFLAGS="-L${d}"
+ if test "x$ISC_RPATH_FLAG" != "x"; then
+ BIND10_RPATH="${ISC_RPATH_FLAG}${d}"
+ fi
+ ])
if test "x$BIND10_LDFLAGS" != "x"; then
break
fi
- LDFLAGS="$LDFLAGS_SAVED"
done
if test "x$BIND10_LDFLAGS" != "x"; then
AC_MSG_RESULT(yes)
@@ -94,7 +108,7 @@ else
fi
# restore LIBS once at this point
-LIBS="$LIBS_SAVES"
+LIBS="$LIBS_SAVED"
AC_SUBST(BIND10_LDFLAGS)
AC_SUBST(BIND10_COMMON_LIB)
@@ -111,12 +125,12 @@ isc::dns::RRType rrtype(1);
], [BIND10_DNS_LIB="-lb10-dns++"
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
-LIBS="$LIBS_SAVES"
+LIBS="$LIBS_SAVED"
AC_SUBST(BIND10_DNS_LIB)
# Restore other flags
CPPFLAGS="$CPPFLAGS_SAVED"
-LDFLAGS="$LDFLAGS_SAVES"
+LDFLAGS="$LDFLAGS_SAVED"
AC_LANG_RESTORE
])dnl AX_ISC_BIND10
diff --git a/examples/m4/ax_isc_rpath.m4 b/examples/m4/ax_isc_rpath.m4
new file mode 100644
index 0000000..91d9b8a
--- /dev/null
+++ b/examples/m4/ax_isc_rpath.m4
@@ -0,0 +1,46 @@
+dnl @synopsis AX_ISC_RPATH
+dnl
+dnl @summary figure out whether and which "rpath" linker option is available
+dnl
+dnl This macro checks if the linker supports an option to embed a path
+dnl to a runtime library (often installed in an uncommon place), such as
+dnl gcc's -rpath option. If found, it sets the ISC_RPATH_FLAG variable to
+dnl the found option flag. The main configure.ac can use it as follows:
+dnl if test "x$ISC_RPATH_FLAG" != "x"; then
+dnl LDFLAGS="$LDFLAGS ${ISC_RPATH_FLAG}/usr/local/lib/some_library"
+dnl fi
+
+AC_DEFUN([AX_ISC_RPATH], [
+
+# We'll tweak both CXXFLAGS and CCFLAGS so this function will work whichever
+# language is used in the main script. Note also that it's not LDFLAGS;
+# technically this is a linker flag, but we've noticed $LDFLAGS can be placed
+# where the compiler could interpret it as a compiler option, leading to
+# subtle failure mode. So, in the check below using the compiler flag is
+# safer (in the actual Makefiles the flag should be set in LDFLAGS).
+CXXFLAGS_SAVED="$CXXFLAGS"
+CXXFLAGS="$CXXFLAGS -Wl,-R/usr/lib"
+CCFLAGS_SAVED="$CCFLAGS"
+CCFLAGS="$CCFLAGS -Wl,-R/usr/lib"
+
+# check -Wl,-R and -R rather than gcc specific -rpath to be as portable
+# as possible. -Wl,-R seems to be safer, so we try it first. In some cases
+# -R is not actually recognized but AC_TRY_LINK doesn't fail due to that.
+AC_MSG_CHECKING([whether -Wl,-R flag is available in linker])
+AC_TRY_LINK([],[],
+ [ AC_MSG_RESULT(yes)
+ ISC_RPATH_FLAG=-Wl,-R
+ ],[ AC_MSG_RESULT(no)
+ AC_MSG_CHECKING([whether -R flag is available in linker])
+ CXXFLAGS="$CXXFLAGS_SAVED -R"
+ CCFLAGS="$CCFLAGS_SAVED -R"
+ AC_TRY_LINK([], [],
+ [ AC_MSG_RESULT([yes; note that -R is more sensitive about the position in option arguments])
+ ISC_RPATH_FLAG=-R
+ ],[ AC_MSG_RESULT(no) ])
+ ])
+
+CXXFLAGS=$CXXFLAGS_SAVED
+CCFLAGS=$CCFLAGS_SAVED
+
+])dnl AX_ISC_RPATH
diff --git a/src/bin/auth/Makefile.am b/src/bin/auth/Makefile.am
index 6ee6677..7d29fcc 100644
--- a/src/bin/auth/Makefile.am
+++ b/src/bin/auth/Makefile.am
@@ -54,7 +54,7 @@ b10_auth_SOURCES += auth_log.cc auth_log.h
b10_auth_SOURCES += auth_config.cc auth_config.h
b10_auth_SOURCES += command.cc command.h
b10_auth_SOURCES += common.h common.cc
-b10_auth_SOURCES += statistics.cc statistics.h
+b10_auth_SOURCES += statistics.cc statistics.h statistics_items.h
b10_auth_SOURCES += datasrc_clients_mgr.h
b10_auth_SOURCES += datasrc_config.h datasrc_config.cc
b10_auth_SOURCES += main.cc
@@ -74,7 +74,6 @@ b10_auth_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
b10_auth_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
b10_auth_LDADD += $(top_builddir)/src/lib/xfr/libb10-xfr.la
b10_auth_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
-b10_auth_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
b10_auth_LDADD += $(top_builddir)/src/lib/util/threads/libb10-threads.la
b10_auth_LDADD += $(SQLITE_LIBS)
diff --git a/src/bin/auth/auth.spec.pre.in b/src/bin/auth/auth.spec.pre.in
index a471b7a..30a455d 100644
--- a/src/bin/auth/auth.spec.pre.in
+++ b/src/bin/auth/auth.spec.pre.in
@@ -145,7 +145,7 @@
"item_type": "integer",
"item_optional": false,
"item_default": 0,
- "item_title": "Queries TCP ",
+ "item_title": "Queries TCP",
"item_description": "A number of total query counts which all auth servers receive over TCP since they started initially"
},
{
@@ -181,14 +181,6 @@
"item_description": "The number of total request counts whose opcode is status"
},
{
- "item_name": "opcode.reserved3",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 3",
- "item_description": "The number of total request counts whose opcode is 3 (reserved)"
- },
- {
"item_name": "opcode.notify",
"item_type": "integer",
"item_optional": true,
@@ -205,84 +197,12 @@
"item_description": "The number of total request counts whose opcode is update"
},
{
- "item_name": "opcode.reserved6",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 6",
- "item_description": "The number of total request counts whose opcode is 6 (reserved)"
- },
- {
- "item_name": "opcode.reserved7",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 7",
- "item_description": "The number of total request counts whose opcode is 7 (reserved)"
- },
- {
- "item_name": "opcode.reserved8",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 8",
- "item_description": "The number of total request counts whose opcode is 8 (reserved)"
- },
- {
- "item_name": "opcode.reserved9",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 9",
- "item_description": "The number of total request counts whose opcode is 9 (reserved)"
- },
- {
- "item_name": "opcode.reserved10",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 10",
- "item_description": "The number of total request counts whose opcode is 10 (reserved)"
- },
- {
- "item_name": "opcode.reserved11",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 11",
- "item_description": "The number of total request counts whose opcode is 11 (reserved)"
- },
- {
- "item_name": "opcode.reserved12",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 12",
- "item_description": "The number of total request counts whose opcode is 12 (reserved)"
- },
- {
- "item_name": "opcode.reserved13",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 13",
- "item_description": "The number of total request counts whose opcode is 13 (reserved)"
- },
- {
- "item_name": "opcode.reserved14",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 14",
- "item_description": "The number of total request counts whose opcode is 14 (reserved)"
- },
- {
- "item_name": "opcode.reserved15",
+ "item_name": "opcode.other",
"item_type": "integer",
"item_optional": true,
"item_default": 0,
- "item_title": "Received requests opcode 15",
- "item_description": "The number of total request counts whose opcode is 15 (reserved)"
+ "item_title": "Received requests opcode other",
+ "item_description": "The number of total request counts whose opcode is other (not well-known)"
},
{
"item_name": "rcode.noerror",
@@ -373,52 +293,68 @@
"item_description": "The number of total responses with rcode 10 (NOTZONE)"
},
{
- "item_name": "rcode.reserved11",
+ "item_name": "rcode.badsigvers",
"item_type": "integer",
"item_optional": true,
"item_default": 0,
- "item_title": "Sent response with rcode 11",
- "item_description": "The number of total responses with rcode 11 (reserved)"
+ "item_title": "Sent 'EDNS version not implemented' response",
+ "item_description": "The number of total responses with rcode 16 (BADVERS)"
},
{
- "item_name": "rcode.reserved12",
+ "item_name": "rcode.badkey",
"item_type": "integer",
"item_optional": true,
"item_default": 0,
- "item_title": "Sent response with rcode 12",
- "item_description": "The number of total responses with rcode 12 (reserved)"
+ "item_title": "Sent 'Key not recognized' response",
+ "item_description": "The number of total responses with rcode 17 (BADKEY)"
},
{
- "item_name": "rcode.reserved13",
+ "item_name": "rcode.badtime",
"item_type": "integer",
"item_optional": true,
"item_default": 0,
- "item_title": "Sent response with rcode 13",
- "item_description": "The number of total responses with rcode 13 (reserved)"
+ "item_title": "Sent 'Signature out of time window' response",
+ "item_description": "The number of total responses with rcode 18 (BADTIME)"
},
{
- "item_name": "rcode.reserved14",
+ "item_name": "rcode.badmode",
"item_type": "integer",
"item_optional": true,
"item_default": 0,
- "item_title": "Sent response with rcode 14",
- "item_description": "The number of total responses with rcode 14 (reserved)"
+ "item_title": "Sent 'Bad TKEY Mode' response",
+ "item_description": "The number of total responses with rcode 19 (BADMODE)"
},
{
- "item_name": "rcode.reserved15",
+ "item_name": "rcode.badname",
"item_type": "integer",
"item_optional": true,
"item_default": 0,
- "item_title": "Sent response with rcode 15",
- "item_description": "The number of total responses with rcode 15 (reserved)"
+ "item_title": "Sent 'Duplicate key name' response",
+ "item_description": "The number of total responses with rcode 20 (BADNAME)"
},
{
- "item_name": "rcode.badvers",
+ "item_name": "rcode.badalg",
"item_type": "integer",
"item_optional": true,
"item_default": 0,
- "item_title": "Sent 'EDNS version not implemented' response",
- "item_description": "The number of total responses with rcode 16 (BADVERS)"
+ "item_title": "Sent 'Algorithm not supported' response",
+ "item_description": "The number of total responses with rcode 21 (BADALG)"
+ },
+ {
+ "item_name": "rcode.badtrunc",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'Bad Truncation' response",
+ "item_description": "The number of total responses with rcode 22 (BADTRUNC)"
+ },
+ {
+ "item_name": "rcode.other",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent responses with rcode other",
+ "item_description": "The number of total responses with rcode other (not well-known)"
}
]
}
diff --git a/src/bin/auth/auth_config.h b/src/bin/auth/auth_config.h
index 8e816a3..57fd270 100644
--- a/src/bin/auth/auth_config.h
+++ b/src/bin/auth/auth_config.h
@@ -18,8 +18,8 @@
#include <cc/data.h>
-#ifndef __CONFIG_H
-#define __CONFIG_H 1
+#ifndef CONFIG_H
+#define CONFIG_H 1
class AuthSrv;
@@ -195,7 +195,7 @@ void configureAuthServer(AuthSrv& server,
AuthConfigParser* createAuthConfigParser(AuthSrv& server,
const std::string& config_id);
-#endif // __CONFIG_H
+#endif // CONFIG_H
// Local Variables:
// mode: c++
diff --git a/src/bin/auth/auth_log.h b/src/bin/auth/auth_log.h
index 7fb3a2d..52b973e 100644
--- a/src/bin/auth/auth_log.h
+++ b/src/bin/auth/auth_log.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __AUTH_LOG__H
-#define __AUTH_LOG__H
+#ifndef AUTH_LOG_H
+#define AUTH_LOG_H
#include <log/macros.h>
#include <auth/auth_messages.h>
@@ -53,4 +53,4 @@ extern isc::log::Logger auth_logger;
} // namespace nsas
} // namespace isc
-#endif // __AUTH_LOG__H
+#endif // AUTH_LOG_H
diff --git a/src/bin/auth/auth_messages.mes b/src/bin/auth/auth_messages.mes
index bdbd2fd..221d122 100644
--- a/src/bin/auth/auth_messages.mes
+++ b/src/bin/auth/auth_messages.mes
@@ -61,6 +61,15 @@ the message.
A debug message, showing when the separate thread for maintaining data
source clients receives a command from the manager.
+% AUTH_DATASRC_CLIENTS_BUILDER_COMMAND_ERROR command execution failure: %1
+The separate thread for maintaining data source clients failed to complete a
+command given by the main thread. In most cases this is some kind of
+configuration or temporary error such as an attempt to load a non-existent
+zone or a temporary DB connection failure. So the event is just logged and
+the thread keeps running. In some rare cases, however, this may indicate an
+internal bug and it may be better to restart the entire program, so the log
+message should be carefully examined.
+
% AUTH_DATASRC_CLIENTS_BUILDER_FAILED data source builder thread stopped due to an exception: %1
The separate thread for maintaining data source clients has been
terminated due to some uncaught exception. When this happens, the
@@ -79,6 +88,11 @@ indicate some run time failure than program errors. As in the other
failure case, the thread terminates the entire process immediately
after logging this message.
+% AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE loaded zone %1/%2
+This debug message is issued when the separate thread for maintaining data
+source clients successfully loaded the named zone of the named class as a
+result of the 'loadzone' command.
+
% AUTH_DATASRC_CLIENTS_BUILDER_RECONFIGURE_CONFIG_ERROR Error in data source configuration: %1
The thread for maintaining data source clients has received a command to
reconfigure, but the parameter data (the new configuration) contains an
@@ -164,11 +178,6 @@ has requested the keyring holding TSIG keys from the configuration
database. It is issued during server startup is an indication that the
initialization is proceeding normally.
-% AUTH_LOAD_ZONE loaded zone %1/%2
-This debug message is issued during the processing of the 'loadzone' command
-when the authoritative server has successfully loaded the named zone of the
-named class.
-
% AUTH_MEM_DATASRC_DISABLED memory data source is disabled for class %1
This is a debug message reporting that the authoritative server has
discovered that the memory data source is disabled for the given class.
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index 157ae03..dca8fd0 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -85,6 +85,7 @@ using namespace isc::xfr;
using namespace isc::asiolink;
using namespace isc::asiodns;
using namespace isc::server_common::portconfig;
+using isc::auth::statistics::Counters;
namespace {
// A helper class for cleaning up message renderer.
@@ -260,7 +261,7 @@ public:
AbstractSession* xfrin_session_;
/// Query counters for statistics
- AuthCounters counters_;
+ Counters counters_;
/// Addresses we listen on
AddressList listen_addresses_;
@@ -285,27 +286,29 @@ public:
/// \brief Resume the server
///
- /// This is a wrapper call for DNSServer::resume(done), if 'done' is true,
- /// the Rcode set in the given Message is counted in the statistics
- /// counter.
+ /// This is a wrapper call for DNSServer::resume(done). Query/Response
+ /// statistics counters are incremented in this method.
///
/// This method is expected to be called by processMessage()
///
/// \param server The DNSServer as passed to processMessage()
/// \param message The response as constructed by processMessage()
- /// \param done If true, the Rcode from the given message is counted,
- /// this value is then passed to server->resume(bool)
+ /// \param stats_attrs Query/response attributes for statistics which is
+ /// not in \p messsage.
+ /// Note: This parameter is modified inside this method
+ /// to store whether the answer has been sent and
+ /// the response is truncated.
+ /// \param done If true, it indicates there is a response.
+ /// this value will be passed to server->resume(bool)
void resumeServer(isc::asiodns::DNSServer* server,
isc::dns::Message& message,
- bool done);
+ statistics::QRAttributes& stats_attrs,
+ const bool done);
private:
bool xfrout_connected_;
AbstractXfroutClient& xfrout_client_;
- /// Increment query counter
- void incCounter(const int protocol);
-
// validateStatistics
bool validateStatistics(isc::data::ConstElementPtr data) const;
@@ -494,6 +497,12 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
OutputBuffer& buffer, DNSServer* server)
{
InputBuffer request_buffer(io_message.getData(), io_message.getDataSize());
+ statistics::QRAttributes stats_attrs;
+
+ // statistics: check transport carrying the message (IP, transport)
+ stats_attrs.setQueryIPVersion(io_message.getRemoteEndpoint().getFamily());
+ stats_attrs.setQueryTransportProtocol(
+ io_message.getRemoteEndpoint().getProtocol());
// First, check the header part. If we fail even for the base header,
// just drop the message.
@@ -503,13 +512,13 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
// Ignore all responses.
if (message.getHeaderFlag(Message::HEADERFLAG_QR)) {
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_RESPONSE_RECEIVED);
- impl_->resumeServer(server, message, false);
+ impl_->resumeServer(server, message, stats_attrs, false);
return;
}
} catch (const Exception& ex) {
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_HEADER_PARSE_FAIL)
.arg(ex.what());
- impl_->resumeServer(server, message, false);
+ impl_->resumeServer(server, message, stats_attrs, false);
return;
}
@@ -520,13 +529,13 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_PACKET_PROTOCOL_ERROR)
.arg(error.getRcode().toText()).arg(error.what());
makeErrorMessage(impl_->renderer_, message, buffer, error.getRcode());
- impl_->resumeServer(server, message, true);
+ impl_->resumeServer(server, message, stats_attrs, true);
return;
} catch (const Exception& ex) {
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_PACKET_PARSE_ERROR)
.arg(ex.what());
makeErrorMessage(impl_->renderer_, message, buffer, Rcode::SERVFAIL());
- impl_->resumeServer(server, message, true);
+ impl_->resumeServer(server, message, stats_attrs, true);
return;
} // other exceptions will be handled at a higher layer.
@@ -549,21 +558,35 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
**impl_->keyring_));
tsig_error = tsig_context->verify(tsig_record, io_message.getData(),
io_message.getDataSize());
+ // statistics: check TSIG attributes
+ // SIG(0) is currently not implemented in Auth, but it is implemented
+ // in BIND 9. At the point we support it, the code to check if the
+ // signature is valid would be around here.
+ stats_attrs.setQuerySig(true, false,
+ tsig_error == TSIGError::NOERROR());
}
if (tsig_error != TSIGError::NOERROR()) {
makeErrorMessage(impl_->renderer_, message, buffer,
tsig_error.toRcode(), tsig_context);
- impl_->resumeServer(server, message, true);
+ impl_->resumeServer(server, message, stats_attrs, true);
return;
}
const Opcode opcode = message.getOpcode();
bool send_answer = true;
try {
- // update per opcode statistics counter. This can only be reliable
- // after TSIG check succeeds.
- impl_->counters_.inc(message.getOpcode());
+ // statistics: check EDNS
+ // note: This can only be reliable after TSIG check succeeds.
+ ConstEDNSPtr edns = message.getEDNS();
+ if (edns != NULL) {
+ stats_attrs.setQueryEDNS(true, edns->getVersion() == 0);
+ stats_attrs.setQueryDO(edns->getDNSSECAwareness());
+ }
+
+ // statistics: check OpCode
+ // note: This can only be reliable after TSIG check succeeds.
+ stats_attrs.setQueryOpCode(opcode.getCode());
if (opcode == Opcode::NOTIFY()) {
send_answer = impl_->processNotify(io_message, message, buffer,
@@ -605,7 +628,7 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_RESPONSE_FAILURE_UNKNOWN);
makeErrorMessage(impl_->renderer_, message, buffer, Rcode::SERVFAIL());
}
- impl_->resumeServer(server, message, send_answer);
+ impl_->resumeServer(server, message, stats_attrs, send_answer);
}
bool
@@ -622,9 +645,6 @@ AuthSrvImpl::processNormalQuery(const IOMessage& io_message, Message& message,
message.setHeaderFlag(Message::HEADERFLAG_AA);
message.setRcode(Rcode::NOERROR());
- // Increment query counter.
- incCounter(io_message.getSocket().getProtocol());
-
if (remote_edns) {
EDNSPtr local_edns = EDNSPtr(new EDNS());
local_edns->setDNSSECAwareness(dnssec_ok);
@@ -675,9 +695,6 @@ AuthSrvImpl::processXfrQuery(const IOMessage& io_message, Message& message,
OutputBuffer& buffer,
auto_ptr<TSIGContext> tsig_context)
{
- // Increment query counter.
- incCounter(io_message.getSocket().getProtocol());
-
if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_AXFR_UDP);
makeErrorMessage(renderer_, message, buffer, Rcode::FORMERR(),
@@ -810,19 +827,6 @@ AuthSrvImpl::processUpdate(const IOMessage& io_message) {
}
void
-AuthSrvImpl::incCounter(const int protocol) {
- // Increment query counter.
- if (protocol == IPPROTO_UDP) {
- counters_.inc(AuthCounters::SERVER_UDP_QUERY);
- } else if (protocol == IPPROTO_TCP) {
- counters_.inc(AuthCounters::SERVER_TCP_QUERY);
- } else {
- // unknown protocol
- isc_throw(Unexpected, "Unknown protocol: " << protocol);
- }
-}
-
-void
AuthSrvImpl::registerStatisticsValidator() {
counters_.registerStatisticsValidator(
boost::bind(&AuthSrvImpl::validateStatistics, this, _1));
@@ -839,10 +843,15 @@ AuthSrvImpl::validateStatistics(isc::data::ConstElementPtr data) const {
}
void
-AuthSrvImpl::resumeServer(DNSServer* server, Message& message, bool done) {
+AuthSrvImpl::resumeServer(DNSServer* server, Message& message,
+ statistics::QRAttributes& stats_attrs,
+ const bool done) {
if (done) {
- counters_.inc(message.getRcode());
+ stats_attrs.answerWasSent();
+ // isTruncated from MessageRenderer
+ stats_attrs.setResponseTruncated(renderer_.isTruncated());
}
+ counters_.inc(stats_attrs, message);
server->resume(done);
}
@@ -865,21 +874,6 @@ ConstElementPtr AuthSrv::getStatistics() const {
return (impl_->counters_.getStatistics());
}
-uint64_t
-AuthSrv::getCounter(const AuthCounters::ServerCounterType type) const {
- return (impl_->counters_.getCounter(type));
-}
-
-uint64_t
-AuthSrv::getCounter(const Opcode opcode) const {
- return (impl_->counters_.getCounter(opcode));
-}
-
-uint64_t
-AuthSrv::getCounter(const Rcode rcode) const {
- return (impl_->counters_.getCounter(rcode));
-}
-
const AddressList&
AuthSrv::getListenAddresses() const {
return (impl_->listen_addresses_);
diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h
index 2d53666..ebd3034 100644
--- a/src/bin/auth/auth_srv.h
+++ b/src/bin/auth/auth_srv.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __AUTH_SRV_H
-#define __AUTH_SRV_H 1
+#ifndef AUTH_SRV_H
+#define AUTH_SRV_H 1
#include <config/ccsession.h>
@@ -222,55 +222,11 @@ public:
/// \brief Returns statistics data
///
/// This function can throw an exception from
- /// AuthCounters::getStatistics().
+ /// Counters::getStatistics().
///
/// \return JSON format statistics data.
isc::data::ConstElementPtr getStatistics() const;
- /// \brief Get the value of counter in the AuthCounters.
- ///
- /// This function calls AuthCounters::getStatistics() and
- /// returns its return value.
- ///
- /// This function never throws an exception as far as
- /// AuthCounters::getStatistics() doesn't throw.
- ///
- /// Note: Currently this function is for testing purpose only.
- ///
- /// \param type Type of a counter to get the value of
- ///
- /// \return the value of the counter.
-
- uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
-
- /// \brief Get the value of per Opcode counter in the Auth Counters.
- ///
- /// This function calls AuthCounters::getCounter(isc::dns::Opcode) and
- /// returns its return value.
- ///
- /// \note This is a tentative interface as an attempt of experimentally
- /// supporting more statistics counters. This should eventually be more
- /// generalized. In any case, this method is mainly for testing.
- ///
- /// \throw None
- /// \param opcode The opcode of the counter to get the value of
- /// \return the value of the counter.
- uint64_t getCounter(const isc::dns::Opcode opcode) const;
-
- /// \brief Get the value of per Rcode counter in the Auth Counters.
- ///
- /// This function calls AuthCounters::getCounter(isc::dns::Rcode) and
- /// returns its return value.
- ///
- /// \note This is a tentative interface as an attempt of experimentally
- /// supporting more statistics counters. This should eventually be more
- /// generalized. In any case, this method is mainly for testing.
- ///
- /// \throw None
- /// \param rcode The rcode of the counter to get the value of
- /// \return the value of the counter.
- uint64_t getCounter(const isc::dns::Rcode rcode) const;
-
/**
* \brief Set and get the addresses we listen on.
*/
@@ -328,7 +284,7 @@ private:
isc::asiodns::DNSServiceBase* dnss_;
};
-#endif // __AUTH_SRV_H
+#endif // AUTH_SRV_H
// Local Variables:
// mode: c++
diff --git a/src/bin/auth/benchmarks/Makefile.am b/src/bin/auth/benchmarks/Makefile.am
index c525b66..27ddfc5 100644
--- a/src/bin/auth/benchmarks/Makefile.am
+++ b/src/bin/auth/benchmarks/Makefile.am
@@ -15,7 +15,7 @@ query_bench_SOURCES = query_bench.cc
query_bench_SOURCES += ../query.h ../query.cc
query_bench_SOURCES += ../auth_srv.h ../auth_srv.cc
query_bench_SOURCES += ../auth_config.h ../auth_config.cc
-query_bench_SOURCES += ../statistics.h ../statistics.cc
+query_bench_SOURCES += ../statistics.h ../statistics.cc ../statistics_items.h
query_bench_SOURCES += ../auth_log.h ../auth_log.cc
query_bench_SOURCES += ../datasrc_config.h ../datasrc_config.cc
@@ -34,7 +34,6 @@ query_bench_LDADD += $(top_builddir)/src/lib/nsas/libb10-nsas.la
query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
query_bench_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
query_bench_LDADD += $(top_builddir)/src/lib/asiodns/libb10-asiodns.la
-query_bench_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
query_bench_LDADD += $(top_builddir)/src/lib/util/threads/libb10-threads.la
query_bench_LDADD += $(SQLITE_LIBS)
diff --git a/src/bin/auth/command.cc b/src/bin/auth/command.cc
index 886fd6c..9fbfb42 100644
--- a/src/bin/auth/command.cc
+++ b/src/bin/auth/command.cc
@@ -176,51 +176,7 @@ public:
virtual ConstElementPtr exec(AuthSrv& server,
isc::data::ConstElementPtr args)
{
- if (args == NULL) {
- isc_throw(AuthCommandError, "Null argument");
- }
-
- ConstElementPtr class_elem = args->get("class");
- RRClass zone_class(class_elem ? RRClass(class_elem->stringValue()) :
- RRClass::IN());
-
- ConstElementPtr origin_elem = args->get("origin");
- if (!origin_elem) {
- isc_throw(AuthCommandError, "Zone origin is missing");
- }
- const Name origin(origin_elem->stringValue());
-
- DataSrcClientsMgr::Holder holder(server.getDataSrcClientsMgr());
- boost::shared_ptr<ConfigurableClientList> list =
- holder.findClientList(zone_class);
-
- if (!list) {
- isc_throw(AuthCommandError, "There's no client list for "
- "class " << zone_class);
- }
-
- switch (list->reload(origin)) {
- case ConfigurableClientList::ZONE_RELOADED:
- // Everything worked fine.
- LOG_DEBUG(auth_logger, DBG_AUTH_OPS, AUTH_LOAD_ZONE)
- .arg(zone_class).arg(origin);
- return (createAnswer());
- case ConfigurableClientList::ZONE_NOT_FOUND:
- isc_throw(AuthCommandError, "Zone " << origin << "/" <<
- zone_class << " was not found in any configured "
- "data source. Configure it first.");
- case ConfigurableClientList::ZONE_NOT_CACHED:
- isc_throw(AuthCommandError, "Zone " << origin << "/" <<
- zone_class << " is not served from memory, but "
- "directly from the data source. It is not possible "
- "to reload it into memory. Configure it to be cached "
- "first.");
- case ConfigurableClientList::CACHE_DISABLED:
- // This is an internal error. Auth server must have the cache
- // enabled.
- isc_throw(isc::Unexpected, "Cache disabled in client list of "
- "class " << zone_class);
- }
+ server.getDataSrcClientsMgr().loadZone(args);
return (createAnswer());
}
};
diff --git a/src/bin/auth/command.h b/src/bin/auth/command.h
index 7db5cd6..5058b81 100644
--- a/src/bin/auth/command.h
+++ b/src/bin/auth/command.h
@@ -16,8 +16,8 @@
#include <cc/data.h>
-#ifndef __COMMAND_H
-#define __COMMAND_H 1
+#ifndef COMMAND_H
+#define COMMAND_H 1
class AuthSrv;
@@ -54,7 +54,7 @@ isc::data::ConstElementPtr
execAuthServerCommand(AuthSrv& server, const std::string& command_id,
isc::data::ConstElementPtr args);
-#endif // __COMMAND_H
+#endif // COMMAND_H
// Local Variables:
// mode: c++
diff --git a/src/bin/auth/common.h b/src/bin/auth/common.h
index 0964217..908a7d1 100644
--- a/src/bin/auth/common.h
+++ b/src/bin/auth/common.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __COMMON_H
-#define __COMMON_H 1
+#ifndef COMMON_H
+#define COMMON_H 1
#include <stdexcept>
#include <string>
@@ -62,7 +62,7 @@ extern const char* const AUTH_NAME;
/// This is sent to interested modules (currently only b10-ddns)
extern const char* const AUTH_STARTED_NOTIFICATION;
-#endif // __COMMON_H
+#endif // COMMON_H
// Local Variables:
// mode: c++
diff --git a/src/bin/auth/datasrc_clients_mgr.h b/src/bin/auth/datasrc_clients_mgr.h
index 48bae81..38bf162 100644
--- a/src/bin/auth/datasrc_clients_mgr.h
+++ b/src/bin/auth/datasrc_clients_mgr.h
@@ -27,6 +27,7 @@
#include <datasrc/data_source.h>
#include <datasrc/client_list.h>
+#include <datasrc/memory/zone_writer.h>
#include <auth/auth_log.h>
#include <auth/datasrc_config.h>
@@ -37,12 +38,26 @@
#include <boost/noncopyable.hpp>
#include <exception>
+#include <cassert>
#include <list>
#include <utility>
namespace isc {
namespace auth {
+/// \brief An exception that is thrown if initial checks for a command fail
+///
+/// This is raised *before* the command to the thread is constructed and
+/// sent, so the application can still handle them (and therefore it is
+/// public, as opposed to InternalCommandError).
+///
+/// And example of its use is currently in loadZone().
+class CommandError : public isc::Exception {
+public:
+ CommandError(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
namespace datasrc_clientmgr_internal {
// This namespace is essentially private for DataSrcClientsMgr(Base) and
// DataSrcClientsBuilder(Base). This is exposed in the public header
@@ -55,6 +70,9 @@ enum CommandID {
RECONFIGURE, ///< Reconfigure the datasource client lists,
/// the argument to the command is the full new
/// datasources configuration.
+ LOADZONE, ///< Load a new version of zone into a memory,
+ /// the argument to the command is a map containing 'class'
+ /// and 'origin' elements, both should have been validated.
SHUTDOWN, ///< Shutdown the builder; no argument
NUM_COMMANDS
};
@@ -234,6 +252,60 @@ public:
clients_map_ = new_lists;
}
+ /// \brief Instruct internal thread to (re)load a zone
+ ///
+ /// \param args Element argument that should be a map of the form
+ /// { "class": "IN", "origin": "example.com" }
+ /// (but class is optional and will default to IN)
+ ///
+ /// \exception CommandError if the args value is null, or not in
+ /// the expected format, or contains
+ /// a bad origin or class string
+ void
+ loadZone(data::ConstElementPtr args) {
+ if (!args) {
+ isc_throw(CommandError, "loadZone argument empty");
+ }
+ if (args->getType() != isc::data::Element::map) {
+ isc_throw(CommandError, "loadZone argument not a map");
+ }
+ if (!args->contains("origin")) {
+ isc_throw(CommandError,
+ "loadZone argument has no 'origin' value");
+ }
+ // Also check if it really is a valid name
+ try {
+ dns::Name(args->get("origin")->stringValue());
+ } catch (const isc::Exception& exc) {
+ isc_throw(CommandError, "bad origin: " << exc.what());
+ }
+
+ if (args->get("origin")->getType() != data::Element::string) {
+ isc_throw(CommandError,
+ "loadZone argument 'origin' value not a string");
+ }
+ if (args->contains("class")) {
+ if (args->get("class")->getType() != data::Element::string) {
+ isc_throw(CommandError,
+ "loadZone argument 'class' value not a string");
+ }
+ // Also check if it is a valid class
+ try {
+ dns::RRClass(args->get("class")->stringValue());
+ } catch (const isc::Exception& exc) {
+ isc_throw(CommandError, "bad class: " << exc.what());
+ }
+ }
+
+ // Note: we could do some more advanced checks here,
+ // e.g. check if the zone is known at all in the configuration.
+ // For now these are skipped, but one obvious way to
+ // implement it would be to factor out the code from
+ // the start of doLoadZone(), and call it here too
+
+ sendCommand(datasrc_clientmgr_internal::LOADZONE, args);
+ }
+
private:
// This is expected to be called at the end of the destructor. It
// actually does nothing, but provides a customization point for
@@ -290,14 +362,27 @@ namespace datasrc_clientmgr_internal {
/// threads or locks.
template <typename MutexType, typename CondVarType>
class DataSrcClientsBuilderBase : boost::noncopyable {
+private:
+ typedef std::map<dns::RRClass,
+ boost::shared_ptr<datasrc::ConfigurableClientList> >
+ ClientListsMap;
+
public:
+ /// \brief Internal errors in handling commands.
+ ///
+ /// This exception is expected to be caught within the
+ /// \c DataSrcClientsBuilder implementation, but is defined as public
+ /// so tests can be checked it.
+ class InternalCommandError : public isc::Exception {
+ public:
+ InternalCommandError(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+ };
+
/// \brief Constructor.
///
/// It simply sets up a local copy of shared data with the manager.
///
- /// Note: this will take actual set (map) of data source clients and
- /// a mutex object for it in #2210 or #2212.
- ///
/// \throw None
DataSrcClientsBuilderBase(std::list<Command>* command_queue,
CondVarType* cond, MutexType* queue_mutex,
@@ -365,6 +450,11 @@ private:
}
}
+ void doLoadZone(const isc::data::ConstElementPtr& arg);
+ boost::shared_ptr<datasrc::memory::ZoneWriter> getZoneWriter(
+ datasrc::ConfigurableClientList& client_list,
+ const dns::RRClass& rrclass, const dns::Name& origin);
+
// The following are shared with the manager
std::list<Command>* command_queue_;
CondVarType* cond_;
@@ -397,7 +487,13 @@ DataSrcClientsBuilderBase<MutexType, CondVarType>::run() {
} // the lock is released here.
while (keep_running && !current_commands.empty()) {
- keep_running = handleCommand(current_commands.front());
+ try {
+ keep_running = handleCommand(current_commands.front());;
+ } catch (const InternalCommandError& e) {
+ LOG_ERROR(auth_logger,
+ AUTH_DATASRC_CLIENTS_BUILDER_COMMAND_ERROR).
+ arg(e.what());
+ }
current_commands.pop_front();
}
}
@@ -426,7 +522,7 @@ DataSrcClientsBuilderBase<MutexType, CondVarType>::handleCommand(
}
const boost::array<const char*, NUM_COMMANDS> command_desc = {
- {"NOOP", "RECONFIGURE", "SHUTDOWN"}
+ {"NOOP", "RECONFIGURE", "LOADZONE", "SHUTDOWN"}
};
LOG_DEBUG(auth_logger, DBGLVL_TRACE_BASIC,
AUTH_DATASRC_CLIENTS_BUILDER_COMMAND).arg(command_desc.at(cid));
@@ -434,6 +530,9 @@ DataSrcClientsBuilderBase<MutexType, CondVarType>::handleCommand(
case RECONFIGURE:
doReconfigure(command.second);
break;
+ case LOADZONE:
+ doLoadZone(command.second);
+ break;
case SHUTDOWN:
return (false);
case NOOP:
@@ -444,6 +543,103 @@ DataSrcClientsBuilderBase<MutexType, CondVarType>::handleCommand(
}
return (true);
}
+
+template <typename MutexType, typename CondVarType>
+void
+DataSrcClientsBuilderBase<MutexType, CondVarType>::doLoadZone(
+ const isc::data::ConstElementPtr& arg)
+{
+ // We assume some basic level validation as this method can only be
+ // called via the manager in practice. manager is expected to do the
+ // minimal validation.
+ assert(arg);
+ assert(arg->get("origin"));
+
+ // TODO: currently, we hardcode IN as the default for the optional
+ // 'class' argument. We should really derive this from the specification,
+ // but at the moment the config/command API does not allow that to be
+ // done easily. Once that is in place (tickets have yet to be created,
+ // as we need to do a tiny bit of design work for that), this
+ // code can be replaced with the original part:
+ // assert(arg->get("class"));
+ // const dns::RRClass(arg->get("class")->stringValue());
+ isc::data::ConstElementPtr class_elem = arg->get("class");
+ const dns::RRClass rrclass(class_elem ?
+ dns::RRClass(class_elem->stringValue()) :
+ dns::RRClass::IN());
+ const dns::Name origin(arg->get("origin")->stringValue());
+ ClientListsMap::iterator found = (*clients_map_)->find(rrclass);
+ if (found == (*clients_map_)->end()) {
+ isc_throw(InternalCommandError, "failed to load a zone " << origin <<
+ "/" << rrclass << ": not configured for the class");
+ }
+
+ boost::shared_ptr<datasrc::ConfigurableClientList> client_list =
+ found->second;
+ assert(client_list);
+
+ try {
+ boost::shared_ptr<datasrc::memory::ZoneWriter> zwriter =
+ getZoneWriter(*client_list, rrclass, origin);
+
+ zwriter->load(); // this can take time but doesn't cause a race
+ { // install() can cause a race and must be in a critical section
+ typename MutexType::Locker locker(*map_mutex_);
+ zwriter->install();
+ }
+ LOG_DEBUG(auth_logger, DBG_AUTH_OPS,
+ AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE)
+ .arg(origin).arg(rrclass);
+
+ // same as load(). We could let the destructor do it, but do it
+ // ourselves explicitly just in case.
+ zwriter->cleanup();
+ } catch (const InternalCommandError& ex) {
+ throw; // this comes from getZoneWriter. just let it go through.
+ } catch (const isc::Exception& ex) {
+ // We catch our internal exceptions (which will be just ignored) and
+ // propagated others (which should generally be considered fatal and
+ // will make the thread terminate)
+ isc_throw(InternalCommandError, "failed to load a zone " << origin <<
+ "/" << rrclass << ": error occurred in reload: " <<
+ ex.what());
+ }
+}
+
+// A dedicated subroutine of doLoadZone(). Separated just for keeping the
+// main method concise.
+template <typename MutexType, typename CondVarType>
+boost::shared_ptr<datasrc::memory::ZoneWriter>
+DataSrcClientsBuilderBase<MutexType, CondVarType>::getZoneWriter(
+ datasrc::ConfigurableClientList& client_list,
+ const dns::RRClass& rrclass, const dns::Name& origin)
+{
+ const datasrc::ConfigurableClientList::ZoneWriterPair writerpair =
+ client_list.getCachedZoneWriter(origin);
+
+ switch (writerpair.first) {
+ case datasrc::ConfigurableClientList::ZONE_SUCCESS:
+ assert(writerpair.second);
+ return (writerpair.second);
+ case datasrc::ConfigurableClientList::ZONE_NOT_FOUND:
+ isc_throw(InternalCommandError, "failed to load zone " << origin
+ << "/" << rrclass << ": not found in any configured "
+ "data source.");
+ case datasrc::ConfigurableClientList::ZONE_NOT_CACHED:
+ isc_throw(InternalCommandError, "failed to load zone " << origin
+ << "/" << rrclass << ": not served from memory");
+ case datasrc::ConfigurableClientList::CACHE_DISABLED:
+ // This is an internal error. Auth server must have the cache
+ // enabled.
+ isc_throw(InternalCommandError, "failed to load zone " << origin
+ << "/" << rrclass << ": internal failure, in-memory cache "
+ "is somehow disabled");
+ }
+
+ // all cases above should either return or throw, but some compilers
+ // still need a return statement
+ return (boost::shared_ptr<datasrc::memory::ZoneWriter>());
+}
} // namespace datasrc_clientmgr_internal
/// \brief Shortcut type for normal data source clients manager.
diff --git a/src/bin/auth/datasrc_config.h b/src/bin/auth/datasrc_config.h
index 77a4177..1723161 100644
--- a/src/bin/auth/datasrc_config.h
+++ b/src/bin/auth/datasrc_config.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef DATASRC_CONFIG_H
-#define DATASRC_CONFIG_H
+#ifndef AUTH_DATASRC_CONFIG_H
+#define AUTH_DATASRC_CONFIG_H
#include <cc/data.h>
#include <datasrc/client_list.h>
@@ -75,7 +75,7 @@ configureDataSourceGeneric(const isc::data::ConstElementPtr& config) {
isc::datasrc::ClientListMapPtr
configureDataSource(const isc::data::ConstElementPtr& config);
-#endif // DATASRC_CONFIG_H
+#endif // AUTH_DATASRC_CONFIG_H
// Local Variables:
// mode: c++
diff --git a/src/bin/auth/statistics.cc b/src/bin/auth/statistics.cc
index 2d5f336..b310b23 100644
--- a/src/bin/auth/statistics.cc
+++ b/src/bin/auth/statistics.cc
@@ -13,9 +13,11 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <auth/statistics.h>
+#include <auth/statistics_items.h>
#include <auth/auth_log.h>
#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <cc/data.h>
#include <cc/session.h>
@@ -32,107 +34,206 @@
#include <boost/noncopyable.hpp>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
using namespace isc::dns;
using namespace isc::auth;
using namespace isc::statistics;
-// TODO: We need a namespace ("auth_server"?) to hold
-// AuthSrv and AuthCounters.
+namespace isc {
+namespace auth {
+namespace statistics {
// TODO: Make use of wrappers like isc::dns::Opcode
// for counter item type.
-class AuthCountersImpl : boost::noncopyable {
+class CountersImpl : boost::noncopyable {
public:
- AuthCountersImpl();
- ~AuthCountersImpl();
- void inc(const AuthCounters::ServerCounterType type);
- void inc(const Opcode opcode) {
- opcode_counter_.inc(opcode.getCode());
- }
- void inc(const Rcode rcode) {
- rcode_counter_.inc(rcode.getCode());
- }
- void inc(const std::string& zone,
- const AuthCounters::PerZoneCounterType type);
+ CountersImpl();
+ ~CountersImpl();
+ void inc(const QRAttributes& qrattrs, const Message& response);
isc::data::ConstElementPtr getStatistics() const;
- void registerStatisticsValidator
- (AuthCounters::validator_type validator);
- // Currently for testing purpose only
- uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
- uint64_t getCounter(const Opcode opcode) const {
- return (opcode_counter_.get(opcode.getCode()));
- }
- uint64_t getCounter(const Rcode rcode) const {
- return (rcode_counter_.get(rcode.getCode()));
- }
+ void registerStatisticsValidator(Counters::validator_type validator);
private:
- Counter server_counter_;
- Counter opcode_counter_;
- static const size_t NUM_OPCODES = 16;
- Counter rcode_counter_;
- static const size_t NUM_RCODES = 17;
- CounterDictionary per_zone_counter_;
- AuthCounters::validator_type validator_;
+ // counter for query/response
+ Counter server_qr_counter_;
+ // set of counters for zones
+ CounterDictionary zone_qr_counters_;
+ // validator
+ Counters::validator_type validator_;
};
-AuthCountersImpl::AuthCountersImpl() :
- // initialize counter
- // size of server_counter_: AuthCounters::SERVER_COUNTER_TYPES
- // size of per_zone_counter_: AuthCounters::PER_ZONE_COUNTER_TYPES
- server_counter_(AuthCounters::SERVER_COUNTER_TYPES),
- opcode_counter_(NUM_OPCODES), rcode_counter_(NUM_RCODES),
- per_zone_counter_(AuthCounters::PER_ZONE_COUNTER_TYPES)
-{
- per_zone_counter_.addElement("_SERVER_");
-}
+CountersImpl::CountersImpl() :
+ // size of server_qr_counter_, zone_qr_counters_: QR_COUNTER_TYPES
+ server_qr_counter_(QR_COUNTER_TYPES),
+ zone_qr_counters_(QR_COUNTER_TYPES),
+ validator_()
+{}
-AuthCountersImpl::~AuthCountersImpl()
+CountersImpl::~CountersImpl()
{}
void
-AuthCountersImpl::inc(const AuthCounters::ServerCounterType type) {
- server_counter_.inc(type);
-}
+CountersImpl::inc(const QRAttributes& qrattrs, const Message& response) {
+ // protocols carrying request
+ if (qrattrs.req_ip_version_ == AF_INET) {
+ server_qr_counter_.inc(QR_REQUEST_IPV4);
+ } else if (qrattrs.req_ip_version_ == AF_INET6) {
+ server_qr_counter_.inc(QR_REQUEST_IPV6);
+ }
+ if (qrattrs.req_transport_protocol_ == IPPROTO_UDP) {
+ server_qr_counter_.inc(QR_REQUEST_UDP);
+ } else if (qrattrs.req_transport_protocol_ == IPPROTO_TCP) {
+ server_qr_counter_.inc(QR_REQUEST_TCP);
+ }
-void
-AuthCountersImpl::inc(const std::string& zone,
- const AuthCounters::PerZoneCounterType type)
-{
- per_zone_counter_[zone].inc(type);
+ // query TSIG
+ if (qrattrs.req_is_tsig_) {
+ server_qr_counter_.inc(QR_REQUEST_TSIG);
+ }
+ if (qrattrs.req_is_sig0_) {
+ server_qr_counter_.inc(QR_REQUEST_SIG0);
+ }
+ if (qrattrs.req_is_badsig_) {
+ server_qr_counter_.inc(QR_REQUEST_BADSIG);
+ // If signature validation is failed, no other attributes are reliable
+ return;
+ }
+
+ // query EDNS
+ if (qrattrs.req_is_edns_0_) {
+ server_qr_counter_.inc(QR_REQUEST_EDNS0);
+ }
+ if (qrattrs.req_is_edns_badver_) {
+ server_qr_counter_.inc(QR_REQUEST_BADEDNSVER);
+ }
+
+ // query DNSSEC
+ if (qrattrs.req_is_dnssec_ok_) {
+ server_qr_counter_.inc(QR_REQUEST_DNSSEC_OK);
+ }
+
+ // QTYPE
+ unsigned int qtype_type = QR_QTYPE_OTHER;
+ const QuestionIterator qiter = response.beginQuestion();
+ if (qiter != response.endQuestion()) {
+ // get the first and only question section and
+ // get the qtype code
+ const unsigned int qtype = (*qiter)->getType().getCode();
+ if (qtype < 258) {
+ // qtype 0..257: lookup qtype-countertype table
+ qtype_type = QRQTypeToQRCounterType[qtype];
+ } else if (qtype < 32768) {
+ // qtype 258..32767: (Unassigned)
+ qtype_type = QR_QTYPE_OTHER;
+ } else if (qtype < 32770) {
+ // qtype 32768..32769: TA and DLV
+ qtype_type = QR_QTYPE_TA + (qtype - 32768);
+ } else {
+ // qtype 32770..65535: (Unassigned, Private use, Reserved)
+ qtype_type = QR_QTYPE_OTHER;
+ }
+ }
+ server_qr_counter_.inc(qtype_type);
+ // OPCODE
+ server_qr_counter_.inc(QROpCodeToQRCounterType[qrattrs.req_opcode_]);
+
+ // response
+ if (qrattrs.answer_sent_) {
+ // responded
+ server_qr_counter_.inc(QR_RESPONSE);
+
+ // response truncated
+ if (qrattrs.res_is_truncated_) {
+ server_qr_counter_.inc(QR_RESPONSE_TRUNCATED);
+ }
+
+ // response EDNS
+ ConstEDNSPtr response_edns = response.getEDNS();
+ if (response_edns != NULL && response_edns->getVersion() == 0) {
+ server_qr_counter_.inc(QR_RESPONSE_EDNS0);
+ }
+
+ // response TSIG
+ if (qrattrs.req_is_tsig_) {
+ // assume response is TSIG signed if request is TSIG signed
+ server_qr_counter_.inc(QR_RESPONSE_TSIG);
+ }
+
+ // response SIG(0) is currently not implemented
+
+ // RCODE
+ const unsigned int rcode = response.getRcode().getCode();
+ unsigned int rcode_type = QR_RCODE_OTHER;
+ if (rcode < 23) {
+ // rcode 0..22: lookup rcode-countertype table
+ rcode_type = QRRCodeToQRCounterType[rcode];
+ } else {
+ // opcode larger than 22 is reserved or unassigned
+ rcode_type = QR_RCODE_OTHER;
+ }
+ server_qr_counter_.inc(rcode_type);
+
+ // compound attributes
+ const unsigned int answer_rrs =
+ response.getRRCount(Message::SECTION_ANSWER);
+ const bool is_aa_set = response.getHeaderFlag(Message::HEADERFLAG_AA);
+
+ if (is_aa_set) {
+ // QryAuthAns
+ server_qr_counter_.inc(QR_QRYAUTHANS);
+ } else {
+ // QryNoAuthAns
+ server_qr_counter_.inc(QR_QRYNOAUTHANS);
+ }
+
+ if (rcode == Rcode::NOERROR_CODE) {
+ if (answer_rrs > 0) {
+ // QrySuccess
+ server_qr_counter_.inc(QR_QRYSUCCESS);
+ } else {
+ if (is_aa_set) {
+ // QryNxrrset
+ server_qr_counter_.inc(QR_QRYNXRRSET);
+ } else {
+ // QryReferral
+ server_qr_counter_.inc(QR_QRYREFERRAL);
+ }
+ }
+ } else if (rcode == Rcode::REFUSED_CODE) {
+ // AuthRej
+ server_qr_counter_.inc(QR_QRYREJECT);
+ }
+ }
}
isc::data::ConstElementPtr
-AuthCountersImpl::getStatistics() const {
+CountersImpl::getStatistics() const {
std::stringstream statistics_string;
statistics_string << "{ \"queries.udp\": "
- << server_counter_.get(AuthCounters::SERVER_UDP_QUERY)
+ << server_qr_counter_.get(QR_REQUEST_UDP)
<< ", \"queries.tcp\": "
- << server_counter_.get(AuthCounters::SERVER_TCP_QUERY);
+ << server_qr_counter_.get(QR_REQUEST_TCP);
// Insert non 0 Opcode counters.
- for (int i = 0; i < NUM_OPCODES; ++i) {
- const Counter::Type counter = opcode_counter_.get(i);
+ for (int i = QR_OPCODE_QUERY; i <= QR_OPCODE_OTHER; ++i) {
+ const Counter::Type counter = server_qr_counter_.get(i);
if (counter != 0) {
- // The counter item name should be derived lower-cased textual
- // representation of the code.
- std::string opcode_txt = Opcode(i).toText();
- std::transform(opcode_txt.begin(), opcode_txt.end(),
- opcode_txt.begin(), ::tolower);
- statistics_string << ", \"opcode." << opcode_txt << "\": "
- << counter;
+ statistics_string << ", \"" << "opcode." <<
+ QRCounterOpcode[i - QR_OPCODE_QUERY].name <<
+ "\": " << counter;
}
}
// Insert non 0 Rcode counters.
- for (int i = 0; i < NUM_RCODES; ++i) {
- const Counter::Type counter = rcode_counter_.get(i);
+ for (int i = QR_RCODE_NOERROR; i <= QR_RCODE_OTHER; ++i) {
+ const Counter::Type counter = server_qr_counter_.get(i);
if (counter != 0) {
- // The counter item name should be derived lower-cased textual
- // representation of the code.
- std::string rcode_txt = Rcode(i).toText();
- std::transform(rcode_txt.begin(), rcode_txt.end(),
- rcode_txt.begin(), ::tolower);
- statistics_string << ", \"rcode." << rcode_txt << "\": "
- << counter;
+ statistics_string << ", \"" << "rcode." <<
+ QRCounterRcode[i - QR_RCODE_NOERROR].name <<
+ "\": " << counter;
}
}
statistics_string << "}";
@@ -150,61 +251,34 @@ AuthCountersImpl::getStatistics() const {
}
void
-AuthCountersImpl::registerStatisticsValidator
- (AuthCounters::validator_type validator)
+CountersImpl::registerStatisticsValidator
+ (Counters::validator_type validator)
{
validator_ = validator;
}
-// Currently for testing purpose only
-uint64_t
-AuthCountersImpl::getCounter(const AuthCounters::ServerCounterType type) const {
- return (server_counter_.get(type));
-}
-
-AuthCounters::AuthCounters() : impl_(new AuthCountersImpl())
+Counters::Counters() : impl_(new CountersImpl())
{}
-AuthCounters::~AuthCounters() {}
+Counters::~Counters() {}
void
-AuthCounters::inc(const AuthCounters::ServerCounterType type) {
- impl_->inc(type);
-}
-
-void
-AuthCounters::inc(const Opcode opcode) {
- impl_->inc(opcode);
-}
-
-void
-AuthCounters::inc(const Rcode rcode) {
- impl_->inc(rcode);
+Counters::inc(const QRAttributes& qrattrs, const Message& response) {
+ impl_->inc(qrattrs, response);
}
isc::data::ConstElementPtr
-AuthCounters::getStatistics() const {
+Counters::getStatistics() const {
return (impl_->getStatistics());
}
-uint64_t
-AuthCounters::getCounter(const AuthCounters::ServerCounterType type) const {
- return (impl_->getCounter(type));
-}
-
-uint64_t
-AuthCounters::getCounter(const Opcode opcode) const {
- return (impl_->getCounter(opcode));
-}
-
-uint64_t
-AuthCounters::getCounter(const Rcode rcode) const {
- return (impl_->getCounter(rcode));
-}
-
void
-AuthCounters::registerStatisticsValidator
- (AuthCounters::validator_type validator) const
+Counters::registerStatisticsValidator
+ (Counters::validator_type validator) const
{
return (impl_->registerStatisticsValidator(validator));
}
+
+} // namespace statistics
+} // namespace auth
+} // namespace isc
diff --git a/src/bin/auth/statistics.h b/src/bin/auth/statistics.h
index 0ca8da4..d60c681 100644
--- a/src/bin/auth/statistics.h
+++ b/src/bin/auth/statistics.h
@@ -12,22 +12,136 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __STATISTICS_H
-#define __STATISTICS_H 1
+#ifndef STATISTICS_H
+#define STATISTICS_H 1
-#include <dns/opcode.h>
-#include <dns/rcode.h>
#include <cc/session.h>
#include <cc/data.h>
+#include <dns/message.h>
+
+#include <string>
+
#include <stdint.h>
#include <boost/scoped_ptr.hpp>
-class AuthCountersImpl;
+namespace isc {
+namespace auth {
+namespace statistics {
+
+class CountersImpl;
+
+class QRAttributes {
+/// \brief Query/Response attributes for statistics.
+///
+/// This class holds some attributes related to a query/response
+/// for statistics data collection.
+///
+/// This class does not have getter methods since it exposes private members
+/// to \c CountersImpl directly.
+friend class CountersImpl;
+private:
+ // request attributes
+ int req_ip_version_; // IP version
+ int req_transport_protocol_; // Transport layer protocol
+ int req_opcode_; // OpCode
+ bool req_is_edns_0_; // EDNS ver.0
+ bool req_is_edns_badver_; // other EDNS version
+ bool req_is_dnssec_ok_; // DO bit
+ bool req_is_tsig_; // signed with valid TSIG
+ bool req_is_sig0_; // signed with valid SIG(0)
+ bool req_is_badsig_; // signed but bad signature
+ // zone origin
+ std::string zone_origin_; // zone origin
+ // response attributes
+ bool answer_sent_; // DNS message has sent
+ bool res_is_truncated_; // DNS message is truncated
+public:
+ /// The constructor.
+ ///
+ /// This constructor is mostly exception free. But it may still throw
+ /// a standard exception if memory allocation fails inside the method.
+ ///
+ QRAttributes() {
+ reset();
+ };
+
+ /// The destructor.
+ ///
+ /// This method never throws an exception.
+ ///
+ ~QRAttributes() {};
+ /// \brief Set query opcode.
+ /// \throw None
+ void setQueryOpCode(const int opcode) {
+ req_opcode_ = opcode;
+ };
+ /// \brief Set IP version carrying a query.
+ /// \throw None
+ void setQueryIPVersion(const int ip_version) {
+ req_ip_version_ = ip_version;
+ };
+ /// \brief Set transport protocol carrying a query.
+ /// \throw None
+ void setQueryTransportProtocol(const int transport_protocol) {
+ req_transport_protocol_ = transport_protocol;
+ };
+ /// \brief Set query EDNS attributes.
+ /// \throw None
+ void setQueryEDNS(const bool is_edns_0, const bool is_edns_badver) {
+ req_is_edns_0_ = is_edns_0;
+ req_is_edns_badver_ = is_edns_badver;
+ };
+ /// \brief Set query DO bit.
+ /// \throw None
+ void setQueryDO(const bool is_dnssec_ok) {
+ req_is_dnssec_ok_ = is_dnssec_ok;
+ };
+ /// \brief Set query TSIG attributes.
+ /// \throw None
+ void setQuerySig(const bool is_tsig, const bool is_sig0,
+ const bool is_badsig)
+ {
+ req_is_tsig_ = is_tsig;
+ req_is_sig0_ = is_sig0;
+ req_is_badsig_ = is_badsig;
+ };
+ /// \brief Set zone origin.
+ /// \throw None
+ void setOrigin(const std::string& origin) {
+ zone_origin_ = origin;
+ };
+ /// \brief Set if the answer was sent.
+ /// \throw None
+ void answerWasSent() {
+ answer_sent_ = true;
+ };
+ /// \brief Set if the response is truncated.
+ /// \throw None
+ void setResponseTruncated(const bool is_truncated) {
+ res_is_truncated_ = is_truncated;
+ };
+ /// \brief Reset attributes.
+ /// \throw None
+ void reset() {
+ req_ip_version_ = 0;
+ req_transport_protocol_ = 0;
+ req_opcode_ = 0;
+ req_is_edns_0_ = false;
+ req_is_edns_badver_ = false;
+ req_is_dnssec_ok_ = false;
+ req_is_tsig_ = false;
+ req_is_sig0_ = false;
+ req_is_badsig_ = false;
+ zone_origin_.clear();
+ answer_sent_ = false;
+ res_is_truncated_ = false;
+ };
+};
/// \brief Set of query counters.
///
-/// \c AuthCounters is set of query counters class. It holds query counters
+/// \c Counters is set of query counters class. It holds query counters
/// and provides an interface to increment the counter of specified type
/// (e.g. UDP query, TCP query).
///
@@ -35,9 +149,7 @@ class AuthCountersImpl;
/// statistics module.
///
/// This class is designed to be a part of \c AuthSrv.
-/// Call \c inc() to increment a counter for specific type of query in
-/// the query processing function. use \c enum \c CounterType to specify
-/// the type of query.
+/// Call \c inc() to increment a counter for the query.
/// Call \c getStatistics() to answer statistics information to statistics
/// module with statistics_session, when the command \c getstats is received.
///
@@ -50,61 +162,31 @@ class AuthCountersImpl;
/// construction overhead of this approach should be acceptable.
///
/// \todo Hold counters for each query types (Notify, Axfr, Ixfr, Normal)
-/// \todo Consider overhead of \c AuthCounters::inc()
-class AuthCounters {
+/// \todo Consider overhead of \c Counters::inc()
+class Counters {
private:
- boost::scoped_ptr<AuthCountersImpl> impl_;
+ boost::scoped_ptr<CountersImpl> impl_;
public:
- // Enum for the type of counter
- enum ServerCounterType {
- SERVER_UDP_QUERY, ///< SERVER_UDP_QUERY: counter for UDP queries
- SERVER_TCP_QUERY, ///< SERVER_TCP_QUERY: counter for TCP queries
- SERVER_COUNTER_TYPES ///< The number of defined counters
- };
- enum PerZoneCounterType {
- ZONE_UDP_QUERY, ///< ZONE_UDP_QUERY: counter for UDP queries
- ZONE_TCP_QUERY, ///< ZONE_TCP_QUERY: counter for TCP queries
- PER_ZONE_COUNTER_TYPES ///< The number of defined counters
- };
/// The constructor.
///
/// This constructor is mostly exception free. But it may still throw
/// a standard exception if memory allocation fails inside the method.
///
- AuthCounters();
+ Counters();
/// The destructor.
///
/// This method never throws an exception.
///
- ~AuthCounters();
+ ~Counters();
- /// \brief Increment the counter specified by the parameter.
- ///
- /// \param type Type of a counter to increment.
+ /// \brief Increment counters according to the parameters.
///
- /// \throw std::out_of_range \a type is unknown.
- ///
- /// usage: counter.inc(AuthCounters::SERVER_UDP_QUERY);
- ///
- void inc(const ServerCounterType type);
-
- /// \brief Increment the counter of a per opcode counter.
- ///
- /// \note This is a tentative interface. See \c getCounter().
- ///
- /// \param opcode The opcode of the counter to increment.
+ /// \param qrattrs Query/Response attributes.
+ /// \param response DNS response message.
///
/// \throw None
- void inc(const isc::dns::Opcode opcode);
-
- /// \brief Increment the counter of a per rcode counter.
- ///
- /// \note This is a tentative interface. See \c getCounter().
///
- /// \param rcode The rcode of the counter to increment.
- ///
- /// \throw None
- void inc(const isc::dns::Rcode rcode);
+ void inc(const QRAttributes& qrattrs, const isc::dns::Message& response);
/// \brief Answers statistics counters to statistics module.
///
@@ -116,47 +198,6 @@ public:
///
isc::data::ConstElementPtr getStatistics() const;
- /// \brief Get the value of a counter in the AuthCounters.
- ///
- /// This function returns a value of the counter specified by \a type.
- /// This method never throws an exception.
- ///
- /// Note: Currently this function is for testing purpose only.
- ///
- /// \param type Type of a counter to get the value of
- ///
- /// \return the value of the counter specified by \a type.
- uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
-
- /// \brief Get the value of a per opcode counter.
- ///
- /// This method returns the value of the per opcode counter for the
- /// specified \c opcode.
- ///
- /// \note This is a tentative interface as an attempt of experimentally
- /// supporting more statistics counters. This should eventually be more
- /// generalized. In any case, this method is mainly for testing.
- ///
- /// \throw None
- /// \param opcode The opcode of the counter to get the value of
- /// \return the value of the counter.
- uint64_t getCounter(const isc::dns::Opcode opcode) const;
-
- /// \brief Get the value of a per rcode counter.
- ///
- /// This method returns the value of the per rcode counter for the
- /// specified \c rcode.
- ///
- /// \note As mentioned in getCounter(const isc::dns::Opcode opcode),
- /// This is a tentative interface as an attempt of experimentally
- /// supporting more statistics counters. This should eventually be more
- /// generalized. In any case, this method is mainly for testing.
- ///
- /// \throw None
- /// \param rcode The rcode of the counter to get the value of
- /// \return the value of the counter.
- uint64_t getCounter(const isc::dns::Rcode rcode) const;
-
/// \brief A type of validation function for the specification in
/// isc::config::ModuleSpec.
///
@@ -168,17 +209,21 @@ public:
validator_type;
/// \brief Register a function type of the statistics validation
- /// function for AuthCounters.
+ /// function for Counters.
///
/// This method never throws an exception.
///
/// \param validator A function type of the validation of
/// statistics specification.
///
- void registerStatisticsValidator(AuthCounters::validator_type validator) const;
+ void registerStatisticsValidator(Counters::validator_type validator) const;
};
-#endif // __STATISTICS_H
+} // namespace statistics
+} // namespace auth
+} // namespace isc
+
+#endif // STATISTICS_H
// Local Variables:
// mode: c++
diff --git a/src/bin/auth/statistics_items.h b/src/bin/auth/statistics_items.h
new file mode 100644
index 0000000..5839206
--- /dev/null
+++ b/src/bin/auth/statistics_items.h
@@ -0,0 +1,609 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __STATISTICS_ITEMS_H
+#define __STATISTICS_ITEMS_H 1
+
+/// This file defines a set of statistics items in Auth module for internal
+/// use. This file is intended to be included in statistics.cc.
+
+namespace {
+
+struct CounterTypeTree {
+ const char* const name;
+ const struct CounterTypeTree* const sub_tree;
+ const int counter_id;
+};
+
+// enum for query/response counters
+enum QRCounterType {
+ // Request Attributes
+ QR_REQUEST_IPV4, ///< Number of IPv4 requests received
+ QR_REQUEST_IPV6, ///< Number of IPv6 requests received
+ QR_REQUEST_EDNS0, ///< Number of requests with EDNS(0) received
+ QR_REQUEST_BADEDNSVER, ///< Number of requests with unsupported EDNS version received
+ QR_REQUEST_TSIG, ///< Number of requests with TSIG received
+ QR_REQUEST_SIG0, ///< Number of requests with SIG(0) received; not implemented in BIND 10
+ QR_REQUEST_BADSIG, ///< Number of requests with invalid TSIG or SIG(0) signature received
+ QR_REQUEST_UDP, ///< Number of UDP requests received
+ QR_REQUEST_TCP, ///< Number of TCP requests received
+ QR_REQUEST_DNSSEC_OK, ///< Number of requests with DO bit
+ // Request Opcodes
+ QR_OPCODE_QUERY, ///< Number of Opcode=QUERY requests received
+ QR_OPCODE_IQUERY, ///< Number of Opcode=IQUERY requests received
+ QR_OPCODE_STATUS, ///< Number of Opcode=STATUS requests received
+ QR_OPCODE_NOTIFY, ///< Number of Opcode=NOTIFY requests received
+ QR_OPCODE_UPDATE, ///< Number of Opcode=UPDATE requests received
+ QR_OPCODE_OTHER, ///< Number of requests in other OpCode received
+ // Query Types
+ QR_QTYPE_A, ///< Number of QTYPE = A queries received
+ QR_QTYPE_NS, ///< Number of QTYPE = NS queries received
+ QR_QTYPE_MD, ///< Number of QTYPE = MD queries received
+ QR_QTYPE_MF, ///< Number of QTYPE = MF queries received
+ QR_QTYPE_CNAME, ///< Number of QTYPE = CNAME queries received
+ QR_QTYPE_SOA, ///< Number of QTYPE = SOA queries received
+ QR_QTYPE_MB, ///< Number of QTYPE = MB queries received
+ QR_QTYPE_MG, ///< Number of QTYPE = MG queries received
+ QR_QTYPE_MR, ///< Number of QTYPE = MR queries received
+ QR_QTYPE_NULL, ///< Number of QTYPE = NULL queries received
+ QR_QTYPE_WKS, ///< Number of QTYPE = WKS queries received
+ QR_QTYPE_PTR, ///< Number of QTYPE = PTR queries received
+ QR_QTYPE_HINFO, ///< Number of QTYPE = HINFO queries received
+ QR_QTYPE_MINFO, ///< Number of QTYPE = MINFO queries received
+ QR_QTYPE_MX, ///< Number of QTYPE = MX queries received
+ QR_QTYPE_TXT, ///< Number of QTYPE = TXT queries received
+ QR_QTYPE_RP, ///< Number of QTYPE = RP queries received
+ QR_QTYPE_AFSDB, ///< Number of QTYPE = AFSDB queries received
+ QR_QTYPE_X25, ///< Number of QTYPE = X25 queries received
+ QR_QTYPE_ISDN, ///< Number of QTYPE = ISDN queries received
+ QR_QTYPE_RT, ///< Number of QTYPE = RT queries received
+ QR_QTYPE_NSAP, ///< Number of QTYPE = NSAP queries received
+ QR_QTYPE_NSAP_PTR, ///< Number of QTYPE = NSAP-PTR queries received
+ QR_QTYPE_SIG, ///< Number of QTYPE = SIG queries received
+ QR_QTYPE_KEY, ///< Number of QTYPE = KEY queries received
+ QR_QTYPE_PX, ///< Number of QTYPE = PX queries received
+ QR_QTYPE_GPOS, ///< Number of QTYPE = GPOS queries received
+ QR_QTYPE_AAAA, ///< Number of QTYPE = AAAA queries received
+ QR_QTYPE_LOC, ///< Number of QTYPE = LOC queries received
+ QR_QTYPE_NXT, ///< Number of QTYPE = NXT queries received
+ QR_QTYPE_EID, ///< Number of QTYPE = EID queries received
+ QR_QTYPE_NIMLOC, ///< Number of QTYPE = NIMLOC queries received
+ QR_QTYPE_SRV, ///< Number of QTYPE = SRV queries received
+ QR_QTYPE_ATMA, ///< Number of QTYPE = ATMA queries received
+ QR_QTYPE_NAPTR, ///< Number of QTYPE = NAPTR queries received
+ QR_QTYPE_KX, ///< Number of QTYPE = KX queries received
+ QR_QTYPE_CERT, ///< Number of QTYPE = CERT queries received
+ QR_QTYPE_A6, ///< Number of QTYPE = A6 queries received
+ QR_QTYPE_DNAME, ///< Number of QTYPE = DNAME queries received
+ QR_QTYPE_SINK, ///< Number of QTYPE = SINK queries received
+ QR_QTYPE_OPT, ///< Number of QTYPE = OPT queries received
+ QR_QTYPE_APL, ///< Number of QTYPE = APL queries received
+ QR_QTYPE_DS, ///< Number of QTYPE = DS queries received
+ QR_QTYPE_SSHFP, ///< Number of QTYPE = SSHFP queries received
+ QR_QTYPE_IPSECKEY, ///< Number of QTYPE = IPSECKEY queries received
+ QR_QTYPE_RRSIG, ///< Number of QTYPE = RRSIG queries received
+ QR_QTYPE_NSEC, ///< Number of QTYPE = NSEC queries received
+ QR_QTYPE_DNSKEY, ///< Number of QTYPE = DNSKEY queries received
+ QR_QTYPE_DHCID, ///< Number of QTYPE = DHCID queries received
+ QR_QTYPE_NSEC3, ///< Number of QTYPE = NSEC3 queries received
+ QR_QTYPE_NSEC3PARAM, ///< Number of QTYPE = NSEC3PARAM queries received
+ QR_QTYPE_HIP, ///< Number of QTYPE = HIP queries received
+ QR_QTYPE_NINFO, ///< Number of QTYPE = NINFO queries received
+ QR_QTYPE_RKEY, ///< Number of QTYPE = RKEY queries received
+ QR_QTYPE_TALINK, ///< Number of QTYPE = TALINK queries received
+ QR_QTYPE_SPF, ///< Number of QTYPE = SPF queries received
+ QR_QTYPE_UINFO, ///< Number of QTYPE = UINFO queries received
+ QR_QTYPE_UID, ///< Number of QTYPE = UID queries received
+ QR_QTYPE_GID, ///< Number of QTYPE = GID queries received
+ QR_QTYPE_UNSPEC, ///< Number of QTYPE = UNSPEC queries received
+ QR_QTYPE_TKEY, ///< Number of QTYPE = TKEY queries received
+ QR_QTYPE_TSIG, ///< Number of QTYPE = TSIG queries received
+ QR_QTYPE_IXFR, ///< Number of QTYPE = IXFR queries received
+ QR_QTYPE_AXFR, ///< Number of QTYPE = AXFR queries received
+ QR_QTYPE_MAILB, ///< Number of QTYPE = MAILB queries received
+ QR_QTYPE_MAILA, ///< Number of QTYPE = MAILA queries received
+ QR_QTYPE_URI, ///< Number of QTYPE = URI queries received
+ QR_QTYPE_CAA, ///< Number of QTYPE = CAA queries received
+ QR_QTYPE_TA, ///< Number of QTYPE = TA queries received
+ QR_QTYPE_DLV, ///< Number of QTYPE = DLV queries received
+ QR_QTYPE_OTHER, ///< Number of queries in other QTYPE received
+ // Respose Attributes
+ QR_RESPONSE, ///< Number of responses sent
+ QR_RESPONSE_TRUNCATED, ///< Number of truncated responses sent
+ QR_RESPONSE_EDNS0, ///< Number of responses with EDNS0; not implemented in BIND 10
+ QR_RESPONSE_TSIG, ///< Number of responses with TSIG
+ QR_RESPONSE_SIG0, ///< Number of responses with SIG(0); not implemented in BIND 10
+ QR_QRYSUCCESS, ///< Number of queries resulted in rcode = NOERROR and answer RR >= 1
+ QR_QRYAUTHANS, ///< Number of queries resulted in authoritative answer
+ QR_QRYNOAUTHANS, ///< Number of queries resulted in non-authoritative answer
+ QR_QRYREFERRAL, ///< Number of queries resulted in referral answer
+ QR_QRYNXRRSET, ///< Number of queries resulted in NOERROR but answer RR == 0
+ QR_QRYREJECT, ///< Number of queries rejected
+ // Response Rcodes
+ QR_RCODE_NOERROR, ///< Number of queries resulted in RCODE = 0 (NoError)
+ QR_RCODE_FORMERR, ///< Number of queries resulted in RCODE = 1 (FormErr)
+ QR_RCODE_SERVFAIL, ///< Number of queries resulted in RCODE = 2 (ServFail)
+ QR_RCODE_NXDOMAIN, ///< Number of queries resulted in RCODE = 3 (NXDomain)
+ QR_RCODE_NOTIMP, ///< Number of queries resulted in RCODE = 4 (NotImp)
+ QR_RCODE_REFUSED, ///< Number of queries resulted in RCODE = 5 (Refused)
+ QR_RCODE_YXDOMAIN, ///< Number of queries resulted in RCODE = 6 (YXDomain)
+ QR_RCODE_YXRRSET, ///< Number of queries resulted in RCODE = 7 (YXRRSet)
+ QR_RCODE_NXRRSET, ///< Number of queries resulted in RCODE = 8 (NXRRSet)
+ QR_RCODE_NOTAUTH, ///< Number of queries resulted in RCODE = 9 (NotAuth)
+ QR_RCODE_NOTZONE, ///< Number of queries resulted in RCODE = 10 (NotZone)
+ QR_RCODE_BADSIGVERS, ///< Number of queries resulted in RCODE = 16 (BADVERS, BADSIG)
+ QR_RCODE_BADKEY, ///< Number of queries resulted in RCODE = 17 (BADKEY)
+ QR_RCODE_BADTIME, ///< Number of queries resulted in RCODE = 18 (BADTIME)
+ QR_RCODE_BADMODE, ///< Number of queries resulted in RCODE = 19 (BADMODE)
+ QR_RCODE_BADNAME, ///< Number of queries resulted in RCODE = 20 (BADNAME)
+ QR_RCODE_BADALG, ///< Number of queries resulted in RCODE = 21 (BADALG)
+ QR_RCODE_BADTRUNC, ///< Number of queries resulted in RCODE = 22 (BADTRUNC)
+ QR_RCODE_OTHER, ///< Number of queries resulted in other RCODEs
+ // End of counter types
+ QR_COUNTER_TYPES ///< The number of defined counters
+};
+
+// item names for query/response counters
+const struct CounterTypeTree QRCounterRequest[] = {
+ { "v4", NULL, QR_REQUEST_IPV4 },
+ { "v6", NULL, QR_REQUEST_IPV6 },
+ { "edns0", NULL, QR_REQUEST_EDNS0 },
+ { "badednsver", NULL, QR_REQUEST_BADEDNSVER },
+ { "tsig", NULL, QR_REQUEST_TSIG },
+ { "sig0", NULL, QR_REQUEST_SIG0 },
+ { "badsig", NULL, QR_REQUEST_BADSIG },
+ { "udp", NULL, QR_REQUEST_UDP },
+ { "tcp", NULL, QR_REQUEST_TCP },
+ { "dnssec_ok", NULL, QR_REQUEST_DNSSEC_OK },
+ { NULL, NULL, -1 }
+};
+const struct CounterTypeTree QRCounterOpcode[] = {
+ { "query", NULL, QR_OPCODE_QUERY },
+ { "iquery", NULL, QR_OPCODE_IQUERY },
+ { "status", NULL, QR_OPCODE_STATUS },
+ { "notify", NULL, QR_OPCODE_NOTIFY },
+ { "update", NULL, QR_OPCODE_UPDATE },
+ { "other", NULL, QR_OPCODE_OTHER },
+ { NULL, NULL, -1 }
+};
+const struct CounterTypeTree QRCounterQtype[] = {
+ { "a", NULL, QR_QTYPE_A, },
+ { "ns", NULL, QR_QTYPE_NS },
+ { "md", NULL, QR_QTYPE_MD },
+ { "mf", NULL, QR_QTYPE_MF },
+ { "cname", NULL, QR_QTYPE_CNAME },
+ { "soa", NULL, QR_QTYPE_SOA },
+ { "mb", NULL, QR_QTYPE_MB },
+ { "mg", NULL, QR_QTYPE_MG },
+ { "mr", NULL, QR_QTYPE_MR },
+ { "null", NULL, QR_QTYPE_NULL },
+ { "wks", NULL, QR_QTYPE_WKS },
+ { "ptr", NULL, QR_QTYPE_PTR },
+ { "hinfo", NULL, QR_QTYPE_HINFO },
+ { "minfo", NULL, QR_QTYPE_MINFO },
+ { "mx", NULL, QR_QTYPE_MX },
+ { "txt", NULL, QR_QTYPE_TXT },
+ { "rp", NULL, QR_QTYPE_RP },
+ { "afsdb", NULL, QR_QTYPE_AFSDB },
+ { "x25", NULL, QR_QTYPE_X25 },
+ { "isdn", NULL, QR_QTYPE_ISDN },
+ { "rt", NULL, QR_QTYPE_RT },
+ { "nsap", NULL, QR_QTYPE_NSAP },
+ { "nsap-ptr", NULL, QR_QTYPE_NSAP_PTR },
+ { "sig", NULL, QR_QTYPE_SIG },
+ { "key", NULL, QR_QTYPE_KEY },
+ { "px", NULL, QR_QTYPE_PX },
+ { "gpos", NULL, QR_QTYPE_GPOS },
+ { "aaaa", NULL, QR_QTYPE_AAAA },
+ { "loc", NULL, QR_QTYPE_LOC },
+ { "nxt", NULL, QR_QTYPE_NXT },
+ { "eid", NULL, QR_QTYPE_EID },
+ { "nimloc", NULL, QR_QTYPE_NIMLOC },
+ { "srv", NULL, QR_QTYPE_SRV },
+ { "atma", NULL, QR_QTYPE_ATMA },
+ { "naptr", NULL, QR_QTYPE_NAPTR },
+ { "kx", NULL, QR_QTYPE_KX },
+ { "cert", NULL, QR_QTYPE_CERT },
+ { "a6", NULL, QR_QTYPE_A6 },
+ { "dname", NULL, QR_QTYPE_DNAME },
+ { "sink", NULL, QR_QTYPE_SINK },
+ { "opt", NULL, QR_QTYPE_OPT },
+ { "apl", NULL, QR_QTYPE_APL },
+ { "ds", NULL, QR_QTYPE_DS },
+ { "sshfp", NULL, QR_QTYPE_SSHFP },
+ { "ipseckey", NULL, QR_QTYPE_IPSECKEY },
+ { "rrsig", NULL, QR_QTYPE_RRSIG },
+ { "nsec", NULL, QR_QTYPE_NSEC },
+ { "dnskey", NULL, QR_QTYPE_DNSKEY },
+ { "dhcid", NULL, QR_QTYPE_DHCID },
+ { "nsec3", NULL, QR_QTYPE_NSEC3 },
+ { "nsec3param", NULL, QR_QTYPE_NSEC3PARAM },
+ { "hip", NULL, QR_QTYPE_HIP },
+ { "ninfo", NULL, QR_QTYPE_NINFO },
+ { "rkey", NULL, QR_QTYPE_RKEY },
+ { "talink", NULL, QR_QTYPE_TALINK },
+ { "spf", NULL, QR_QTYPE_SPF },
+ { "uinfo", NULL, QR_QTYPE_UINFO },
+ { "uid", NULL, QR_QTYPE_UID },
+ { "gid", NULL, QR_QTYPE_GID },
+ { "unspec", NULL, QR_QTYPE_UNSPEC },
+ { "tkey", NULL, QR_QTYPE_TKEY },
+ { "tsig", NULL, QR_QTYPE_TSIG },
+ { "ixfr", NULL, QR_QTYPE_IXFR },
+ { "axfr", NULL, QR_QTYPE_AXFR },
+ { "mailb", NULL, QR_QTYPE_MAILB },
+ { "maila", NULL, QR_QTYPE_MAILA },
+ { "uri", NULL, QR_QTYPE_URI },
+ { "caa", NULL, QR_QTYPE_CAA },
+ { "ta", NULL, QR_QTYPE_TA },
+ { "dlv", NULL, QR_QTYPE_DLV },
+ { "other", NULL, QR_QTYPE_OTHER },
+ { NULL, NULL, -1 }
+};
+const struct CounterTypeTree QRCounterResponse[] = {
+ { "truncated", NULL, QR_RESPONSE_TRUNCATED },
+ { "edns0", NULL, QR_RESPONSE_EDNS0 },
+ { "tsig", NULL, QR_RESPONSE_TSIG },
+ { "sig0", NULL, QR_RESPONSE_SIG0 },
+ { NULL, NULL, -1 }
+};
+const struct CounterTypeTree QRCounterRcode[] = {
+ { "noerror", NULL, QR_RCODE_NOERROR },
+ { "formerr", NULL, QR_RCODE_FORMERR },
+ { "servfail", NULL, QR_RCODE_SERVFAIL },
+ { "nxdomain", NULL, QR_RCODE_NXDOMAIN },
+ { "notimp", NULL, QR_RCODE_NOTIMP },
+ { "refused", NULL, QR_RCODE_REFUSED },
+ { "yxdomain", NULL, QR_RCODE_YXDOMAIN },
+ { "yxrrset", NULL, QR_RCODE_YXRRSET },
+ { "nxrrset", NULL, QR_RCODE_NXRRSET },
+ { "notauth", NULL, QR_RCODE_NOTAUTH },
+ { "notzone", NULL, QR_RCODE_NOTZONE },
+ { "badsigvers", NULL, QR_RCODE_BADSIGVERS },
+ { "badkey", NULL, QR_RCODE_BADKEY },
+ { "badtime", NULL, QR_RCODE_BADTIME },
+ { "badmode", NULL, QR_RCODE_BADMODE },
+ { "badname", NULL, QR_RCODE_BADNAME },
+ { "badalg", NULL, QR_RCODE_BADALG },
+ { "badtrunc", NULL, QR_RCODE_BADTRUNC },
+ { "other", NULL, QR_RCODE_OTHER },
+ { NULL, NULL, -1 }
+};
+const struct CounterTypeTree QRCounterTree[] = {
+ { "request", QRCounterRequest, -1 },
+ { "opcode", QRCounterOpcode, -1 },
+ { "qtype", QRCounterQtype, -1 },
+ { "responses", NULL, QR_RESPONSE },
+ { "response", QRCounterResponse, -1 },
+ { "qrysuccess", NULL, QR_QRYSUCCESS },
+ { "qryauthans", NULL, QR_QRYAUTHANS },
+ { "qrynoauthans", NULL, QR_QRYNOAUTHANS },
+ { "qryreferral", NULL, QR_QRYREFERRAL },
+ { "qrynxrrset", NULL, QR_QRYNXRRSET },
+ { "authqryrej", NULL, QR_QRYREJECT },
+ { "rcode", QRCounterRcode, -1 },
+ { NULL, NULL, -1 }
+};
+
+const int QROpCodeToQRCounterType[16] = {
+ QR_OPCODE_QUERY, // Opcode = 0: Query
+ QR_OPCODE_IQUERY, // Opcode = 1: Iquery
+ QR_OPCODE_STATUS, // Opcode = 2: STATUS
+ QR_OPCODE_OTHER, // Opcode = 3: (Unassigned)
+ QR_OPCODE_NOTIFY, // Opcode = 4: Notify
+ QR_OPCODE_UPDATE, // Opcode = 5: Update
+ QR_OPCODE_OTHER, // Opcode = 6: (Unassigned)
+ QR_OPCODE_OTHER, // Opcode = 7: (Unassigned)
+ QR_OPCODE_OTHER, // Opcode = 8: (Unassigned)
+ QR_OPCODE_OTHER, // Opcode = 9: (Unassigned)
+ QR_OPCODE_OTHER, // Opcode = 10: (Unassigned)
+ QR_OPCODE_OTHER, // Opcode = 11: (Unassigned)
+ QR_OPCODE_OTHER, // Opcode = 12: (Unassigned)
+ QR_OPCODE_OTHER, // Opcode = 13: (Unassigned)
+ QR_OPCODE_OTHER, // Opcode = 14: (Unassigned)
+ QR_OPCODE_OTHER // Opcode = 15: (Unassigned)
+};
+const int QRQTypeToQRCounterType[258] = {
+ QR_QTYPE_OTHER, // RRtype = 0: special use
+ QR_QTYPE_A, // RRtype = 1: A
+ QR_QTYPE_NS, // RRtype = 2: NS
+ QR_QTYPE_MD, // RRtype = 3: MD
+ QR_QTYPE_MF, // RRtype = 4: MF
+ QR_QTYPE_CNAME, // RRtype = 5: CNAME
+ QR_QTYPE_SOA, // RRtype = 6: SOA
+ QR_QTYPE_MB, // RRtype = 7: MB
+ QR_QTYPE_MG, // RRtype = 8: MG
+ QR_QTYPE_MR, // RRtype = 9: MR
+ QR_QTYPE_NULL, // RRtype = 10: NULL
+ QR_QTYPE_WKS, // RRtype = 11: WKS
+ QR_QTYPE_PTR, // RRtype = 12: PTR
+ QR_QTYPE_HINFO, // RRtype = 13: HINFO
+ QR_QTYPE_MINFO, // RRtype = 14: MINFO
+ QR_QTYPE_MX, // RRtype = 15: MX
+ QR_QTYPE_TXT, // RRtype = 16: TXT
+ QR_QTYPE_RP, // RRtype = 17: RP
+ QR_QTYPE_AFSDB, // RRtype = 18: AFSDB
+ QR_QTYPE_X25, // RRtype = 19: X25
+ QR_QTYPE_ISDN, // RRtype = 20: ISDN
+ QR_QTYPE_RT, // RRtype = 21: RT
+ QR_QTYPE_NSAP, // RRtype = 22: NSAP
+ QR_QTYPE_NSAP_PTR, // RRtype = 23: NSAP-PTR
+ QR_QTYPE_SIG, // RRtype = 24: SIG
+ QR_QTYPE_KEY, // RRtype = 25: KEY
+ QR_QTYPE_PX, // RRtype = 26: PX
+ QR_QTYPE_GPOS, // RRtype = 27: GPOS
+ QR_QTYPE_AAAA, // RRtype = 28: AAAA
+ QR_QTYPE_LOC, // RRtype = 29: LOC
+ QR_QTYPE_NXT, // RRtype = 30: NXT
+ QR_QTYPE_EID, // RRtype = 31: EID
+ QR_QTYPE_NIMLOC, // RRtype = 32: NIMLOC
+ QR_QTYPE_SRV, // RRtype = 33: SRV
+ QR_QTYPE_ATMA, // RRtype = 34: ATMA
+ QR_QTYPE_NAPTR, // RRtype = 35: NAPTR
+ QR_QTYPE_KX, // RRtype = 36: KX
+ QR_QTYPE_CERT, // RRtype = 37: CERT
+ QR_QTYPE_A6, // RRtype = 38: A6
+ QR_QTYPE_DNAME, // RRtype = 39: DNAME
+ QR_QTYPE_SINK, // RRtype = 40: SINK
+ QR_QTYPE_OPT, // RRtype = 41: OPT
+ QR_QTYPE_APL, // RRtype = 42: APL
+ QR_QTYPE_DS, // RRtype = 43: DS
+ QR_QTYPE_SSHFP, // RRtype = 44: SSHFP
+ QR_QTYPE_IPSECKEY, // RRtype = 45: IPSECKEY
+ QR_QTYPE_RRSIG, // RRtype = 46: RRSIG
+ QR_QTYPE_NSEC, // RRtype = 47: NSEC
+ QR_QTYPE_DNSKEY, // RRtype = 48: DNSKEY
+ QR_QTYPE_DHCID, // RRtype = 49: DHCID
+ QR_QTYPE_NSEC3, // RRtype = 50: NSEC3
+ QR_QTYPE_NSEC3PARAM, // RRtype = 51: NSEC3PARAM
+ QR_QTYPE_OTHER, // RRtype = 52: TLSA
+ QR_QTYPE_OTHER, // RRtype = 53: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 54: (Unassigned)
+ QR_QTYPE_HIP, // RRtype = 55: HIP
+ QR_QTYPE_NINFO, // RRtype = 56: NINFO
+ QR_QTYPE_RKEY, // RRtype = 57: RKEY
+ QR_QTYPE_TALINK, // RRtype = 58: TALINK
+ QR_QTYPE_OTHER, // RRtype = 59: CDS
+ QR_QTYPE_OTHER, // RRtype = 60: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 61: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 62: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 63: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 64: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 65: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 66: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 67: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 68: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 69: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 70: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 71: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 72: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 73: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 74: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 75: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 76: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 77: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 78: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 79: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 80: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 81: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 82: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 83: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 84: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 85: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 86: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 87: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 88: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 89: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 90: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 91: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 92: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 93: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 94: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 95: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 96: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 97: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 98: (Unassigned)
+ QR_QTYPE_SPF, // RRtype = 99: SPF
+ QR_QTYPE_UINFO, // RRtype = 100: UINFO
+ QR_QTYPE_UID, // RRtype = 101: UID
+ QR_QTYPE_GID, // RRtype = 102: GID
+ QR_QTYPE_UNSPEC, // RRtype = 103: UNSPEC
+ QR_QTYPE_OTHER, // RRtype = 104: NID
+ QR_QTYPE_OTHER, // RRtype = 105: L32
+ QR_QTYPE_OTHER, // RRtype = 106: L64
+ QR_QTYPE_OTHER, // RRtype = 107: LP
+ QR_QTYPE_OTHER, // RRtype = 108: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 109: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 110: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 111: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 112: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 113: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 114: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 115: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 116: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 117: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 118: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 119: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 120: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 121: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 122: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 123: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 124: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 125: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 126: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 127: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 128: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 129: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 130: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 131: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 132: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 133: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 134: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 135: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 136: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 137: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 138: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 139: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 140: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 141: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 142: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 143: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 144: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 145: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 146: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 147: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 148: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 149: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 150: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 151: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 152: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 153: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 154: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 155: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 156: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 157: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 158: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 159: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 160: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 161: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 162: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 163: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 164: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 165: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 166: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 167: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 168: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 169: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 170: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 171: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 172: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 173: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 174: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 175: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 176: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 177: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 178: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 179: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 180: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 181: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 182: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 183: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 184: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 185: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 186: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 187: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 188: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 189: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 190: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 191: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 192: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 193: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 194: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 195: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 196: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 197: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 198: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 199: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 200: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 201: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 202: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 203: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 204: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 205: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 206: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 207: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 208: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 209: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 210: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 211: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 212: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 213: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 214: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 215: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 216: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 217: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 218: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 219: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 220: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 221: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 222: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 223: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 224: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 225: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 226: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 227: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 228: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 229: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 230: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 231: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 232: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 233: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 234: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 235: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 236: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 237: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 238: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 239: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 240: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 241: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 242: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 243: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 244: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 245: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 246: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 247: (Unassigned)
+ QR_QTYPE_OTHER, // RRtype = 248: (Unassigned)
+ QR_QTYPE_TKEY, // RRtype = 249: TKEY
+ QR_QTYPE_TSIG, // RRtype = 250: TSIG
+ QR_QTYPE_IXFR, // RRtype = 251: IXFR
+ QR_QTYPE_AXFR, // RRtype = 252: AXFR
+ QR_QTYPE_MAILB, // RRtype = 253: MAILB
+ QR_QTYPE_MAILA, // RRtype = 254: MAILA
+ QR_QTYPE_OTHER, // RRtype = 255: for All records
+ QR_QTYPE_URI, // RRtype = 256: URI
+ QR_QTYPE_CAA // RRtype = 257: CAA
+};
+const int QRRCodeToQRCounterType[23] = {
+ QR_RCODE_NOERROR, // Rcode = 0: NoError
+ QR_RCODE_FORMERR, // Rcode = 1: FormErr
+ QR_RCODE_SERVFAIL, // Rcode = 2: ServFail
+ QR_RCODE_NXDOMAIN, // Rcode = 3: NXDomain
+ QR_RCODE_NOTIMP, // Rcode = 4: NotImp
+ QR_RCODE_REFUSED, // Rcode = 5: Refused
+ QR_RCODE_YXDOMAIN, // Rcode = 6: YXDomain
+ QR_RCODE_YXRRSET, // Rcode = 7: YXRRSet
+ QR_RCODE_NXRRSET, // Rcode = 8: NXRRSet
+ QR_RCODE_NOTAUTH, // Rcode = 9: NotAuth
+ QR_RCODE_NOTZONE, // Rcode = 10: NotZone
+ QR_RCODE_OTHER, // Rcode = 11: (Unassigned)
+ QR_RCODE_OTHER, // Rcode = 12: (Unassigned)
+ QR_RCODE_OTHER, // Rcode = 13: (Unassigned)
+ QR_RCODE_OTHER, // Rcode = 14: (Unassigned)
+ QR_RCODE_OTHER, // Rcode = 15: (Unassigned)
+ QR_RCODE_BADSIGVERS, // Rcode = 16: BADVERS, BADSIG
+ QR_RCODE_BADKEY, // Rcode = 17: BADKEY
+ QR_RCODE_BADTIME, // Rcode = 18: BADTIME
+ QR_RCODE_BADMODE, // Rcode = 19: BADMODE
+ QR_RCODE_BADNAME, // Rcode = 20: BADNAME
+ QR_RCODE_BADALG, // Rcode = 21: BADALG
+ QR_RCODE_BADTRUNC // Rcode = 22: BADTRUNC
+};
+
+} // anonymous namespace
+
+#endif // __STATISTICS_ITEMS_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/bin/auth/tests/Makefile.am b/src/bin/auth/tests/Makefile.am
index 3138c27..6a91309 100644
--- a/src/bin/auth/tests/Makefile.am
+++ b/src/bin/auth/tests/Makefile.am
@@ -41,7 +41,7 @@ run_unittests_SOURCES += ../query.h ../query.cc
run_unittests_SOURCES += ../auth_config.h ../auth_config.cc
run_unittests_SOURCES += ../command.h ../command.cc
run_unittests_SOURCES += ../common.h ../common.cc
-run_unittests_SOURCES += ../statistics.h ../statistics.cc
+run_unittests_SOURCES += ../statistics.h ../statistics.cc ../statistics_items.h
run_unittests_SOURCES += ../datasrc_config.h ../datasrc_config.cc
run_unittests_SOURCES += datasrc_util.h datasrc_util.cc
run_unittests_SOURCES += auth_srv_unittest.cc
@@ -75,7 +75,6 @@ run_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
run_unittests_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
run_unittests_LDADD += $(top_builddir)/src/lib/nsas/libb10-nsas.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
-run_unittests_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
run_unittests_LDADD += $(top_builddir)/src/lib/config/tests/libfake_session.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/threads/libb10-threads.la
run_unittests_LDADD += $(GTEST_LDADD)
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index d498d9d..8015043 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -15,7 +15,6 @@
#include <config.h>
#include <util/io/sockaddr_util.h>
-#include <util/memory_segment_local.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
@@ -36,6 +35,7 @@
#include <auth/command.h>
#include <auth/common.h>
#include <auth/statistics.h>
+#include <auth/statistics_items.h>
#include <auth/datasrc_config.h>
#include <util/unittests/mock_socketsession.h>
@@ -74,8 +74,10 @@ using namespace isc::asiodns;
using namespace isc::asiolink;
using namespace isc::testutils;
using namespace isc::server_common::portconfig;
+using isc::datasrc::memory::ZoneTableSegment;
using isc::UnitTestUtil;
using boost::scoped_ptr;
+using isc::auth::statistics::Counters;
namespace {
const char* const CONFIG_TESTDB =
@@ -123,29 +125,47 @@ protected:
// Helper for checking Rcode statistic counters;
// Checks for one specific Rcode statistics counter value
- void checkRcodeCounter(const Rcode& rcode, int expected_value) const {
- EXPECT_EQ(expected_value, server.getCounter(rcode)) <<
- "Expected Rcode count for " << rcode.toText() <<
- " " << expected_value << ", was: " <<
- server.getCounter(rcode);
+ void checkRcodeCounter(const std::string& rcode_name, const int rcode_value,
+ const int expected_value) const
+ {
+ EXPECT_EQ(expected_value, rcode_value) <<
+ "Expected Rcode count for " << rcode_name <<
+ " " << expected_value << ", was: " <<
+ rcode_value;
}
// Checks whether all Rcode counters are set to zero
void checkAllRcodeCountersZero() const {
- for (int i = 0; i < 17; i++) {
- checkRcodeCounter(Rcode(i), 0);
- }
+ // with checking NOERROR == 0 and the others are 0
+ checkAllRcodeCountersZeroExcept(Rcode::NOERROR(), 0);
}
// Checks whether all Rcode counters are set to zero except the given
// rcode (it is checked to be set to 'value')
void checkAllRcodeCountersZeroExcept(const Rcode& rcode, int value) const {
- for (int i = 0; i < 17; i++) {
- const Rcode rc(i);
- if (rc == rcode) {
- checkRcodeCounter(Rcode(i), value);
- } else {
- checkRcodeCounter(Rcode(i), 0);
+ std::string target_rcode_name = rcode.toText();
+ std::transform(target_rcode_name.begin(), target_rcode_name.end(),
+ target_rcode_name.begin(), ::tolower);
+ // rcode 16 is registered as both BADVERS and BADSIG
+ if (target_rcode_name == "badvers") {
+ target_rcode_name = "badsigvers";
+ }
+
+ const std::map<std::string, ConstElementPtr>
+ stats_map(server.getStatistics()->mapValue());
+
+ const std::string rcode_prefix("rcode.");
+ for (std::map<std::string, ConstElementPtr>::const_iterator
+ i = stats_map.begin(), e = stats_map.end();
+ i != e;
+ ++i)
+ {
+ if (i->first.compare(0, rcode_prefix.size(), rcode_prefix) == 0) {
+ if (i->first.compare(rcode_prefix + target_rcode_name) == 0) {
+ checkRcodeCounter(i->first, i->second->intValue(), value);
+ } else {
+ checkRcodeCounter(i->first, i->second->intValue(), 0);
+ }
}
}
}
@@ -222,6 +242,29 @@ createBuiltinVersionResponse(const qid_t qid, vector<uint8_t>& data) {
renderer.getLength());
}
+// Check if the item has expected value.
+// Before reading the item, check the item exists.
+void
+expectCounterItem(ConstElementPtr stats,
+ const std::string& item, const int expected) {
+ ConstElementPtr value(Element::create(0));
+ if (item == "queries.udp" || item == "queries.tcp" || expected != 0) {
+ // if the value of the item is not zero, the item exists and has
+ // expected value
+ // item "queries.udp" and "queries.tcp" exists whether the value
+ // is zero or nonzero
+ ASSERT_TRUE(stats->find(item, value)) << " Item: " << item;
+ // Get the value of the item with another method because of API bug
+ // (ticket #2302)
+ value = stats->find(item);
+ EXPECT_EQ(expected, value->intValue()) << " Item: " << item;
+ } else {
+ // otherwise the item does not exist
+ ASSERT_FALSE(stats->find(item, value)) << " Item: " << item <<
+ std::endl << " Value: " << value->intValue();
+ }
+}
+
// We did not configure any client lists. Therefore it should be REFUSED
TEST_F(AuthSrvTest, noClientList) {
UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
@@ -405,7 +448,9 @@ TEST_F(AuthSrvTest, TSIGCheckFirst) {
"It should be unsigned with this error";
// TSIG should have failed, and so the per opcode counter shouldn't be
// incremented.
- EXPECT_EQ(0, server.getCounter(Opcode::RESERVED14()));
+ ConstElementPtr stats = server.getStatistics();
+ expectCounterItem(stats, "opcode.normal", 0);
+ expectCounterItem(stats, "opcode.other", 0);
checkAllRcodeCountersZeroExcept(Rcode::NOTAUTH(), 1);
}
@@ -1041,8 +1086,12 @@ TEST_F(AuthSrvTest,
// Submit UDP normal query and check query counter
TEST_F(AuthSrvTest, queryCounterUDPNormal) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_UDP_QUERY));
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics();
+ expectCounterItem(stats_init, "queries.udp", 0);
+ expectCounterItem(stats_init, "queries.tcp", 0);
+ expectCounterItem(stats_init, "opcode.query", 0);
+ expectCounterItem(stats_init, "rcode.refused", 0);
// Create UDP message and process.
UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
default_qid, Name("example.com"),
@@ -1050,18 +1099,25 @@ TEST_F(AuthSrvTest, queryCounterUDPNormal) {
createRequestPacket(request_message, IPPROTO_UDP);
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
- // After processing UDP query, the counter should be 1.
- EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_UDP_QUERY));
- // The counter for opcode Query should also be one
- EXPECT_EQ(1, server.getCounter(Opcode::QUERY()));
- // The counter for REFUSED responses should also be one, the rest zero
- checkAllRcodeCountersZeroExcept(Rcode::REFUSED(), 1);
+ // After processing the UDP query, these counters should be incremented:
+ // queries.udp, opcode.query, rcode.refused
+ // and these counters should not be incremented:
+ // queries.tcp
+ ConstElementPtr stats_after = server.getStatistics();
+ expectCounterItem(stats_after, "queries.udp", 1);
+ expectCounterItem(stats_after, "queries.tcp", 0);
+ expectCounterItem(stats_after, "opcode.query", 1);
+ expectCounterItem(stats_after, "rcode.refused", 1);
}
// Submit TCP normal query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPNormal) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics();
+ expectCounterItem(stats_init, "queries.udp", 0);
+ expectCounterItem(stats_init, "queries.tcp", 0);
+ expectCounterItem(stats_init, "opcode.query", 0);
+ expectCounterItem(stats_init, "rcode.refused", 0);
// Create TCP message and process.
UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
default_qid, Name("example.com"),
@@ -1069,18 +1125,24 @@ TEST_F(AuthSrvTest, queryCounterTCPNormal) {
createRequestPacket(request_message, IPPROTO_TCP);
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
- // After processing TCP query, the counter should be 1.
- EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
- // The counter for SUCCESS responses should also be one
- EXPECT_EQ(1, server.getCounter(Opcode::QUERY()));
- // The counter for REFUSED responses should also be one, the rest zero
- checkAllRcodeCountersZeroExcept(Rcode::REFUSED(), 1);
+ // After processing the TCP query, these counters should be incremented:
+ // queries.tcp, opcode.query, rcode.refused
+ // and these counters should not be incremented:
+ // queries.udp
+ ConstElementPtr stats_after = server.getStatistics();
+ expectCounterItem(stats_after, "queries.udp", 0);
+ expectCounterItem(stats_after, "queries.tcp", 1);
+ expectCounterItem(stats_after, "opcode.query", 1);
+ expectCounterItem(stats_after, "rcode.refused", 1);
}
// Submit TCP AXFR query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics();
+ expectCounterItem(stats_init, "queries.udp", 0);
+ expectCounterItem(stats_init, "queries.tcp", 0);
+ expectCounterItem(stats_init, "opcode.query", 0);
UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Name("example.com"), RRClass::IN(), RRType::AXFR());
createRequestPacket(request_message, IPPROTO_TCP);
@@ -1089,16 +1151,24 @@ TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
- // After processing TCP AXFR query, the counter should be 1.
- EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
- // No rcodes should be incremented
- checkAllRcodeCountersZero();
+ // After processing the TCP AXFR query, these counters should be
+ // incremented:
+ // queries.tcp, opcode.query
+ // and these counters should not be incremented:
+ // queries.udp
+ ConstElementPtr stats_after = server.getStatistics();
+ expectCounterItem(stats_after, "queries.udp", 0);
+ expectCounterItem(stats_after, "queries.tcp", 1);
+ expectCounterItem(stats_after, "opcode.query", 1);
}
// Submit TCP IXFR query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics();
+ expectCounterItem(stats_init, "queries.udp", 0);
+ expectCounterItem(stats_init, "queries.tcp", 0);
+ expectCounterItem(stats_init, "opcode.query", 0);
UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Name("example.com"), RRClass::IN(), RRType::IXFR());
createRequestPacket(request_message, IPPROTO_TCP);
@@ -1107,14 +1177,27 @@ TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
- // After processing TCP IXFR query, the counter should be 1.
- EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+ // After processing the TCP IXFR query, these counters should be
+ // incremented:
+ // queries.tcp, opcode.query
+ // and these counters should not be incremented:
+ // queries.udp
+ ConstElementPtr stats_after = server.getStatistics();
+ expectCounterItem(stats_after, "queries.udp", 0);
+ expectCounterItem(stats_after, "queries.tcp", 1);
+ expectCounterItem(stats_after, "opcode.query", 1);
}
TEST_F(AuthSrvTest, queryCounterOpcodes) {
- for (int i = 0; i < 16; ++i) {
+ // Check for 0..2, 3(=other), 4..5
+ // The counter should be initialized to 0.
+ for (int i = 0; i < 6; ++i) {
// The counter should be initialized to 0.
- EXPECT_EQ(0, server.getCounter(Opcode(i)));
+ expectCounterItem(server.getStatistics(),
+ std::string("opcode.") +
+ QRCounterOpcode[QROpCodeToQRCounterType[i] -
+ QR_OPCODE_QUERY].name,
+ 0);
// For each possible opcode, create a request message and send it
UnitTestUtil::createRequestMessage(request_message, Opcode(i),
@@ -1132,7 +1215,45 @@ TEST_F(AuthSrvTest, queryCounterOpcodes) {
}
// Confirm the counter.
- EXPECT_EQ(i + 1, server.getCounter(Opcode(i)));
+ expectCounterItem(server.getStatistics(),
+ std::string("opcode.") +
+ QRCounterOpcode[QROpCodeToQRCounterType[i] -
+ QR_OPCODE_QUERY].name,
+ i + 1);
+ }
+ // Check for 6..15
+ // they are treated as the 'other' opcode
+ // the 'other' opcode counter is 4 at this point
+ int expected = 4;
+ for (int i = 6; i < 16; ++i) {
+ // The counter should be initialized to 0.
+ expectCounterItem(server.getStatistics(),
+ std::string("opcode.") +
+ QRCounterOpcode[QROpCodeToQRCounterType[i] -
+ QR_OPCODE_QUERY].name,
+ expected);
+
+ // For each possible opcode, create a request message and send it
+ UnitTestUtil::createRequestMessage(request_message, Opcode(i),
+ default_qid, Name("example.com"),
+ RRClass::IN(), RRType::NS());
+ createRequestPacket(request_message, IPPROTO_UDP);
+
+ // "send" the request once
+ parse_message->clear(Message::PARSE);
+ server.processMessage(*io_message, *parse_message,
+ *response_obuffer,
+ &dnsserv);
+
+ // the 'other' opcode counter should be incremented
+ ++expected;
+
+ // Confirm the counter.
+ expectCounterItem(server.getStatistics(),
+ std::string("opcode.") +
+ QRCounterOpcode[QROpCodeToQRCounterType[i] -
+ QR_OPCODE_QUERY].name,
+ expected);
}
}
@@ -1401,7 +1522,9 @@ public:
real_list, ThrowWhen throw_when, bool isc_exception,
ConstRRsetPtr fake_rrset = ConstRRsetPtr()) :
ConfigurableClientList(RRClass::IN()),
- real_(real_list)
+ real_(real_list),
+ config_(Element::fromJSON("{}")),
+ ztable_segment_(ZoneTableSegment::create(*config_, RRClass::IN()))
{
BOOST_FOREACH(const DataSourceInfo& info, real_->getDataSources()) {
const isc::datasrc::DataSourceClientPtr
@@ -1413,13 +1536,14 @@ public:
data_sources_.push_back(
DataSourceInfo(client.get(),
isc::datasrc::DataSourceClientContainerPtr(),
- false, RRClass::IN(), mem_sgmt_));
+ false, RRClass::IN(), ztable_segment_));
}
}
private:
const boost::shared_ptr<isc::datasrc::ConfigurableClientList> real_;
+ const ConstElementPtr config_;
+ boost::shared_ptr<ZoneTableSegment> ztable_segment_;
vector<isc::datasrc::DataSourceClientPtr> clients_;
- MemorySegmentLocal mem_sgmt_;
};
} // end anonymous namespace for throwing proxy classes
@@ -1715,6 +1839,15 @@ namespace {
isc::config::parseAnswer(command_result, response);
EXPECT_EQ(0, command_result);
}
+
+ void sendCommand(AuthSrv& server, const std::string& command,
+ ConstElementPtr args, int expected_result) {
+ ConstElementPtr response = execAuthServerCommand(server, command,
+ args);
+ int command_result = -1;
+ isc::config::parseAnswer(command_result, response);
+ EXPECT_EQ(expected_result, command_result);
+ }
} // end anonymous namespace
TEST_F(AuthSrvTest, DDNSForwardCreateDestroy) {
@@ -1786,4 +1919,18 @@ TEST_F(AuthSrvTest, DDNSForwardCreateDestroy) {
Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
}
+TEST_F(AuthSrvTest, loadZoneCommand) {
+ // Just some very basic tests, to check the command is accepted, and that
+ // it raises on bad arguments, but not on correct ones (full testing
+ // is handled in the unit tests for the corresponding classes)
+
+ // Empty map should fail
+ ElementPtr args(Element::createMap());
+ sendCommand(server, "loadzone", args, 1);
+ // Setting an origin should be enough (even if it isn't actually loaded,
+ // it should be initially accepted)
+ args->set("origin", Element::create("example.com"));
+ sendCommand(server, "loadzone", args, 0);
+}
+
}
diff --git a/src/bin/auth/tests/command_unittest.cc b/src/bin/auth/tests/command_unittest.cc
index 280def6..be90d73 100644
--- a/src/bin/auth/tests/command_unittest.cc
+++ b/src/bin/auth/tests/command_unittest.cc
@@ -169,281 +169,6 @@ TEST_F(AuthCommandTest, shutdownIncorrectPID) {
EXPECT_EQ(0, rcode_);
}
-// A helper function commonly used for the "loadzone" command tests.
-// It configures the server with a memory data source containing two
-// zones, and checks the zones are correctly loaded.
-void
-zoneChecks(AuthSrv& server) {
- const RRClass rrclass(RRClass::IN());
-
- DataSrcClientsMgr::Holder holder(server.getDataSrcClientsMgr());
- EXPECT_EQ(ZoneFinder::SUCCESS,
- holder.findClientList(rrclass)->find(Name("ns.test1.example"))
- .finder_->find(Name("ns.test1.example"), RRType::A())->code);
- EXPECT_EQ(ZoneFinder::NXRRSET,
- holder.findClientList(rrclass)->find(Name("ns.test1.example")).
- finder_->find(Name("ns.test1.example"), RRType::AAAA())->code);
- EXPECT_EQ(ZoneFinder::SUCCESS,
- holder.findClientList(rrclass)->find(Name("ns.test2.example")).
- finder_->find(Name("ns.test2.example"), RRType::A())->code);
- EXPECT_EQ(ZoneFinder::NXRRSET,
- holder.findClientList(rrclass)->find(Name("ns.test2.example")).
- finder_->find(Name("ns.test2.example"), RRType::AAAA())->code);
-}
-
-void
-installDataSrcClientLists(AuthSrv& server, ClientListMapPtr lists) {
- server.getDataSrcClientsMgr().setDataSrcClientLists(lists);
-}
-
-void
-configureZones(AuthSrv& server) {
- ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR "/test1.zone.in "
- TEST_DATA_BUILDDIR "/test1.zone.copied"));
- ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR "/test2.zone.in "
- TEST_DATA_BUILDDIR "/test2.zone.copied"));
-
- const ConstElementPtr config(Element::fromJSON("{"
- "\"IN\": [{"
- " \"type\": \"MasterFiles\","
- " \"params\": {"
- " \"test1.example\": \"" +
- string(TEST_DATA_BUILDDIR "/test1.zone.copied") + "\","
- " \"test2.example\": \"" +
- string(TEST_DATA_BUILDDIR "/test2.zone.copied") + "\""
- " },"
- " \"cache-enable\": true"
- "}]}"));
-
- installDataSrcClientLists(server, configureDataSource(config));
-
- zoneChecks(server);
-}
-
-void
-newZoneChecks(AuthSrv& server) {
- const RRClass rrclass(RRClass::IN());
-
- DataSrcClientsMgr::Holder holder(server.getDataSrcClientsMgr());
- EXPECT_EQ(ZoneFinder::SUCCESS, holder.findClientList(rrclass)->
- find(Name("ns.test1.example")).finder_->
- find(Name("ns.test1.example"), RRType::A())->code);
-
- // now test1.example should have ns/AAAA
- EXPECT_EQ(ZoneFinder::SUCCESS, holder.findClientList(rrclass)->
- find(Name("ns.test1.example")).finder_->
- find(Name("ns.test1.example"), RRType::AAAA())->code);
-
- // test2.example shouldn't change
- EXPECT_EQ(ZoneFinder::SUCCESS, holder.findClientList(rrclass)->
- find(Name("ns.test2.example")).finder_->
- find(Name("ns.test2.example"), RRType::A())->code);
- EXPECT_EQ(ZoneFinder::NXRRSET,
- holder.findClientList(rrclass)->
- find(Name("ns.test2.example")).finder_->
- find(Name("ns.test2.example"), RRType::AAAA())->code);
-}
-
-TEST_F(AuthCommandTest, loadZone) {
- configureZones(server_);
-
- ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR
- "/test1-new.zone.in "
- TEST_DATA_BUILDDIR "/test1.zone.copied"));
- ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR
- "/test2-new.zone.in "
- TEST_DATA_BUILDDIR "/test2.zone.copied"));
-
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\"}"));
- checkAnswer(0);
- newZoneChecks(server_);
-}
-
-TEST_F(AuthCommandTest,
-#ifdef USE_STATIC_LINK
- DISABLED_loadZoneSQLite3
-#else
- loadZoneSQLite3
-#endif
- )
-{
- // Prepare the database first
- const string test_db = TEST_DATA_BUILDDIR "/auth_test.sqlite3.copied";
- const string bad_db = TEST_DATA_BUILDDIR "/does-not-exist.sqlite3";
- stringstream ss("example.org. 3600 IN SOA . . 0 0 0 0 0\n");
- createSQLite3DB(RRClass::IN(), Name("example.org"), test_db.c_str(), ss);
- // This describes the data source in the configuration
- const ConstElementPtr config(Element::fromJSON("{"
- "\"IN\": [{"
- " \"type\": \"sqlite3\","
- " \"params\": {\"database_file\": \"" + test_db + "\"},"
- " \"cache-enable\": true,"
- " \"cache-zones\": [\"example.org\"]"
- "}]}"));
- installDataSrcClientLists(server_, configureDataSource(config));
-
- {
- DataSrcClientsMgr::Holder holder(server_.getDataSrcClientsMgr());
-
- // Check that the A record at www.example.org does not exist
- EXPECT_EQ(ZoneFinder::NXDOMAIN,
- holder.findClientList(RRClass::IN())->
- find(Name("example.org")).finder_->
- find(Name("www.example.org"), RRType::A())->code);
-
- // Add the record to the underlying sqlite database, by loading
- // it as a separate datasource, and updating it
- ConstElementPtr sql_cfg = Element::fromJSON("{ \"type\": \"sqlite3\","
- "\"database_file\": \""
- + test_db + "\"}");
- DataSourceClientContainer sql_ds("sqlite3", sql_cfg);
- ZoneUpdaterPtr sql_updater =
- sql_ds.getInstance().getUpdater(Name("example.org"), false);
- RRsetPtr rrset(new RRset(Name("www.example.org."), RRClass::IN(),
- RRType::A(), RRTTL(60)));
- rrset->addRdata(rdata::createRdata(rrset->getType(),
- rrset->getClass(),
- "192.0.2.1"));
- sql_updater->addRRset(*rrset);
- sql_updater->commit();
-
- EXPECT_EQ(ZoneFinder::NXDOMAIN,
- holder.findClientList(RRClass::IN())->
- find(Name("example.org")).finder_->
- find(Name("www.example.org"), RRType::A())->code);
- }
-
- // Now send the command to reload it
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"example.org\"}"));
- checkAnswer(0, "Successful load");
-
- {
- DataSrcClientsMgr::Holder holder(server_.getDataSrcClientsMgr());
- // And now it should be present too.
- EXPECT_EQ(ZoneFinder::SUCCESS,
- holder.findClientList(RRClass::IN())->
- find(Name("example.org")).finder_->
- find(Name("www.example.org"), RRType::A())->code);
- }
-
- // Some error cases. First, the zone has no configuration. (note .com here)
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON("{\"origin\": \"example.com\"}"));
- checkAnswer(1, "example.com");
-
- {
- DataSrcClientsMgr::Holder holder(server_.getDataSrcClientsMgr());
- // The previous zone is not hurt in any way
- EXPECT_EQ(ZoneFinder::SUCCESS,
- holder.findClientList(RRClass::IN())->
- find(Name("example.org")).finder_->
- find(Name("example.org"), RRType::SOA())->code);
- }
-
- const ConstElementPtr config2(Element::fromJSON("{"
- "\"IN\": [{"
- " \"type\": \"sqlite3\","
- " \"params\": {\"database_file\": \"" + bad_db + "\"},"
- " \"cache-enable\": true,"
- " \"cache-zones\": [\"example.com\"]"
- "}]}"));
- EXPECT_THROW(configureDataSource(config2),
- ConfigurableClientList::ConfigurationError);
-
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON("{\"origin\": \"example.com\"}"));
- checkAnswer(1, "Unreadable");
-
- DataSrcClientsMgr::Holder holder(server_.getDataSrcClientsMgr());
- // The previous zone is not hurt in any way
- EXPECT_EQ(ZoneFinder::SUCCESS,
- holder.findClientList(RRClass::IN())->
- find(Name("example.org")).finder_->
- find(Name("example.org"), RRType::SOA())->code);
-}
-
-TEST_F(AuthCommandTest, loadBrokenZone) {
- configureZones(server_);
-
- ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR
- "/test1-broken.zone.in "
- TEST_DATA_BUILDDIR "/test1.zone.copied"));
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\"}"));
- checkAnswer(1);
- zoneChecks(server_); // zone shouldn't be replaced
-}
-
-TEST_F(AuthCommandTest, loadUnreadableZone) {
- configureZones(server_);
-
- // install the zone file as unreadable
- ASSERT_EQ(0, system(INSTALL_PROG " -c -m 000 " TEST_DATA_DIR
- "/test1.zone.in "
- TEST_DATA_BUILDDIR "/test1.zone.copied"));
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\"}"));
- checkAnswer(1);
- zoneChecks(server_); // zone shouldn't be replaced
-}
-
-TEST_F(AuthCommandTest, loadZoneWithoutDataSrc) {
- // try to execute load command without configuring the zone beforehand.
- // it should fail.
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\"}"));
- checkAnswer(1);
-}
-
-TEST_F(AuthCommandTest, loadZoneInvalidParams) {
- configureZones(server_);
-
- // null arg
- result_ = execAuthServerCommand(server_, "loadzone", ElementPtr());
- checkAnswer(1, "Null arg");
-
- // zone class is bogus
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\","
- " \"class\": \"no_such_class\"}"));
- checkAnswer(1, "No such class");
-
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\","
- " \"class\": 1}"));
- checkAnswer(1, "Integral class");
-
-
- // origin is missing
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON("{}"));
- checkAnswer(1, "Missing origin");
-
- // zone doesn't exist in the data source
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON("{\"origin\": \"xx\"}"));
- checkAnswer(1, "No such zone");
-
- // origin is bogus
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"...\"}"));
- checkAnswer(1, "Wrong name");
-
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON("{\"origin\": 10}"));
- checkAnswer(1, "Integral name");
-}
-
TEST_F(AuthCommandTest, getStats) {
result_ = execAuthServerCommand(server_, "getstats", ConstElementPtr());
parseAnswer(rcode_, result_);
diff --git a/src/bin/auth/tests/datasrc_clients_builder_unittest.cc b/src/bin/auth/tests/datasrc_clients_builder_unittest.cc
index 22d33cf..585e7c3 100644
--- a/src/bin/auth/tests/datasrc_clients_builder_unittest.cc
+++ b/src/bin/auth/tests/datasrc_clients_builder_unittest.cc
@@ -12,36 +12,62 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <util/unittests/check_valgrind.h>
+
+#include <dns/name.h>
+#include <dns/rrclass.h>
+
#include <cc/data.h>
+#include <datasrc/client.h>
+#include <datasrc/factory.h>
+
#include <auth/datasrc_clients_mgr.h>
+#include <auth/datasrc_config.h>
+
+#include <testutils/dnsmessage_test.h>
+
#include "test_datasrc_clients_mgr.h"
+#include "datasrc_util.h"
#include <gtest/gtest.h>
#include <boost/function.hpp>
+#include <cstdlib>
+#include <string>
+#include <sstream>
+
using isc::data::ConstElementPtr;
+using namespace isc::dns;
+using namespace isc::data;
using namespace isc::datasrc;
using namespace isc::auth::datasrc_clientmgr_internal;
+using namespace isc::auth::unittest;
+using namespace isc::testutils;
namespace {
class DataSrcClientsBuilderTest : public ::testing::Test {
protected:
DataSrcClientsBuilderTest() :
+ clients_map(new std::map<RRClass,
+ boost::shared_ptr<ConfigurableClientList> >),
builder(&command_queue, &cond, &queue_mutex, &clients_map, &map_mutex),
- cond(command_queue, delayed_command_queue),
+ cond(command_queue, delayed_command_queue), rrclass(RRClass::IN()),
shutdown_cmd(SHUTDOWN, ConstElementPtr()),
noop_cmd(NOOP, ConstElementPtr())
{}
- TestDataSrcClientsBuilder builder;
+ void configureZones(); // used for loadzone related tests
+
+ ClientListMapPtr clients_map; // configured clients
std::list<Command> command_queue; // test command queue
std::list<Command> delayed_command_queue; // commands available after wait
- ClientListMapPtr clients_map; // configured clients
+ TestDataSrcClientsBuilder builder;
TestCondVar cond;
TestMutex queue_mutex;
TestMutex map_mutex;
+ const RRClass rrclass;
const Command shutdown_cmd;
const Command noop_cmd;
};
@@ -74,13 +100,20 @@ TEST_F(DataSrcClientsBuilderTest, exception) {
// them. Right now, we simply abort to prevent the system from running
// with half-broken state. Eventually we should introduce a better
// error handling.
- command_queue.push_back(noop_cmd);
- queue_mutex.throw_from_noop = TestMutex::EXCLASS;
- EXPECT_DEATH_IF_SUPPORTED({builder.run();}, "");
+ if (!isc::util::unittests::runningOnValgrind()) {
+ command_queue.push_back(noop_cmd);
+ queue_mutex.throw_from_noop = TestMutex::EXCLASS;
+ EXPECT_DEATH_IF_SUPPORTED({builder.run();}, "");
+
+ command_queue.push_back(noop_cmd);
+ queue_mutex.throw_from_noop = TestMutex::INTEGER;
+ EXPECT_DEATH_IF_SUPPORTED({builder.run();}, "");
+ }
command_queue.push_back(noop_cmd);
- queue_mutex.throw_from_noop = TestMutex::INTEGER;
- EXPECT_DEATH_IF_SUPPORTED({builder.run();}, "");
+ command_queue.push_back(shutdown_cmd); // we need to stop the loop
+ queue_mutex.throw_from_noop = TestMutex::INTERNAL;
+ builder.run();
}
TEST_F(DataSrcClientsBuilderTest, condWait) {
@@ -106,10 +139,10 @@ TEST_F(DataSrcClientsBuilderTest, reconfigure) {
Command reconfig_cmd(RECONFIGURE, ConstElementPtr());
// Initially, no clients should be there
- EXPECT_EQ(ClientListMapPtr(), clients_map);
+ EXPECT_TRUE(clients_map->empty());
// A config that doesn't do much except be accepted
- ConstElementPtr good_config = isc::data::Element::fromJSON(
+ ConstElementPtr good_config = Element::fromJSON(
"{"
"\"IN\": [{"
" \"type\": \"MasterFiles\","
@@ -121,7 +154,7 @@ TEST_F(DataSrcClientsBuilderTest, reconfigure) {
// A configuration that is 'correct' in the top-level, but contains
// bad data for the type it specifies
- ConstElementPtr bad_config = isc::data::Element::fromJSON(
+ ConstElementPtr bad_config = Element::fromJSON(
"{"
"\"IN\": [{"
" \"type\": \"MasterFiles\","
@@ -142,7 +175,7 @@ TEST_F(DataSrcClientsBuilderTest, reconfigure) {
// If a 'bad' command argument got here, the config validation should
// have failed already, but still, the handler should return true,
// and the clients_map should not be updated.
- reconfig_cmd.second = isc::data::Element::create("{ \"foo\": \"bar\" }");
+ reconfig_cmd.second = Element::create("{ \"foo\": \"bar\" }");
EXPECT_TRUE(builder.handleCommand(reconfig_cmd));
EXPECT_EQ(working_config_clients, clients_map);
// Building failed, so map mutex should not have been locked again
@@ -173,7 +206,7 @@ TEST_F(DataSrcClientsBuilderTest, reconfigure) {
EXPECT_EQ(2, map_mutex.lock_count);
// And finally, try an empty config to disable all datasource clients
- reconfig_cmd.second = isc::data::Element::createMap();
+ reconfig_cmd.second = Element::createMap();
EXPECT_TRUE(builder.handleCommand(reconfig_cmd));
EXPECT_EQ(0, clients_map->size());
EXPECT_EQ(3, map_mutex.lock_count);
@@ -193,4 +226,292 @@ TEST_F(DataSrcClientsBuilderTest, badCommand) {
isc::Unexpected);
}
+// A helper function commonly used for the "loadzone" command tests.
+// It configures the given data source client lists with a memory data source
+// containing two zones, and checks the zones are correctly loaded.
+void
+zoneChecks(ClientListMapPtr clients_map, RRClass rrclass) {
+ EXPECT_EQ(ZoneFinder::SUCCESS, clients_map->find(rrclass)->second->
+ find(Name("ns.test1.example")).finder_->
+ find(Name("ns.test1.example"), RRType::A())->code);
+ EXPECT_EQ(ZoneFinder::NXRRSET, clients_map->find(rrclass)->second->
+ find(Name("ns.test1.example")).finder_->
+ find(Name("ns.test1.example"), RRType::AAAA())->code);
+ EXPECT_EQ(ZoneFinder::SUCCESS, clients_map->find(rrclass)->second->
+ find(Name("ns.test2.example")).finder_->
+ find(Name("ns.test2.example"), RRType::A())->code);
+ EXPECT_EQ(ZoneFinder::NXRRSET, clients_map->find(rrclass)->second->
+ find(Name("ns.test2.example")).finder_->
+ find(Name("ns.test2.example"), RRType::AAAA())->code);
+}
+
+// Another helper that checks after completing loadzone command.
+void
+newZoneChecks(ClientListMapPtr clients_map, RRClass rrclass) {
+ EXPECT_EQ(ZoneFinder::SUCCESS, clients_map->find(rrclass)->second->
+ find(Name("ns.test1.example")).finder_->
+ find(Name("ns.test1.example"), RRType::A())->code);
+ // now test1.example should have ns/AAAA
+ EXPECT_EQ(ZoneFinder::SUCCESS, clients_map->find(rrclass)->second->
+ find(Name("ns.test1.example")).finder_->
+ find(Name("ns.test1.example"), RRType::AAAA())->code);
+
+ // test2.example shouldn't change
+ EXPECT_EQ(ZoneFinder::SUCCESS, clients_map->find(rrclass)->second->
+ find(Name("ns.test2.example")).finder_->
+ find(Name("ns.test2.example"), RRType::A())->code);
+ EXPECT_EQ(ZoneFinder::NXRRSET,
+ clients_map->find(rrclass)->second->
+ find(Name("ns.test2.example")).finder_->
+ find(Name("ns.test2.example"), RRType::AAAA())->code);
+}
+
+void
+DataSrcClientsBuilderTest::configureZones() {
+ ASSERT_EQ(0, std::system(INSTALL_PROG " -c " TEST_DATA_DIR "/test1.zone.in "
+ TEST_DATA_BUILDDIR "/test1.zone.copied"));
+ ASSERT_EQ(0, std::system(INSTALL_PROG " -c " TEST_DATA_DIR "/test2.zone.in "
+ TEST_DATA_BUILDDIR "/test2.zone.copied"));
+
+ const ConstElementPtr config(
+ Element::fromJSON(
+ "{"
+ "\"IN\": [{"
+ " \"type\": \"MasterFiles\","
+ " \"params\": {"
+ " \"test1.example\": \"" +
+ std::string(TEST_DATA_BUILDDIR "/test1.zone.copied") + "\","
+ " \"test2.example\": \"" +
+ std::string(TEST_DATA_BUILDDIR "/test2.zone.copied") + "\""
+ " },"
+ " \"cache-enable\": true"
+ "}]}"));
+ clients_map = configureDataSource(config);
+ zoneChecks(clients_map, rrclass);
+}
+
+TEST_F(DataSrcClientsBuilderTest, loadZone) {
+ // pre test condition checks
+ EXPECT_EQ(0, map_mutex.lock_count);
+ EXPECT_EQ(0, map_mutex.unlock_count);
+
+ configureZones();
+
+ EXPECT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR
+ "/test1-new.zone.in "
+ TEST_DATA_BUILDDIR "/test1.zone.copied"));
+ EXPECT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR
+ "/test2-new.zone.in "
+ TEST_DATA_BUILDDIR "/test2.zone.copied"));
+
+ const Command loadzone_cmd(LOADZONE, Element::fromJSON(
+ "{\"class\": \"IN\","
+ " \"origin\": \"test1.example\"}"));
+ EXPECT_TRUE(builder.handleCommand(loadzone_cmd));
+ EXPECT_EQ(1, map_mutex.lock_count); // we should have acquired the lock
+ EXPECT_EQ(1, map_mutex.unlock_count); // and released it.
+
+ newZoneChecks(clients_map, rrclass);
+}
+
+TEST_F(DataSrcClientsBuilderTest,
+#ifdef USE_STATIC_LINK
+ DISABLED_loadZoneSQLite3
+#else
+ loadZoneSQLite3
+#endif
+ )
+{
+ // Prepare the database first
+ const std::string test_db = TEST_DATA_BUILDDIR "/auth_test.sqlite3.copied";
+ std::stringstream ss("example.org. 3600 IN SOA . . 0 0 0 0 0\n");
+ createSQLite3DB(rrclass, Name("example.org"), test_db.c_str(), ss);
+ // This describes the data source in the configuration
+ const ConstElementPtr config(Element::fromJSON("{"
+ "\"IN\": [{"
+ " \"type\": \"sqlite3\","
+ " \"params\": {\"database_file\": \"" + test_db + "\"},"
+ " \"cache-enable\": true,"
+ " \"cache-zones\": [\"example.org\"]"
+ "}]}"));
+ clients_map = configureDataSource(config);
+
+ // Check that the A record at www.example.org does not exist
+ EXPECT_EQ(ZoneFinder::NXDOMAIN,
+ clients_map->find(rrclass)->second->
+ find(Name("example.org")).finder_->
+ find(Name("www.example.org"), RRType::A())->code);
+
+ // Add the record to the underlying sqlite database, by loading
+ // it as a separate datasource, and updating it
+ ConstElementPtr sql_cfg = Element::fromJSON("{ \"type\": \"sqlite3\","
+ "\"database_file\": \""
+ + test_db + "\"}");
+ DataSourceClientContainer sql_ds("sqlite3", sql_cfg);
+ ZoneUpdaterPtr sql_updater =
+ sql_ds.getInstance().getUpdater(Name("example.org"), false);
+ sql_updater->addRRset(
+ *textToRRset("www.example.org. 60 IN A 192.0.2.1"));
+ sql_updater->commit();
+
+ EXPECT_EQ(ZoneFinder::NXDOMAIN,
+ clients_map->find(rrclass)->second->
+ find(Name("example.org")).finder_->
+ find(Name("www.example.org"), RRType::A())->code);
+
+ // Now send the command to reload it
+ const Command loadzone_cmd(LOADZONE, Element::fromJSON(
+ "{\"class\": \"IN\","
+ " \"origin\": \"example.org\"}"));
+ EXPECT_TRUE(builder.handleCommand(loadzone_cmd));
+ // And now it should be present too.
+ EXPECT_EQ(ZoneFinder::SUCCESS,
+ clients_map->find(rrclass)->second->
+ find(Name("example.org")).finder_->
+ find(Name("www.example.org"), RRType::A())->code);
+
+ // An error case: the zone has no configuration. (note .com here)
+ const Command nozone_cmd(LOADZONE, Element::fromJSON(
+ "{\"class\": \"IN\","
+ " \"origin\": \"example.com\"}"));
+ EXPECT_THROW(builder.handleCommand(nozone_cmd),
+ TestDataSrcClientsBuilder::InternalCommandError);
+ // The previous zone is not hurt in any way
+ EXPECT_EQ(ZoneFinder::SUCCESS, clients_map->find(rrclass)->second->
+ find(Name("example.org")).finder_->
+ find(Name("example.org"), RRType::SOA())->code);
+
+ // attempt of reloading a zone but in-memory cache is disabled.
+ const ConstElementPtr config2(Element::fromJSON("{"
+ "\"IN\": [{"
+ " \"type\": \"sqlite3\","
+ " \"params\": {\"database_file\": \"" + test_db + "\"},"
+ " \"cache-enable\": false,"
+ " \"cache-zones\": [\"example.org\"]"
+ "}]}"));
+ clients_map = configureDataSource(config2);
+ EXPECT_THROW(builder.handleCommand(
+ Command(LOADZONE, Element::fromJSON(
+ "{\"class\": \"IN\","
+ " \"origin\": \"example.org\"}"))),
+ TestDataSrcClientsBuilder::InternalCommandError);
+
+ // basically impossible case: in-memory cache is completely disabled.
+ // In this implementation of manager-builder, this should never happen,
+ // but it catches it like other configuration error and keeps going.
+ clients_map->clear();
+ boost::shared_ptr<ConfigurableClientList> nocache_list(
+ new ConfigurableClientList(rrclass));
+ nocache_list->configure(
+ Element::fromJSON(
+ "[{\"type\": \"sqlite3\","
+ " \"params\": {\"database_file\": \"" + test_db + "\"},"
+ " \"cache-enable\": true,"
+ " \"cache-zones\": [\"example.org\"]"
+ "}]"), false); // false = disable cache
+ (*clients_map)[rrclass] = nocache_list;
+ EXPECT_THROW(builder.handleCommand(
+ Command(LOADZONE, Element::fromJSON(
+ "{\"class\": \"IN\","
+ " \"origin\": \"example.org\"}"))),
+ TestDataSrcClientsBuilder::InternalCommandError);
+}
+
+TEST_F(DataSrcClientsBuilderTest, loadBrokenZone) {
+ configureZones();
+
+ ASSERT_EQ(0, std::system(INSTALL_PROG " -c " TEST_DATA_DIR
+ "/test1-broken.zone.in "
+ TEST_DATA_BUILDDIR "/test1.zone.copied"));
+ // there's an error in the new zone file. reload will be rejected.
+ const Command loadzone_cmd(LOADZONE, Element::fromJSON(
+ "{\"class\": \"IN\","
+ " \"origin\": \"test1.example\"}"));
+ EXPECT_THROW(builder.handleCommand(loadzone_cmd),
+ TestDataSrcClientsBuilder::InternalCommandError);
+ zoneChecks(clients_map, rrclass); // zone shouldn't be replaced
+}
+
+TEST_F(DataSrcClientsBuilderTest, loadUnreadableZone) {
+ configureZones();
+
+ // install the zone file as unreadable
+ ASSERT_EQ(0, std::system(INSTALL_PROG " -c -m 000 " TEST_DATA_DIR
+ "/test1.zone.in "
+ TEST_DATA_BUILDDIR "/test1.zone.copied"));
+ const Command loadzone_cmd(LOADZONE, Element::fromJSON(
+ "{\"class\": \"IN\","
+ " \"origin\": \"test1.example\"}"));
+ EXPECT_THROW(builder.handleCommand(loadzone_cmd),
+ TestDataSrcClientsBuilder::InternalCommandError);
+ zoneChecks(clients_map, rrclass); // zone shouldn't be replaced
+}
+
+TEST_F(DataSrcClientsBuilderTest, loadZoneWithoutDataSrc) {
+ // try to execute load command without configuring the zone beforehand.
+ // it should fail.
+ EXPECT_THROW(builder.handleCommand(
+ Command(LOADZONE,
+ Element::fromJSON(
+ "{\"class\": \"IN\", "
+ " \"origin\": \"test1.example\"}"))),
+ TestDataSrcClientsBuilder::InternalCommandError);
+}
+
+TEST_F(DataSrcClientsBuilderTest, loadZoneInvalidParams) {
+ configureZones();
+
+ if (!isc::util::unittests::runningOnValgrind()) {
+ // null arg: this causes assertion failure
+ EXPECT_DEATH_IF_SUPPORTED({
+ builder.handleCommand(Command(LOADZONE, ElementPtr()));
+ }, "");
+ }
+
+ // zone class is bogus (note that this shouldn't happen except in tests)
+ EXPECT_THROW(builder.handleCommand(
+ Command(LOADZONE,
+ Element::fromJSON(
+ "{\"origin\": \"test1.example\","
+ " \"class\": \"no_such_class\"}"))),
+ InvalidRRClass);
+
+ // not a string
+ EXPECT_THROW(builder.handleCommand(
+ Command(LOADZONE,
+ Element::fromJSON(
+ "{\"origin\": \"test1.example\","
+ " \"class\": 1}"))),
+ isc::data::TypeError);
+
+ // class or origin is missing: result in assertion failure
+ if (!isc::util::unittests::runningOnValgrind()) {
+ EXPECT_DEATH_IF_SUPPORTED({
+ builder.handleCommand(Command(LOADZONE,
+ Element::fromJSON(
+ "{\"class\": \"IN\"}")));
+ }, "");
+ }
+
+ // zone doesn't exist in the data source
+ EXPECT_THROW(
+ builder.handleCommand(
+ Command(LOADZONE,
+ Element::fromJSON(
+ "{\"class\": \"IN\", \"origin\": \"xx\"}"))),
+ TestDataSrcClientsBuilder::InternalCommandError);
+
+ // origin is bogus
+ EXPECT_THROW(builder.handleCommand(
+ Command(LOADZONE,
+ Element::fromJSON(
+ "{\"class\": \"IN\", \"origin\": \"...\"}"))),
+ EmptyLabel);
+ EXPECT_THROW(builder.handleCommand(
+ Command(LOADZONE,
+ Element::fromJSON(
+ "{\"origin\": 10, \"class\": 1}"))),
+ isc::data::TypeError);
+}
+
} // unnamed namespace
diff --git a/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc b/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc
index 7d1eb4d..c37ef11 100644
--- a/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc
+++ b/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc
@@ -196,6 +196,55 @@ TEST(DataSrcClientsMgrTest, holder) {
EXPECT_THROW(TestDataSrcClientsMgr::Holder holder2(mgr), isc::Unexpected);
}
+TEST(DataSrcClientsMgrTest, reload) {
+ TestDataSrcClientsMgr mgr;
+ EXPECT_TRUE(FakeDataSrcClientsBuilder::started);
+ EXPECT_TRUE(FakeDataSrcClientsBuilder::command_queue->empty());
+
+ isc::data::ElementPtr args =
+ isc::data::Element::fromJSON("{ \"class\": \"IN\","
+ " \"origin\": \"example.com\" }");
+ mgr.loadZone(args);
+ EXPECT_EQ(1, FakeDataSrcClientsBuilder::command_queue->size());
+ mgr.loadZone(args);
+ EXPECT_EQ(2, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // Should fail with non-string 'class' value
+ args->set("class", Element::create(1));
+ EXPECT_THROW(mgr.loadZone(args), CommandError);
+ EXPECT_EQ(2, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // And with badclass
+ args->set("class", Element::create("BADCLASS"));
+ EXPECT_THROW(mgr.loadZone(args), CommandError);
+ EXPECT_EQ(2, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // Should succeed without 'class'
+ args->remove("class");
+ mgr.loadZone(args);
+ EXPECT_EQ(3, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // but fail without origin, without sending new commands
+ args->remove("origin");
+ EXPECT_THROW(mgr.loadZone(args), CommandError);
+ EXPECT_EQ(3, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // And for 'origin' that is not a string
+ args->set("origin", Element::create(1));
+ EXPECT_THROW(mgr.loadZone(args), CommandError);
+ EXPECT_EQ(3, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // And origin that is not a correct name
+ args->set("origin", Element::create(".."));
+ EXPECT_THROW(mgr.loadZone(args), CommandError);
+ EXPECT_EQ(3, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // same for empty data and data that is not a map
+ EXPECT_THROW(mgr.loadZone(isc::data::ConstElementPtr()), CommandError);
+ EXPECT_THROW(mgr.loadZone(isc::data::Element::createList()), CommandError);
+ EXPECT_EQ(3, FakeDataSrcClientsBuilder::command_queue->size());
+}
+
TEST(DataSrcClientsMgrTest, realThread) {
// Using the non-test definition with a real thread. Just checking
// no disruption happens.
diff --git a/src/bin/auth/tests/datasrc_util.h b/src/bin/auth/tests/datasrc_util.h
index 07ebc0c..9748332 100644
--- a/src/bin/auth/tests/datasrc_util.h
+++ b/src/bin/auth/tests/datasrc_util.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __AUTH_DATA_SOURCE_UTIL_H
-#define __AUTH_DATA_SOURCE_UTIL_H 1
+#ifndef AUTH_DATA_SOURCE_UTIL_H
+#define AUTH_DATA_SOURCE_UTIL_H 1
#include <dns/name.h>
#include <dns/rrclass.h>
@@ -51,7 +51,7 @@ createSQLite3DB(dns::RRClass zclass, const dns::Name& zname,
} // end of auth
} // end of isc
-#endif // __AUTH_DATA_SOURCE_UTIL_H
+#endif // AUTH_DATA_SOURCE_UTIL_H
// Local Variables:
// mode: c++
diff --git a/src/bin/auth/tests/statistics_unittest.cc b/src/bin/auth/tests/statistics_unittest.cc
index d2f5a5a..052a70e 100644
--- a/src/bin/auth/tests/statistics_unittest.cc
+++ b/src/bin/auth/tests/statistics_unittest.cc
@@ -27,345 +27,97 @@
#include <cc/session.h>
#include <auth/statistics.h>
+#include <auth/statistics_items.h>
#include <dns/tests/unittest_util.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
using namespace std;
using namespace isc::cc;
using namespace isc::dns;
using namespace isc::data;
+using isc::auth::statistics::Counters;
+using isc::auth::statistics::QRAttributes;
namespace {
-class AuthCountersTest : public ::testing::Test {
-private:
- class MockSession : public AbstractSession {
- public:
- MockSession() :
- // by default we return a simple "success" message.
- msg_(Element::fromJSON("{\"result\": [0, \"SUCCESS\"]}")),
- throw_session_error_(false), throw_session_timeout_(false)
- {}
- virtual void establish(const char* socket_file);
- virtual void disconnect();
- virtual int group_sendmsg(ConstElementPtr msg, string group,
- string instance, string to);
- virtual bool group_recvmsg(ConstElementPtr& envelope,
- ConstElementPtr& msg,
- bool nonblock, int seq);
- virtual void subscribe(string group, string instance);
- virtual void unsubscribe(string group, string instance);
- virtual void startRead(boost::function<void()> read_callback);
- virtual int reply(ConstElementPtr envelope, ConstElementPtr newmsg);
- virtual bool hasQueuedMsgs() const;
- virtual void setTimeout(size_t) {}
- virtual size_t getTimeout() const { return (0); };
-
- void setThrowSessionError(bool flag);
- void setThrowSessionTimeout(bool flag);
-
- void setMessage(ConstElementPtr msg) { msg_ = msg; }
-
- ConstElementPtr sent_msg;
- string msg_destination;
- private:
- ConstElementPtr msg_;
- bool throw_session_error_;
- bool throw_session_timeout_;
- };
-
+class CountersTest : public ::testing::Test {
protected:
- AuthCountersTest() : counters() {
- }
- ~AuthCountersTest() {
- }
- AuthCounters counters;
- // no need to be inherited from the original class here.
- class MockModuleSpec {
- public:
- bool validateStatistics(ConstElementPtr, const bool valid) const
- { return (valid); }
- };
- MockModuleSpec module_spec_;
+ CountersTest() : counters() {}
+ ~CountersTest() {}
+ Counters counters;
};
+// Test if the values of the counters are all zero except for the items
+// specified in except_for.
void
-AuthCountersTest::MockSession::establish(const char*) {}
-
-void
-AuthCountersTest::MockSession::disconnect() {}
-
-void
-AuthCountersTest::MockSession::subscribe(string, string)
-{}
-
-void
-AuthCountersTest::MockSession::unsubscribe(string, string)
-{}
-
-void
-AuthCountersTest::MockSession::startRead(boost::function<void()>)
-{}
-
-int
-AuthCountersTest::MockSession::reply(ConstElementPtr, ConstElementPtr) {
- return (-1);
-}
-
-bool
-AuthCountersTest::MockSession::hasQueuedMsgs() const {
- return (false);
-}
-
-int
-AuthCountersTest::MockSession::group_sendmsg(ConstElementPtr msg,
- string group, string, string)
-{
- if (throw_session_error_) {
- isc_throw(SessionError, "Session Error");
- }
- sent_msg = msg;
- msg_destination = group;
- return (0);
-}
-
-bool
-AuthCountersTest::MockSession::group_recvmsg(ConstElementPtr&,
- ConstElementPtr& msg, bool, int)
-{
- if (throw_session_timeout_) {
- isc_throw(SessionTimeout, "Session Timeout");
- }
- msg = msg_;
- return (true);
-}
-
-void
-AuthCountersTest::MockSession::setThrowSessionError(bool flag) {
- throw_session_error_ = flag;
-}
-
-void
-AuthCountersTest::MockSession::setThrowSessionTimeout(bool flag) {
- throw_session_timeout_ = flag;
-}
-
-TEST_F(AuthCountersTest, incrementUDPCounter) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
- EXPECT_NO_THROW(counters.inc(AuthCounters::SERVER_UDP_QUERY));
- // After increment, the counter should be 1.
- EXPECT_EQ(1, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
-}
-
-TEST_F(AuthCountersTest, incrementTCPCounter) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
- EXPECT_NO_THROW(counters.inc(AuthCounters::SERVER_TCP_QUERY));
- // After increment, the counter should be 1.
- EXPECT_EQ(1, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
-}
-
-TEST_F(AuthCountersTest, incrementInvalidCounter) {
- // Expect to throw an isc::OutOfRange
- EXPECT_THROW(counters.inc(AuthCounters::SERVER_COUNTER_TYPES),
- isc::OutOfRange);
-}
-
-TEST_F(AuthCountersTest, incrementOpcodeCounter) {
- // The counter should be initialized to 0. If we increment it by 1
- // the counter should be 1.
- for (int i = 0; i < 16; ++i) {
- EXPECT_EQ(0, counters.getCounter(Opcode(i)));
- counters.inc(Opcode(i));
- EXPECT_EQ(1, counters.getCounter(Opcode(i)));
- }
-}
-
-TEST_F(AuthCountersTest, incrementRcodeCounter) {
- // The counter should be initialized to 0. If we increment it by 1
- // the counter should be 1.
- for (int i = 0; i < 17; ++i) {
- EXPECT_EQ(0, counters.getCounter(Rcode(i)));
- counters.inc(Rcode(i));
- EXPECT_EQ(1, counters.getCounter(Rcode(i)));
- }
-}
-
-void
-opcodeDataCheck(ConstElementPtr data, const int expected[16]) {
- const char* item_names[] = {
- "query", "iquery", "status", "reserved3", "notify", "update",
- "reserved6", "reserved7", "reserved8", "reserved9", "reserved10",
- "reserved11", "reserved12", "reserved13", "reserved14", "reserved15",
- NULL
- };
- int i;
- for (i = 0; i < 16; ++i) {
- ASSERT_NE(static_cast<const char*>(NULL), item_names[i]);
- const string item_name = "opcode." + string(item_names[i]);
- if (expected[i] == 0) {
- EXPECT_FALSE(data->get(item_name));
- } else {
- EXPECT_EQ(expected[i], data->get(item_name)->intValue());
- }
- }
- // We should have examined all names
- ASSERT_EQ(static_cast<const char*>(NULL), item_names[i]);
-}
-
-void
-rcodeDataCheck(ConstElementPtr data, const int expected[17]) {
- const char* item_names[] = {
- "noerror", "formerr", "servfail", "nxdomain", "notimp", "refused",
- "yxdomain", "yxrrset", "nxrrset", "notauth", "notzone", "reserved11",
- "reserved12", "reserved13", "reserved14", "reserved15", "badvers",
- NULL
- };
- int i;
- for (i = 0; i < 17; ++i) {
- ASSERT_NE(static_cast<const char*>(NULL), item_names[i]);
- const string item_name = "rcode." + string(item_names[i]);
- if (expected[i] == 0) {
- EXPECT_FALSE(data->get(item_name));
- } else {
- EXPECT_EQ(expected[i], data->get(item_name)->intValue());
+checkCountersAllZeroExcept(const isc::data::ConstElementPtr counters,
+ const std::set<std::string>& except_for) {
+ std::map<std::string, ConstElementPtr> stats_map = counters->mapValue();
+
+ for (std::map<std::string, ConstElementPtr>::const_iterator
+ i = stats_map.begin(), e = stats_map.end();
+ i != e;
+ ++i)
+ {
+ int expect = 0;
+ if (except_for.count(i->first) != 0) {
+ expect = 1;
}
+ EXPECT_EQ(expect, i->second->intValue()) << "Expected counter "
+ << i->first << " = " << expect << ", actual: "
+ << i->second->intValue();
}
- // We should have examined all names
- ASSERT_EQ(static_cast<const char*>(NULL), item_names[i]);
}
-TEST_F(AuthCountersTest, getStatisticsWithoutValidator) {
- // Get statistics data.
- // Validate if it answers correct data.
+TEST_F(CountersTest, incrementNormalQuery) {
+ Message response(Message::RENDER);
+ QRAttributes qrattrs;
+ std::set<std::string> expect_nonzero;
- // Counters should be initialized to 0.
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
+ expect_nonzero.clear();
+ checkCountersAllZeroExcept(counters.getStatistics(), expect_nonzero);
- // UDP query counter is set to 2.
- counters.inc(AuthCounters::SERVER_UDP_QUERY);
- counters.inc(AuthCounters::SERVER_UDP_QUERY);
- // TCP query counter is set to 1.
- counters.inc(AuthCounters::SERVER_TCP_QUERY);
- ConstElementPtr statistics_data = counters.getStatistics();
+ qrattrs.setQueryIPVersion(AF_INET6);
+ qrattrs.setQueryTransportProtocol(IPPROTO_UDP);
+ qrattrs.setQueryOpCode(Opcode::QUERY_CODE);
+ qrattrs.setQueryEDNS(true, false);
+ qrattrs.setQueryDO(true);
+ qrattrs.answerWasSent();
- // UDP query counter is 2 and TCP query counter is 1.
- EXPECT_EQ(2, statistics_data->get("queries.udp")->intValue());
- EXPECT_EQ(1, statistics_data->get("queries.tcp")->intValue());
+ response.setRcode(Rcode::REFUSED());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::AAAA()));
- // By default opcode counters are all 0 and omitted
- const int opcode_results[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 };
- opcodeDataCheck(statistics_data, opcode_results);
- // By default rcode counters are all 0 and omitted
- const int rcode_results[17] = { 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 };
- rcodeDataCheck(statistics_data, rcode_results);
-}
+ counters.inc(qrattrs, response);
-void
-updateOpcodeCounters(AuthCounters &counters, const int expected[16]) {
- for (int i = 0; i < 16; ++i) {
- for (int j = 0; j < expected[i]; ++j) {
- counters.inc(Opcode(i));
- }
- }
+ expect_nonzero.clear();
+ expect_nonzero.insert("opcode.query");
+ expect_nonzero.insert("queries.udp");
+ expect_nonzero.insert("rcode.refused");
+ checkCountersAllZeroExcept(counters.getStatistics(), expect_nonzero);
}
-void
-updateRcodeCounters(AuthCounters &counters, const int expected[17]) {
- for (int i = 0; i < 17; ++i) {
- for (int j = 0; j < expected[i]; ++j) {
- counters.inc(Rcode(i));
+int
+countTreeElements(const struct CounterTypeTree* tree) {
+ int count = 0;
+ for (int i = 0; tree[i].name != NULL; ++i) {
+ if (tree[i].sub_tree == NULL) {
+ ++count;
+ } else {
+ count += countTreeElements(tree[i].sub_tree);
}
}
+ return count;
}
-TEST_F(AuthCountersTest, getStatisticsWithOpcodeCounters) {
- // Increment some of the opcode counters. Then they should appear in the
- // submitted data; others shouldn't
- const int opcode_results[16] = { 1, 2, 3, 0, 4, 5, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 };
- updateOpcodeCounters(counters, opcode_results);
- ConstElementPtr statistics_data = counters.getStatistics();
- opcodeDataCheck(statistics_data, opcode_results);
-}
-
-TEST_F(AuthCountersTest, getStatisticsWithAllOpcodeCounters) {
- // Increment all opcode counters. Then they should appear in the
- // submitted data.
- const int opcode_results[16] = { 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1 };
- updateOpcodeCounters(counters, opcode_results);
- ConstElementPtr statistics_data = counters.getStatistics();
- opcodeDataCheck(statistics_data, opcode_results);
-}
-
-TEST_F(AuthCountersTest, getStatisticsWithRcodeCounters) {
- // Increment some of the rcode counters. Then they should appear in the
- // submitted data; others shouldn't
- const int rcode_results[17] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,
- 10, 0, 0, 0, 0, 0, 0, 11 };
- updateRcodeCounters(counters, rcode_results);
- ConstElementPtr statistics_data = counters.getStatistics();
- rcodeDataCheck(statistics_data, rcode_results);
+TEST(StatisticsItemsTest, QRItemNamesCheck) {
+ EXPECT_EQ(QR_COUNTER_TYPES, countTreeElements(QRCounterTree));
}
-TEST_F(AuthCountersTest, getStatisticsWithAllRcodeCounters) {
- // Increment all rcode counters. Then they should appear in the
- // submitted data.
- const int rcode_results[17] = { 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1 };
- updateOpcodeCounters(counters, rcode_results);
- ConstElementPtr statistics_data = counters.getStatistics();
- opcodeDataCheck(statistics_data, rcode_results);
-}
-
-TEST_F(AuthCountersTest, getStatisticsWithValidator) {
-
- //a validator for the unittest
- AuthCounters::validator_type validator;
- ConstElementPtr el;
-
- // Get statistics data with correct statistics validator.
- validator = boost::bind(
- &AuthCountersTest::MockModuleSpec::validateStatistics,
- &module_spec_, _1, true);
-
- EXPECT_TRUE(validator(el));
-
- // register validator to AuthCounters
- counters.registerStatisticsValidator(validator);
-
- // Counters should be initialized to 0.
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
-
- // UDP query counter is set to 2.
- counters.inc(AuthCounters::SERVER_UDP_QUERY);
- counters.inc(AuthCounters::SERVER_UDP_QUERY);
- // TCP query counter is set to 1.
- counters.inc(AuthCounters::SERVER_TCP_QUERY);
-
- // checks the value returned by getStatistics
- ConstElementPtr statistics_data = counters.getStatistics();
-
- // UDP query counter is 2 and TCP query counter is 1.
- EXPECT_EQ(2, statistics_data->get("queries.udp")->intValue());
- EXPECT_EQ(1, statistics_data->get("queries.tcp")->intValue());
-
- // Get statistics data with incorrect statistics validator.
- validator = boost::bind(
- &AuthCountersTest::MockModuleSpec::validateStatistics,
- &module_spec_, _1, false);
-
- EXPECT_FALSE(validator(el));
-
- counters.registerStatisticsValidator(validator);
-
- // checks the value returned by getStatistics
- EXPECT_FALSE(counters.getStatistics());
-}
}
diff --git a/src/bin/auth/tests/test_datasrc_clients_mgr.cc b/src/bin/auth/tests/test_datasrc_clients_mgr.cc
index 44c8b7d..82937c0 100644
--- a/src/bin/auth/tests/test_datasrc_clients_mgr.cc
+++ b/src/bin/auth/tests/test_datasrc_clients_mgr.cc
@@ -50,6 +50,8 @@ TestDataSrcClientsBuilder::doNoop() {
isc_throw(Exception, "test exception");
case TestMutex::INTEGER:
throw 42;
+ case TestMutex::INTERNAL:
+ isc_throw(InternalCommandError, "internal error, should be ignored");
}
}
} // namespace datasrc_clientmgr_internal
diff --git a/src/bin/auth/tests/test_datasrc_clients_mgr.h b/src/bin/auth/tests/test_datasrc_clients_mgr.h
index 4abffa2..9b1a367 100644
--- a/src/bin/auth/tests/test_datasrc_clients_mgr.h
+++ b/src/bin/auth/tests/test_datasrc_clients_mgr.h
@@ -43,7 +43,8 @@ public:
// None: no throw from specialized doNoop()
// EXCLASS: throw some exception class object
// INTEGER: throw an integer
- enum ExceptionFromNoop { NONE, EXCLASS, INTEGER };
+ // INTERNAL: internal error (shouldn't terminate the thread)
+ enum ExceptionFromNoop { NONE, EXCLASS, INTEGER, INTERNAL };
TestMutex() : lock_count(0), unlock_count(0), noop_count(0),
throw_from_noop(NONE)
diff --git a/src/bin/bindctl/tests/bindctl_test.py b/src/bin/bindctl/tests/bindctl_test.py
index f598472..b9af5c2 100644
--- a/src/bin/bindctl/tests/bindctl_test.py
+++ b/src/bin/bindctl/tests/bindctl_test.py
@@ -511,10 +511,7 @@ class TestBindCmdInterpreter(unittest.TestCase):
def test_csv_file_dir(self):
# Checking default value
- if "HOME" in os.environ:
- home_dir = os.environ["HOME"]
- else:
- home_dir = pwd.getpwnam(getpass.getuser()).pw_dir
+ home_dir = pwd.getpwnam(getpass.getuser()).pw_dir
self.assertEqual(home_dir + os.sep + '.bind10' + os.sep,
bindcmd.BindCmdInterpreter().csv_file_dir)
diff --git a/src/bin/cfgmgr/Makefile.am b/src/bin/cfgmgr/Makefile.am
index e9e0cca..9c73f79 100644
--- a/src/bin/cfgmgr/Makefile.am
+++ b/src/bin/cfgmgr/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = . plugins tests
+SUBDIRS = . plugins local_plugins tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
diff --git a/src/bin/cfgmgr/local_plugins/Makefile.am b/src/bin/cfgmgr/local_plugins/Makefile.am
new file mode 100644
index 0000000..2f4dd39
--- /dev/null
+++ b/src/bin/cfgmgr/local_plugins/Makefile.am
@@ -0,0 +1,11 @@
+# Nothing is installed from this directory. This local_plugins
+# directory overrides the plugins directory when lettuce is run, and the
+# spec file here is used to serve the static zone from the source tree
+# for testing (instead of installation prefix).
+
+noinst_DATA = datasrc.spec
+
+datasrc.spec: ../plugins/datasrc.spec.pre
+ $(SED) -e "s|@@STATIC_ZONE_FILE@@|$(abs_top_builddir)/src/lib/datasrc/static.zone|;s|@@SQLITE3_DATABASE_FILE@@|$(abs_top_builddir)/local.zone.sqlite3|" ../plugins/datasrc.spec.pre >$@
+
+CLEANFILES = datasrc.spec
diff --git a/src/bin/cfgmgr/plugins/Makefile.am b/src/bin/cfgmgr/plugins/Makefile.am
index e6ed127..5967abd 100644
--- a/src/bin/cfgmgr/plugins/Makefile.am
+++ b/src/bin/cfgmgr/plugins/Makefile.am
@@ -3,7 +3,7 @@ SUBDIRS = tests
EXTRA_DIST = README logging.spec tsig_keys.spec
datasrc.spec: datasrc.spec.pre
- $(SED) -e "s|@@PKGDATADIR@@|$(pkgdatadir)|;s|@@LOCALSTATEDIR@@|$(localstatedir)|" datasrc.spec.pre >$@
+ $(SED) -e "s|@@STATIC_ZONE_FILE@@|$(pkgdatadir)/static.zone|;s|@@SQLITE3_DATABASE_FILE@@|$(localstatedir)/$(PACKAGE)/zone.sqlite3|" datasrc.spec.pre >$@
config_plugindir = @prefix@/share/@PACKAGE@/config_plugins
config_plugin_DATA = logging.spec tsig_keys.spec datasrc.spec
diff --git a/src/bin/cfgmgr/plugins/datasrc.spec.pre.in b/src/bin/cfgmgr/plugins/datasrc.spec.pre.in
index f2c6a97..6d5bd77 100644
--- a/src/bin/cfgmgr/plugins/datasrc.spec.pre.in
+++ b/src/bin/cfgmgr/plugins/datasrc.spec.pre.in
@@ -12,7 +12,7 @@
{
"type": "sqlite3",
"params": {
- "database_file": "@@LOCALSTATEDIR@@/@PACKAGE@/zone.sqlite3"
+ "database_file": "@@SQLITE3_DATABASE_FILE@@"
}
}
],
@@ -20,7 +20,7 @@
{
"type": "static",
"cache-enable": false,
- "params": "@@PKGDATADIR@@/static.zone"
+ "params": "@@STATIC_ZONE_FILE@@"
}
]
},
diff --git a/src/bin/dhcp4/dhcp4_log.h b/src/bin/dhcp4/dhcp4_log.h
index 3717b62..b042ea4 100644
--- a/src/bin/dhcp4/dhcp4_log.h
+++ b/src/bin/dhcp4/dhcp4_log.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DHCP4_LOG__H
-#define __DHCP4_LOG__H
+#ifndef DHCP4_LOG_H
+#define DHCP4_LOG_H
#include <log/macros.h>
#include <log/logger_support.h>
@@ -56,4 +56,4 @@ extern isc::log::Logger dhcp4_logger;
} // namespace dhcp4
} // namespace isc
-#endif // __DHCP4_LOG__H
+#endif // DHCP4_LOG_H
diff --git a/src/bin/dhcp6/Makefile.am b/src/bin/dhcp6/Makefile.am
index 68aadea..55fe619 100644
--- a/src/bin/dhcp6/Makefile.am
+++ b/src/bin/dhcp6/Makefile.am
@@ -60,6 +60,7 @@ b10_dhcp6_CXXFLAGS = -Wno-unused-parameter
endif
b10_dhcp6_LDADD = $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
+b10_dhcp6_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
diff --git a/src/bin/dhcp6/config_parser.cc b/src/bin/dhcp6/config_parser.cc
index dbffc40..0fca770 100644
--- a/src/bin/dhcp6/config_parser.cc
+++ b/src/bin/dhcp6/config_parser.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
@@ -21,6 +21,7 @@
#include <boost/scoped_ptr.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
+#include <util/encode/hex.h>
#include <asiolink/io_address.h>
#include <cc/data.h>
#include <config/ccsession.h>
@@ -60,12 +61,18 @@ typedef std::map<string, string> StringStorage;
/// no subnet object created yet to store them.
typedef std::vector<Pool6Ptr> PoolStorage;
+/// @brief Collection of options.
+typedef std::vector<OptionPtr> OptionStorage;
+
/// @brief Global uint32 parameters that will be used as defaults.
Uint32Storage uint32_defaults;
/// @brief global string parameters that will be used as defaults.
StringStorage string_defaults;
+/// @brief Global storage for options that will be used as defaults.
+OptionStorage option_defaults;
+
/// @brief a dummy configuration parser
///
/// It is a debugging parser. It does not configure anything,
@@ -135,6 +142,9 @@ protected:
///
/// For overview of usability of this generic purpose parser, see
/// \ref dhcpv6-config-inherit page.
+///
+/// @todo this class should be turned into the template class which
+/// will handle all uintX_types of data (see ticket #2415).
class Uint32Parser : public DhcpConfigParser {
public:
@@ -151,12 +161,37 @@ public:
///
/// @param value pointer to the content of parsed values
virtual void build(ConstElementPtr value) {
+ bool parse_error = false;
+ // Cast the provided value to int64 value to check.
+ int64_t int64value = 0;
try {
- value_ = boost::lexical_cast<uint32_t>(value->str());
- } catch (const boost::bad_lexical_cast &) {
+ // Parsing the value as a int64 value allows to
+ // check if the provided value is within the range
+ // of uint32_t (is not negative or greater than
+ // maximal uint32_t value.
+ int64value = boost::lexical_cast<int64_t>(value->str());
+ } catch (const boost::bad_lexical_cast&) {
+ parse_error = true;
+ }
+ if (!parse_error) {
+ if ((int64value < 0) ||
+ (int64value > std::numeric_limits<uint32_t>::max())) {
+ parse_error = true;
+ } else {
+ try {
+ value_ = boost::lexical_cast<uint32_t>(value->str());
+ } catch (const boost::bad_lexical_cast &) {
+ parse_error = true;
+ }
+ }
+
+ }
+
+ if (parse_error) {
isc_throw(BadValue, "Failed to parse value " << value->str()
<< " as unsigned 32-bit integer.");
}
+
storage_->insert(pair<string, uint32_t>(param_name_, value_));
}
@@ -445,6 +480,259 @@ protected:
PoolStorage* pools_;
};
+/// @brief Parser for option data value.
+///
+/// This parser parses configuration entries that specify value of
+/// a single option. These entries include option name, option code
+/// and data carried by the option. If parsing is successful than
+/// instance of an option is created and added to the storage provided
+/// by the calling class.
+///
+/// @todo This class parses and validates option name. However it is
+/// not used anywhere util support for option spaces is implemented
+/// (see tickets #2319, #2314). When option spaces are implemented
+/// there will be a way to reference the particular option using
+/// its type (code) or option name.
+class OptionDataParser : public DhcpConfigParser {
+public:
+
+ /// @brief Constructor.
+ ///
+ /// Class constructor.
+ OptionDataParser(const std::string&)
+ : options_(NULL) { }
+
+ /// @brief Parses the single option data.
+ ///
+ /// This method parses the data of a single option from the configuration.
+ /// The option data includes option name, option code and data being
+ /// carried by this option. Eventually it creates the instance of the
+ /// option.
+ ///
+ /// @warning setStorage must be called with valid storage pointer prior
+ /// to calling this method.
+ ///
+ /// @param option_data_entries collection of entries that define value
+ /// for a particular option.
+ /// @throw Dhcp6ConfigError if invalid parameter specified in
+ /// the configuration.
+ /// @throw isc::InvalidOperation if failed to set storage prior to
+ /// calling build.
+ /// @throw isc::BadValue if option data storage is invalid.
+ virtual void build(ConstElementPtr option_data_entries) {
+ if (options_ == NULL) {
+ isc_throw(isc::InvalidOperation, "Parser logic error: storage must be set before "
+ "parsing option data.");
+ }
+ BOOST_FOREACH(ConfigPair param, option_data_entries->mapValue()) {
+ ParserPtr parser;
+ if (param.first == "name") {
+ boost::shared_ptr<StringParser>
+ name_parser(dynamic_cast<StringParser*>(StringParser::Factory(param.first)));
+ if (name_parser) {
+ name_parser->setStorage(&string_values_);
+ parser = name_parser;
+ }
+ } else if (param.first == "code") {
+ boost::shared_ptr<Uint32Parser>
+ code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::Factory(param.first)));
+ if (code_parser) {
+ code_parser->setStorage(&uint32_values_);
+ parser = code_parser;
+ }
+ } else if (param.first == "data") {
+ boost::shared_ptr<StringParser>
+ value_parser(dynamic_cast<StringParser*>(StringParser::Factory(param.first)));
+ if (value_parser) {
+ value_parser->setStorage(&string_values_);
+ parser = value_parser;
+ }
+ } else {
+ isc_throw(Dhcp6ConfigError,
+ "Parser error: option-data parameter not supported: "
+ << param.first);
+ }
+ parser->build(param.second);
+ }
+ // Try to create the option instance.
+ createOption();
+ }
+
+ /// @brief Does nothing.
+ ///
+ /// This function does noting because option data is committed
+ /// by a higher level parser.
+ virtual void commit() { }
+
+ /// @brief Set storage for the parser.
+ ///
+ /// Sets storage for the parser. This storage points to the
+ /// vector of options and is used by multiple instances of
+ /// OptionDataParser. Each instance creates exactly one object
+ /// of dhcp::Option or derived type and appends it to this
+ /// storage.
+ ///
+ /// @param storage pointer to the options storage
+ void setStorage(OptionStorage* storage) {
+ options_ = storage;
+ }
+
+private:
+
+ /// @brief Create option instance.
+ ///
+ /// Creates an instance of an option and adds it to the provided
+ /// options storage. If the option data parsed by \ref build function
+ /// are invalid or insufficient it emits exception.
+ ///
+ /// @warning this function does not check if options_ storage pointer
+ /// is intitialized but this is not needed here because it is checked in
+ /// \ref build function.
+ ///
+ /// @throw Dhcp6ConfigError if parameters provided in the configuration
+ /// are invalid.
+ void createOption() {
+ // Option code is held in the uint32_t storage but is supposed to
+ // be uint16_t value. We need to check that value in the configuration
+ // does not exceed range of uint16_t and is not zero.
+ uint32_t option_code = getUint32Param("code");
+ if (option_code == 0) {
+ isc_throw(Dhcp6ConfigError, "Parser error: value of 'code' must not"
+ << " be equal to zero. Option code '0' is reserved in"
+ << " DHCPv6.");
+ } else if (option_code > std::numeric_limits<uint16_t>::max()) {
+ isc_throw(Dhcp6ConfigError, "Parser error: value of 'code' must not"
+ << " exceed " << std::numeric_limits<uint16_t>::max());
+ }
+ // Check the option name has been specified, is non-empty and does not
+ // contain spaces.
+ // @todo possibly some more restrictions apply here?
+ std::string option_name = getStringParam("name");
+ if (option_name.empty()) {
+ isc_throw(Dhcp6ConfigError, "Parser error: option name must not be"
+ << " empty");
+ } else if (option_name.find(" ") != std::string::npos) {
+ isc_throw(Dhcp6ConfigError, "Parser error: option name must not contain"
+ << " spaces");
+ }
+
+ std::string option_data = getStringParam("data");
+ std::vector<uint8_t> binary;
+ try {
+ util::encode::decodeHex(option_data, binary);
+ } catch (...) {
+ isc_throw(Dhcp6ConfigError, "Parser error: option data is not a valid"
+ << " string of hexadecimal digits: " << option_data);
+ }
+
+ // Create the actual option.
+ // @todo Currently we simply create dhcp::Option instance here but we will
+ // need to use dedicated factory functions once the option definitions are
+ // created for all options.
+ OptionPtr option(new Option(Option::V6, static_cast<uint16_t>(option_code),
+ binary));
+
+ // If option is created succesfully, add it to the storage.
+ options_->push_back(option);
+ }
+
+ /// @brief Get a parameter from the strings storage.
+ ///
+ /// @param param_id parameter identifier.
+ /// @throw Dhcp6ConfigError if parameter has not been found.
+ std::string getStringParam(const std::string& param_id) const {
+ StringStorage::const_iterator param = string_values_.find(param_id);
+ if (param == string_values_.end()) {
+ isc_throw(Dhcp6ConfigError, "Parser error: option-data parameter"
+ << " '" << param_id << "' not specified");
+ }
+ return (param->second);
+ }
+
+ /// @brief Get a parameter from the uint32 values storage.
+ ///
+ /// @param param_id parameter identifier.
+ /// @throw Dhcp6ConfigError if parameter has not been found.
+ uint32_t getUint32Param(const std::string& param_id) const {
+ Uint32Storage::const_iterator param = uint32_values_.find(param_id);
+ if (param == uint32_values_.end()) {
+ isc_throw(Dhcp6ConfigError, "Parser error: option-data parameter"
+ << " '" << param_id << "' not specified");
+ }
+ return (param->second);
+ }
+
+ /// Storage for uint32 values (e.g. option code).
+ Uint32Storage uint32_values_;
+ /// Storage for string values (e.g. option name or data).
+ StringStorage string_values_;
+ /// Pointer to options storage. This storage is provided by
+ /// the calling class and is shared by all OptionDataParser objects.
+ OptionStorage* options_;
+};
+
+/// @brief Parser for option data values with ina subnet.
+///
+/// This parser iterates over all entries that define options
+/// data for a particular subnet and creates a collection of options.
+/// If parsing is successful, all these options are added to the Subnet
+/// object.
+class OptionDataListParser : public DhcpConfigParser {
+public:
+
+ /// @brief Constructor.
+ ///
+ /// Unless otherwise specified, parsed options will be stored in
+ /// a global option containers (option_default). That storage location
+ /// is overriden on a subnet basis.
+ OptionDataListParser(const std::string&)
+ : options_(&option_defaults) { }
+
+ /// @brief Parses entries that define options' data for a subnet.
+ ///
+ /// This method iterates over all entries that define option data
+ /// for options within a single subnet and creates options' instances.
+ ///
+ /// @param option_data_list pointer to a list of options' data sets.
+ /// @throw Dhcp6ConfigError if option parsing failed.
+ void build(ConstElementPtr option_data_list) {
+ BOOST_FOREACH(ConstElementPtr option_value, option_data_list->listValue()) {
+ boost::shared_ptr<OptionDataParser> parser(new OptionDataParser("option-data"));
+ // options_ member will hold instances of all options thus
+ // each OptionDataParser takes it as a storage.
+ parser->setStorage(options_);
+ // Build the instance of a singkle option.
+ parser->build(option_value);
+ }
+ }
+
+ /// @brief Set storage for option instances.
+ ///
+ /// @param storage pointer to options storage.
+ void setStorage(OptionStorage* storage) {
+ options_ = storage;
+ }
+
+
+ /// @brief Does nothing.
+ ///
+ /// @todo Currently this function does nothing but in the future
+ /// we may need to extend it to commit at this level.
+ void commit() { }
+
+ /// @brief Create DhcpDataListParser object
+ ///
+ /// @param param_name param name.
+ ///
+ /// @return DhcpConfigParser object.
+ static DhcpConfigParser* Factory(const std::string& param_name) {
+ return (new OptionDataListParser(param_name));
+ }
+
+ /// Pointer to options instances storage.
+ OptionStorage* options_;
+};
+
/// @brief this class parses a single subnet
///
/// This class parses the whole subnet definition. It creates parsers
@@ -464,35 +752,36 @@ public:
void build(ConstElementPtr subnet) {
BOOST_FOREACH(ConfigPair param, subnet->mapValue()) {
-
ParserPtr parser(createSubnet6ConfigParser(param.first));
-
- // if this is an Uint32 parser, tell it to store the values
- // in values_, rather than in global storage
- boost::shared_ptr<Uint32Parser> uintParser =
- boost::dynamic_pointer_cast<Uint32Parser>(parser);
- if (uintParser) {
- uintParser->setStorage(&uint32_values_);
- } else {
-
- boost::shared_ptr<StringParser> stringParser =
- boost::dynamic_pointer_cast<StringParser>(parser);
- if (stringParser) {
- stringParser->setStorage(&string_values_);
- } else {
-
- boost::shared_ptr<PoolParser> poolParser =
- boost::dynamic_pointer_cast<PoolParser>(parser);
- if (poolParser) {
- poolParser->setStorage(&pools_);
- }
- }
+ // The actual type of the parser is unknown here. We have to discover
+ // parser type here to invoke corresponding setStorage function on it.
+ // We discover parser type by trying to cast the parser to various
+ // parser types and checking which one was successful. For this one
+ // a setStorage and build methods are invoked.
+
+ // Try uint32 type parser.
+ if (buildParser<Uint32Parser, Uint32Storage >(parser, uint32_values_,
+ param.second)) {
+ // Storage set, build invoked on the parser, proceed with
+ // next configuration element.
+ continue;
+ }
+ // Try string type parser.
+ if (buildParser<StringParser, StringStorage >(parser, string_values_,
+ param.second)) {
+ continue;
+ }
+ // Try pools parser.
+ if (buildParser<PoolParser, PoolStorage >(parser, pools_,
+ param.second)) {
+ continue;
+ }
+ // Try option data parser.
+ if (buildParser<OptionDataListParser, OptionStorage >(parser, options_,
+ param.second)) {
+ continue;
}
-
- parser->build(param.second);
- parsers_.push_back(parser);
}
-
// Ok, we now have subnet parsed
}
@@ -540,10 +829,78 @@ public:
subnet->addPool6(*it);
}
+ const Subnet::OptionContainer& options = subnet->getOptions();
+ const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
+
+ // Add subnet specific options.
+ BOOST_FOREACH(OptionPtr option, options_) {
+ Subnet::OptionContainerTypeRange range = idx.equal_range(option->getType());
+ if (std::distance(range.first, range.second) > 0) {
+ LOG_WARN(dhcp6_logger, DHCP6_CONFIG_OPTION_DUPLICATE)
+ .arg(option->getType()).arg(addr.toText());
+ }
+ subnet->addOption(option);
+ }
+
+ // Check all global options and add them to the subnet object if
+ // they have been configured in the global scope. If they have been
+ // configured in the subnet scope we don't add global option because
+ // the one configured in the subnet scope always takes precedense.
+ BOOST_FOREACH(OptionPtr option, option_defaults) {
+ // Get all options specified locally in the subnet and having
+ // code equal to global option's code.
+ Subnet::OptionContainerTypeRange range = idx.equal_range(option->getType());
+ // @todo: In the future we will be searching for options using either
+ // option code or namespace. Currently we have only the option
+ // code available so if there is at least one option found with the
+ // specific code we don't add globally configured option.
+ // @todo with this code the first globally configured option
+ // with the given code will be added to a subnet. We may
+ // want to issue warning about dropping configuration of
+ // global option if one already exsist.
+ if (std::distance(range.first, range.second) == 0) {
+ subnet->addOption(option);
+ }
+ }
+
CfgMgr::instance().addSubnet6(subnet);
}
-protected:
+private:
+
+ /// @brief Set storage for a parser and invoke build.
+ ///
+ /// This helper method casts the provided parser pointer to specified
+ /// type. If cast is successful it sets the corresponding storage for
+ /// this parser, invokes build on it and save the parser.
+ ///
+ /// @tparam T parser type to which parser argument should be cast.
+ /// @tparam Y storage type for the specified parser type.
+ /// @param parser parser on which build must be invoked.
+ /// @param storage reference to a storage that will be set for a parser.
+ /// @param subnet subnet element read from the configuration and being parsed.
+ /// @return true if parser pointer was successfully cast to specialized
+ /// parser type provided as Y.
+ template<typename T, typename Y>
+ bool buildParser(const ParserPtr& parser, Y& storage, const ConstElementPtr& subnet) {
+ // We need to cast to T in order to set storage for the parser.
+ boost::shared_ptr<T> cast_parser = boost::dynamic_pointer_cast<T>(parser);
+ // It is common that this cast is not successful because we try to cast to all
+ // supported parser types as we don't know the type of a parser in advance.
+ if (cast_parser) {
+ // Cast, successful so we go ahead with setting storage and actual parse.
+ cast_parser->setStorage(&storage);
+ parser->build(subnet);
+ parsers_.push_back(parser);
+ // We indicate that cast was successful so as the calling function
+ // may skip attempts to cast to other parser types and proceed to
+ // next element.
+ return (true);
+ }
+ // It was not successful. Indicate that another parser type
+ // should be tried.
+ return (false);
+ }
/// @brief creates parsers for entries in subnet definition
///
@@ -569,6 +926,10 @@ protected:
factories.insert(pair<string, ParserFactory*>(
"pool", PoolParser::Factory));
+ factories.insert(pair<string, ParserFactory*>(
+ "option-data", OptionDataListParser::Factory));
+
+
FactoryMap::iterator f = factories.find(config_id);
if (f == factories.end()) {
// Used for debugging only.
@@ -622,6 +983,9 @@ protected:
/// storage for pools belonging to this subnet
PoolStorage pools_;
+ /// storage for options belonging to this subnet
+ OptionStorage options_;
+
/// parsers are stored here
ParserCollection parsers_;
};
@@ -698,7 +1062,6 @@ public:
DhcpConfigParser* createGlobalDhcpConfigParser(const std::string& config_id) {
FactoryMap factories;
- //
factories.insert(pair<string, ParserFactory*>(
"preferred-lifetime", Uint32Parser::Factory));
factories.insert(pair<string, ParserFactory*>(
@@ -714,6 +1077,9 @@ DhcpConfigParser* createGlobalDhcpConfigParser(const std::string& config_id) {
"subnet6", Subnets6ListConfigParser::Factory));
factories.insert(pair<string, ParserFactory*>(
+ "option-data", OptionDataListParser::Factory));
+
+ factories.insert(pair<string, ParserFactory*>(
"version", StringParser::Factory));
FactoryMap::iterator f = factories.find(config_id);
@@ -749,6 +1115,12 @@ configureDhcp6Server(Dhcpv6Srv& , ConstElementPtr config_set) {
"Null pointer is passed to configuration parser");
}
+ /// Reset global storage. Containers being reset below may contain
+ /// data from the previous configuration attempts.
+ option_defaults.clear();
+ uint32_defaults.clear();
+ string_defaults.clear();
+
/// @todo: append most essential info here (like "2 new subnets configured")
string config_details;
diff --git a/src/bin/dhcp6/dhcp6.dox b/src/bin/dhcp6/dhcp6.dox
index fe842de..c234f40 100644
--- a/src/bin/dhcp6/dhcp6.dox
+++ b/src/bin/dhcp6/dhcp6.dox
@@ -35,7 +35,7 @@
This method iterates over list of received configuration elements and creates a
list of parsers for each received entry. Parser is an object that is derived
- from a \ref isc::dhcp::Dhcp6ConfigParser class. Once a parser is created
+ from a \ref isc::dhcp::DhcpConfigParser class. Once a parser is created
(constructor), its value is set (using build() method). Once all parsers are
build, the configuration is then applied ("commited") and commit() method is
called.
@@ -51,7 +51,7 @@
@section dhcpv6-config-inherit DHCPv6 Configuration Inheritance
- One notable useful features of DHCP configuration is its parameter inheritance.
+ One notable useful feature of DHCP configuration is its parameter inheritance.
For example, renew-timer value may be specified at a global scope and it then
applies to all subnets. However, some subnets may have it overwritten with more
specific values that takes precedence over global values that are considered
@@ -64,7 +64,7 @@
phase (commit() method), appropriate parsers can use apply parameter inheritance.
Debugging configuration parser may be confusing. Therefore there is a special
- class called \ref isc::dhcp::DummyParser. It does not configure anything, but just
+ class called \ref isc::dhcp::DebugParser. It does not configure anything, but just
accepts any parameter of any type. If requested to commit configuration, it will
print out received parameter name and its value. This class is not currently used,
but it is convenient to have it every time a new parameter is added to DHCP
@@ -76,4 +76,6 @@
simple as possible. In fact, currently the code has to call Subnet6->getT1() and
do not implement any fancy inheritance logic.
+ @todo Add section about setting up options and their definitions with bindctl.
+
*/
diff --git a/src/bin/dhcp6/dhcp6.spec b/src/bin/dhcp6/dhcp6.spec
index f35f606..c5e9565 100644
--- a/src/bin/dhcp6/dhcp6.spec
+++ b/src/bin/dhcp6/dhcp6.spec
@@ -40,6 +40,37 @@
"item_default": 4000
},
+ { "item_name": "option-data",
+ "item_type": "list",
+ "item_optional": false,
+ "item_default": [],
+ "list_item_spec":
+ {
+ "item_name": "single-option-data",
+ "item_type": "map",
+ "item_optional": false,
+ "item_default": {},
+ "map_item_spec": [
+ {
+ "item_name": "name",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": ""
+ },
+
+ { "item_name": "code",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 0
+ },
+ { "item_name": "data",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": ""
+ } ]
+ }
+ },
+
{ "item_name": "subnet6",
"item_type": "list",
"item_optional": false,
@@ -92,10 +123,40 @@
"item_optional": false,
"item_default": ""
}
- }
- ]
- }
- }
+ },
+ { "item_name": "option-data",
+ "item_type": "list",
+ "item_optional": false,
+ "item_default": [],
+ "list_item_spec":
+ {
+ "item_name": "single-option-data",
+ "item_type": "map",
+ "item_optional": false,
+ "item_default": {},
+ "map_item_spec": [
+ {
+ "item_name": "name",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": ""
+ },
+ {
+ "item_name": "code",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 0
+ },
+ {
+ "item_name": "data",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": ""
+ } ]
+ }
+ } ]
+ }
+ }
],
"commands": [
{
diff --git a/src/bin/dhcp6/dhcp6_log.h b/src/bin/dhcp6/dhcp6_log.h
index 6d7f4e3..fb3c3f9 100644
--- a/src/bin/dhcp6/dhcp6_log.h
+++ b/src/bin/dhcp6/dhcp6_log.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DHCP6_LOG__H
-#define __DHCP6_LOG__H
+#ifndef DHCP6_LOG_H
+#define DHCP6_LOG_H
#include <log/macros.h>
#include <log/logger_support.h>
@@ -56,4 +56,4 @@ extern isc::log::Logger dhcp6_logger;
} // namespace dhcp6
} // namespace isc
-#endif // __DHCP6_LOG__H
+#endif // DHCP6_LOG_H
diff --git a/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes
index 2399c19..ffca69a 100644
--- a/src/bin/dhcp6/dhcp6_messages.mes
+++ b/src/bin/dhcp6/dhcp6_messages.mes
@@ -129,3 +129,8 @@ This is an informational message announcing the successful processing of a
new configuration. it is output during server startup, and when an updated
configuration is committed by the administrator. Additional information
may be provided.
+
+% DHCP6_CONFIG_OPTION_DUPLICATE multiple options with the code: %1 added to the subnet: %2
+This warning message is issued on attempt to configure multiple options with the
+same option code for the particular subnet. Adding multiple options is uncommon
+for DHCPv6, yet it is not prohibited.
diff --git a/src/bin/dhcp6/tests/Makefile.am b/src/bin/dhcp6/tests/Makefile.am
index 1629ae6..78caa2f 100644
--- a/src/bin/dhcp6/tests/Makefile.am
+++ b/src/bin/dhcp6/tests/Makefile.am
@@ -63,6 +63,7 @@ dhcp6_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
dhcp6_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
dhcp6_unittests_LDADD = $(GTEST_LDADD)
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
+dhcp6_unittests_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcpsrv.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc
index 22592e8..489e3c1 100644
--- a/src/bin/dhcp6/tests/config_parser_unittest.cc
+++ b/src/bin/dhcp6/tests/config_parser_unittest.cc
@@ -49,6 +49,110 @@ public:
delete srv_;
};
+ /// @brief Create the simple configuration with single option.
+ ///
+ /// This function allows to set one of the parameters that configure
+ /// option value. These parameters are: "name", "code" and "data".
+ ///
+ /// @param param_value string holiding option parameter value to be
+ /// injected into the configuration string.
+ /// @param parameter name of the parameter to be configured with
+ /// param value.
+ std::string createConfigWithOption(const std::string& param_value,
+ const std::string& parameter) {
+ std::ostringstream stream;
+ stream << "{ \"interface\": [ \"all\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"pool\": [ \"2001:db8:1::/80\" ],"
+ " \"subnet\": \"2001:db8:1::/64\", "
+ " \"option-data\": [ {";
+ if (parameter == "name") {
+ stream <<
+ " \"name\": \"" << param_value << "\","
+ " \"code\": 80,"
+ " \"data\": \"AB CDEF0105\"";
+ } else if (parameter == "code") {
+ stream <<
+ " \"name\": \"option_foo\","
+ " \"code\": " << param_value << ","
+ " \"data\": \"AB CDEF0105\"";
+ } else if (parameter == "data") {
+ stream <<
+ " \"name\": \"option_foo\","
+ " \"code\": 80,"
+ " \"data\": \"" << param_value << "\"";
+ }
+ stream <<
+ " } ]"
+ " } ],"
+ "\"valid-lifetime\": 4000 }";
+ return (stream.str());
+ }
+
+ /// @brief Test invalid option parameter value.
+ ///
+ /// This test function constructs the simple configuration
+ /// string and injects invalid option configuration into it.
+ /// It expects that parser will fail with provided option code.
+ ///
+ /// @param param_value string holding invalid option parameter value
+ /// to be injected into configuration string.
+ /// @param parameter name of the parameter to be configured with
+ /// param_value (can be any of "name", "code", "data")
+ void testInvalidOptionParam(const std::string& param_value,
+ const std::string& parameter) {
+ ConstElementPtr x;
+ std::string config = createConfigWithOption(param_value, parameter);
+ ElementPtr json = Element::fromJSON(config);
+ EXPECT_NO_THROW(x = configureDhcp6Server(*srv_, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ ASSERT_EQ(1, rcode_);
+ }
+
+ /// @brief Test option against given code and data.
+ ///
+ /// @param option_desc option descriptor that carries the option to
+ /// be tested.
+ /// @param expected_code expected code of the option.
+ /// @param expected_data expected data in the option.
+ /// @param expected_data_len length of the reference data.
+ /// @param extra_data if true extra data is allowed in an option
+ /// after tested data.
+ void testOption(const Subnet::OptionDescriptor& option_desc,
+ uint16_t expected_code, const uint8_t* expected_data,
+ size_t expected_data_len,
+ bool extra_data = false) {
+ // Check if option descriptor contains valid option pointer.
+ ASSERT_TRUE(option_desc.option);
+ // Verify option type.
+ EXPECT_EQ(expected_code, option_desc.option->getType());
+ // We may have many different option types being created. Some of them
+ // have dedicated classes derived from Option class. In such case if
+ // we want to verify the option contents against expected_data we have
+ // to prepare raw buffer with the contents of the option. The easiest
+ // way is to call pack() which will prepare on-wire data.
+ util::OutputBuffer buf(option_desc.option->getData().size());
+ option_desc.option->pack(buf);
+ if (extra_data) {
+ // The length of the buffer must be at least equal to size of the
+ // reference data but it can sometimes be greater than that. This is
+ // because some options carry suboptions that increase the overall
+ // length.
+ ASSERT_GE(buf.getLength() - option_desc.option->getHeaderLen(),
+ expected_data_len);
+ } else {
+ ASSERT_EQ(buf.getLength() - option_desc.option->getHeaderLen(),
+ expected_data_len);
+ }
+ // Verify that the data is correct. However do not verify suboptions.
+ const uint8_t* data = static_cast<const uint8_t*>(buf.getData());
+ EXPECT_TRUE(memcmp(expected_data, data, expected_data_len));
+ }
+
Dhcpv6Srv* srv_;
int rcode_;
@@ -73,7 +177,7 @@ TEST_F(Dhcp6ParserTest, version) {
/// The goal of this test is to verify that the code accepts only
/// valid commands and malformed or unsupported parameters are rejected.
-TEST_F(Dhcp6ParserTest, bogus_command) {
+TEST_F(Dhcp6ParserTest, bogusCommand) {
ConstElementPtr x;
@@ -89,7 +193,7 @@ TEST_F(Dhcp6ParserTest, bogus_command) {
/// The goal of this test is to verify if wrongly defined subnet will
/// be rejected. Properly defined subnet must include at least one
/// pool definition.
-TEST_F(Dhcp6ParserTest, empty_subnet) {
+TEST_F(Dhcp6ParserTest, emptySubnet) {
ConstElementPtr status;
@@ -109,7 +213,7 @@ TEST_F(Dhcp6ParserTest, empty_subnet) {
/// The goal of this test is to verify if defined subnet uses global
/// parameter timer definitions.
-TEST_F(Dhcp6ParserTest, subnet_global_defaults) {
+TEST_F(Dhcp6ParserTest, subnetGlobalDefaults) {
ConstElementPtr status;
@@ -144,7 +248,7 @@ TEST_F(Dhcp6ParserTest, subnet_global_defaults) {
// This test checks if it is possible to override global values
// on a per subnet basis.
-TEST_F(Dhcp6ParserTest, subnet_local) {
+TEST_F(Dhcp6ParserTest, subnetLocal) {
ConstElementPtr status;
@@ -181,7 +285,7 @@ TEST_F(Dhcp6ParserTest, subnet_local) {
// Test verifies that a subnet with pool values that do not belong to that
// pool are rejected.
-TEST_F(Dhcp6ParserTest, pool_out_of_subnet) {
+TEST_F(Dhcp6ParserTest, poolOutOfSubnet) {
ConstElementPtr status;
@@ -209,7 +313,7 @@ TEST_F(Dhcp6ParserTest, pool_out_of_subnet) {
// Goal of this test is to verify if pools can be defined
// using prefix/length notation. There is no separate test for min-max
// notation as it was tested in several previous tests.
-TEST_F(Dhcp6ParserTest, pool_prefix_len) {
+TEST_F(Dhcp6ParserTest, poolPrefixLen) {
ConstElementPtr x;
@@ -240,4 +344,318 @@ TEST_F(Dhcp6ParserTest, pool_prefix_len) {
EXPECT_EQ(4000, subnet->getValid());
}
+// Goal of this test is to verify that global option
+// data is configured for the subnet if the subnet
+// configuration does not include options configuration.
+TEST_F(Dhcp6ParserTest, optionDataDefaults) {
+ ConstElementPtr x;
+ string config = "{ \"interface\": [ \"all\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000,"
+ "\"renew-timer\": 1000,"
+ "\"option-data\": [ {"
+ " \"name\": \"option_foo\","
+ " \"code\": 100,"
+ " \"data\": \"AB CDEF0105\""
+ " },"
+ " {"
+ " \"name\": \"option_foo2\","
+ " \"code\": 101,"
+ " \"data\": \"01\""
+ " } ],"
+ "\"subnet6\": [ { "
+ " \"pool\": [ \"2001:db8:1::/80\" ],"
+ " \"subnet\": \"2001:db8:1::/64\""
+ " } ],"
+ "\"valid-lifetime\": 4000 }";
+
+ ElementPtr json = Element::fromJSON(config);
+
+ EXPECT_NO_THROW(x = configureDhcp6Server(*srv_, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ ASSERT_EQ(0, rcode_);
+
+ Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
+ ASSERT_TRUE(subnet);
+ const Subnet::OptionContainer& options = subnet->getOptions();
+ ASSERT_EQ(2, options.size());
+
+ // Get the search index. Index #1 is to search using option code.
+ const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
+
+ // Get the options for specified index. Expecting one option to be
+ // returned but in theory we may have multiple options with the same
+ // code so we get the range.
+ std::pair<Subnet::OptionContainerTypeIndex::const_iterator,
+ Subnet::OptionContainerTypeIndex::const_iterator> range =
+ idx.equal_range(100);
+ // Expect single option with the code equal to 100.
+ ASSERT_EQ(1, std::distance(range.first, range.second));
+ const uint8_t foo_expected[] = {
+ 0xAB, 0xCD, 0xEF, 0x01, 0x05
+ };
+ // Check if option is valid in terms of code and carried data.
+ testOption(*range.first, 100, foo_expected, sizeof(foo_expected));
+
+ range = idx.equal_range(101);
+ ASSERT_EQ(1, std::distance(range.first, range.second));
+ // Do another round of testing with second option.
+ const uint8_t foo2_expected[] = {
+ 0x01
+ };
+ testOption(*range.first, 101, foo2_expected, sizeof(foo2_expected));
+
+ // Check that options with other option codes are not returned.
+ for (uint16_t code = 102; code < 110; ++code) {
+ range = idx.equal_range(code);
+ EXPECT_EQ(0, std::distance(range.first, range.second));
+ }
+}
+
+// Goal of this test is to verify options configuration
+// for a single subnet. In particular this test checks
+// that local options configuration overrides global
+// option setting.
+TEST_F(Dhcp6ParserTest, optionDataInSingleSubnet) {
+ ConstElementPtr x;
+ string config = "{ \"interface\": [ \"all\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"option-data\": [ {"
+ " \"name\": \"option_foo\","
+ " \"code\": 100,"
+ " \"data\": \"AB\""
+ " } ],"
+ "\"subnet6\": [ { "
+ " \"pool\": [ \"2001:db8:1::/80\" ],"
+ " \"subnet\": \"2001:db8:1::/64\", "
+ " \"option-data\": [ {"
+ " \"name\": \"option_foo\","
+ " \"code\": 100,"
+ " \"data\": \"AB CDEF0105\""
+ " },"
+ " {"
+ " \"name\": \"option_foo2\","
+ " \"code\": 101,"
+ " \"data\": \"01\""
+ " } ]"
+ " } ],"
+ "\"valid-lifetime\": 4000 }";
+
+ ElementPtr json = Element::fromJSON(config);
+
+ EXPECT_NO_THROW(x = configureDhcp6Server(*srv_, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ ASSERT_EQ(0, rcode_);
+
+ Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
+ ASSERT_TRUE(subnet);
+ const Subnet::OptionContainer& options = subnet->getOptions();
+ ASSERT_EQ(2, options.size());
+
+ // Get the search index. Index #1 is to search using option code.
+ const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
+
+ // Get the options for specified index. Expecting one option to be
+ // returned but in theory we may have multiple options with the same
+ // code so we get the range.
+ std::pair<Subnet::OptionContainerTypeIndex::const_iterator,
+ Subnet::OptionContainerTypeIndex::const_iterator> range =
+ idx.equal_range(100);
+ // Expect single option with the code equal to 100.
+ ASSERT_EQ(1, std::distance(range.first, range.second));
+ const uint8_t foo_expected[] = {
+ 0xAB, 0xCD, 0xEF, 0x01, 0x05
+ };
+ // Check if option is valid in terms of code and carried data.
+ testOption(*range.first, 100, foo_expected, sizeof(foo_expected));
+
+ range = idx.equal_range(101);
+ ASSERT_EQ(1, std::distance(range.first, range.second));
+ // Do another round of testing with second option.
+ const uint8_t foo2_expected[] = {
+ 0x01
+ };
+ testOption(*range.first, 101, foo2_expected, sizeof(foo2_expected));
+}
+
+// Goal of this test is to verify options configuration
+// for multiple subnets.
+TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
+ ConstElementPtr x;
+ string config = "{ \"interface\": [ \"all\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"pool\": [ \"2001:db8:1::/80\" ],"
+ " \"subnet\": \"2001:db8:1::/64\", "
+ " \"option-data\": [ {"
+ " \"name\": \"option_foo\","
+ " \"code\": 100,"
+ " \"data\": \"0102030405060708090A\""
+ " } ]"
+ " },"
+ " {"
+ " \"pool\": [ \"2001:db8:2::/80\" ],"
+ " \"subnet\": \"2001:db8:2::/64\", "
+ " \"option-data\": [ {"
+ " \"name\": \"option_foo2\","
+ " \"code\": 101,"
+ " \"data\": \"FFFEFDFCFB\""
+ " } ]"
+ " } ],"
+ "\"valid-lifetime\": 4000 }";
+
+ ElementPtr json = Element::fromJSON(config);
+
+ EXPECT_NO_THROW(x = configureDhcp6Server(*srv_, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ ASSERT_EQ(0, rcode_);
+
+ Subnet6Ptr subnet1 = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
+ ASSERT_TRUE(subnet1);
+ const Subnet::OptionContainer& options1 = subnet1->getOptions();
+ ASSERT_EQ(1, options1.size());
+
+ // Get the search index. Index #1 is to search using option code.
+ const Subnet::OptionContainerTypeIndex& idx1 = options1.get<1>();
+
+ // Get the options for specified index. Expecting one option to be
+ // returned but in theory we may have multiple options with the same
+ // code so we get the range.
+ std::pair<Subnet::OptionContainerTypeIndex::const_iterator,
+ Subnet::OptionContainerTypeIndex::const_iterator> range1 =
+ idx1.equal_range(100);
+ // Expect single option with the code equal to 100.
+ ASSERT_EQ(1, std::distance(range1.first, range1.second));
+ const uint8_t foo_expected[] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0A
+ };
+ // Check if option is valid in terms of code and carried data.
+ testOption(*range1.first, 100, foo_expected, sizeof(foo_expected));
+
+ // Test another subnet in the same way.
+ Subnet6Ptr subnet2 = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:2::4"));
+ ASSERT_TRUE(subnet2);
+ const Subnet::OptionContainer& options2 = subnet2->getOptions();
+ ASSERT_EQ(1, options2.size());
+
+ const Subnet::OptionContainerTypeIndex& idx2 = options2.get<1>();
+ std::pair<Subnet::OptionContainerTypeIndex::const_iterator,
+ Subnet::OptionContainerTypeIndex::const_iterator> range2 =
+ idx2.equal_range(101);
+ ASSERT_EQ(1, std::distance(range2.first, range2.second));
+
+ const uint8_t foo2_expected[] = {
+ 0xFF, 0xFE, 0xFD, 0xFC, 0xFB
+ };
+ testOption(*range2.first, 101, foo2_expected, sizeof(foo2_expected));
+}
+
+// Verify that empty option name is rejected in the configuration.
+TEST_F(Dhcp6ParserTest, optionNameEmpty) {
+ // Empty option names not allowed.
+ testInvalidOptionParam("", "name");
+}
+
+// Verify that empty option name with spaces is rejected
+// in the configuration.
+TEST_F(Dhcp6ParserTest, optionNameSpaces) {
+ // Spaces in option names not allowed.
+ testInvalidOptionParam("option foo", "name");
+}
+
+// Verify that negative option code is rejected in the configuration.
+TEST_F(Dhcp6ParserTest, optionCodeNegative) {
+ // Check negative option code -4. This should fail too.
+ testInvalidOptionParam("-4", "code");
+}
+
+// Verify that out of bounds option code is rejected in the configuration.
+TEST_F(Dhcp6ParserTest, optionCodeNonUint16) {
+ // The valid option codes are uint16_t values so passing
+ // uint16_t maximum value incremented by 1 should result
+ // in failure.
+ testInvalidOptionParam("65536", "code");
+}
+
+// Verify that out of bounds option code is rejected in the configuration.
+TEST_F(Dhcp6ParserTest, optionCodeHighNonUint16) {
+ // Another check for uint16_t overflow but this time
+ // let's pass even greater option code value.
+ testInvalidOptionParam("70000", "code");
+}
+
+// Verify that zero option code is rejected in the configuration.
+TEST_F(Dhcp6ParserTest, optionCodeZero) {
+ // Option code 0 is reserved and should not be accepted
+ // by configuration parser.
+ testInvalidOptionParam("0", "code");
+}
+
+// Verify that option data which contains non hexadecimal characters
+// is rejected by the configuration.
+TEST_F(Dhcp6ParserTest, optionDataInvalidChar) {
+ // Option code 0 is reserved and should not be accepted
+ // by configuration parser.
+ testInvalidOptionParam("01020R", "data");
+}
+
+// Verify that option data containins '0x' prefix is rejected
+// by the configuration.
+TEST_F(Dhcp6ParserTest, optionDataUnexpectedPrefix) {
+ // Option code 0 is reserved and should not be accepted
+ // by configuration parser.
+ testInvalidOptionParam("0x0102", "data");
+}
+
+// Verify that option data consisting od an odd number of
+// hexadecimal digits is rejected in the configuration.
+TEST_F(Dhcp6ParserTest, optionDataOddLength) {
+ // Option code 0 is reserved and should not be accepted
+ // by configuration parser.
+ testInvalidOptionParam("123", "data");
+}
+
+// Verify that either lower or upper case characters are allowed
+// to specify the option data.
+TEST_F(Dhcp6ParserTest, optionDataLowerCase) {
+ ConstElementPtr x;
+ std::string config = createConfigWithOption("0a0b0C0D", "data");
+ ElementPtr json = Element::fromJSON(config);
+
+ EXPECT_NO_THROW(x = configureDhcp6Server(*srv_, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ ASSERT_EQ(0, rcode_);
+
+ Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
+ ASSERT_TRUE(subnet);
+ const Subnet::OptionContainer& options = subnet->getOptions();
+ ASSERT_EQ(1, options.size());
+
+ // Get the search index. Index #1 is to search using option code.
+ const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
+
+ // Get the options for specified index. Expecting one option to be
+ // returned but in theory we may have multiple options with the same
+ // code so we get the range.
+ std::pair<Subnet::OptionContainerTypeIndex::const_iterator,
+ Subnet::OptionContainerTypeIndex::const_iterator> range =
+ idx.equal_range(80);
+ // Expect single option with the code equal to 100.
+ ASSERT_EQ(1, std::distance(range.first, range.second));
+ const uint8_t foo_expected[] = {
+ 0x0A, 0x0B, 0x0C, 0x0D
+ };
+ // Check if option is valid in terms of code and carried data.
+ testOption(*range.first, 80, foo_expected, sizeof(foo_expected));
+}
+
};
diff --git a/src/bin/resolver/resolver.h b/src/bin/resolver/resolver.h
index e91192e..cc0f09f 100644
--- a/src/bin/resolver/resolver.h
+++ b/src/bin/resolver/resolver.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RESOLVER_H
-#define __RESOLVER_H 1
+#ifndef RESOLVER_H
+#define RESOLVER_H 1
#include <string>
#include <vector>
@@ -266,7 +266,7 @@ private:
isc::cache::ResolverCache* cache_;
};
-#endif // __RESOLVER_H
+#endif // RESOLVER_H
// Local Variables:
// mode: c++
diff --git a/src/bin/resolver/resolver_log.h b/src/bin/resolver/resolver_log.h
index e0e3fda..a4b6c44 100644
--- a/src/bin/resolver/resolver_log.h
+++ b/src/bin/resolver/resolver_log.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RESOLVER_LOG__H
-#define __RESOLVER_LOG__H
+#ifndef RESOLVER_LOG_H
+#define RESOLVER_LOG_H
#include <log/macros.h>
#include "resolver_messages.h"
@@ -46,4 +46,4 @@ const int RESOLVER_DBG_DETAIL = DBGLVL_TRACE_DETAIL_DATA;
/// space.
extern isc::log::Logger resolver_logger;
-#endif // __RESOLVER_LOG__H
+#endif // RESOLVER_LOG_H
diff --git a/src/bin/resolver/response_scrubber.h b/src/bin/resolver/response_scrubber.h
index c59ac15..cb80b26 100644
--- a/src/bin/resolver/response_scrubber.h
+++ b/src/bin/resolver/response_scrubber.h
@@ -14,8 +14,8 @@
// $Id$
-#ifndef __RESPONSE_SCRUBBER_H
-#define __RESPONSE_SCRUBBER_H
+#ifndef RESPONSE_SCRUBBER_H
+#define RESPONSE_SCRUBBER_H
/// \page DataScrubbing Data Scrubbing
/// \section DataScrubbingIntro Introduction
@@ -419,4 +419,4 @@ public:
}
};
-#endif // __RESPONSE_SCRUBBER_H
+#endif // RESPONSE_SCRUBBER_H
diff --git a/src/bin/sockcreator/sockcreator.h b/src/bin/sockcreator/sockcreator.h
index e5d4783..8e32c48 100644
--- a/src/bin/sockcreator/sockcreator.h
+++ b/src/bin/sockcreator/sockcreator.h
@@ -18,8 +18,8 @@
/// This module holds the functionality of the socket creator. It is a separate
/// module from main to make testing easier.
-#ifndef __SOCKCREATOR_H
-#define __SOCKCREATOR_H 1
+#ifndef SOCKCREATOR_H
+#define SOCKCREATOR_H 1
#include <util/io/fd_share.h>
#include <exceptions/exceptions.h>
@@ -144,4 +144,4 @@ run(const int input_fd, const int output_fd, get_sock_t get_sock_fun,
} // namespace socket_creator
} // NAMESPACE ISC
-#endif // __SOCKCREATOR_H
+#endif // SOCKCREATOR_H
diff --git a/src/bin/sysinfo/.gitignore b/src/bin/sysinfo/.gitignore
index 9194aff..b5c759d 100644
--- a/src/bin/sysinfo/.gitignore
+++ b/src/bin/sysinfo/.gitignore
@@ -1,3 +1,4 @@
/isc-sysinfo
-/sysinfo.py
/isc-sysinfo.1
+/run_sysinfo.sh
+/sysinfo.py
diff --git a/src/bin/sysinfo/Makefile.am b/src/bin/sysinfo/Makefile.am
index 25a3556..1618535 100644
--- a/src/bin/sysinfo/Makefile.am
+++ b/src/bin/sysinfo/Makefile.am
@@ -1,4 +1,5 @@
bin_SCRIPTS = isc-sysinfo
+noinst_SCRIPTS = run_sysinfo.sh
CLEANFILES = isc-sysinfo sysinfo.pyc
diff --git a/src/bin/sysinfo/run_sysinfo.sh.in b/src/bin/sysinfo/run_sysinfo.sh.in
new file mode 100755
index 0000000..268b5a4
--- /dev/null
+++ b/src/bin/sysinfo/run_sysinfo.sh.in
@@ -0,0 +1,38 @@
+#! /bin/sh
+
+# Copyright (C) 2012 Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+PYTHON_EXEC=${PYTHON_EXEC:- at PYTHON@}
+export PYTHON_EXEC
+
+SYSINFO_PATH=@abs_top_builddir@/src/bin/sysinfo
+
+# Note: we shouldn't need log_messages except for the seemingly necessary
+# dependency due to the automatic import in the isc package (its __init__.py
+# imports some other modules)
+PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/python/isc/log_messages
+export PYTHONPATH
+
+# Likewise, we need only because isc.log requires some loadable modules.
+# sysinfo itself shouldn't need any of them.
+SET_ENV_LIBRARY_PATH=@SET_ENV_LIBRARY_PATH@
+if test $SET_ENV_LIBRARY_PATH = yes; then
+ @ENV_LIBRARY_PATH@=@abs_top_builddir@/src/lib/dns/.libs:@abs_top_builddir@/src/lib/dns/python/.libs:@abs_top_builddir@/src/lib/cryptolink/.libs:@abs_top_builddir@/src/lib/cc/.libs:@abs_top_builddir@/src/lib/config/.libs:@abs_top_builddir@/src/lib/log/.libs:@abs_top_builddir@/src/lib/acl/.libs:@abs_top_builddir@/src/lib/util/.libs:@abs_top_builddir@/src/lib/util/io/.libs:@abs_top_builddir@/src/lib/exceptions/.libs:@abs_top_builddir@/src/lib/datasrc/.libs:$@ENV_LIBRARY_PATH@
+ export @ENV_LIBRARY_PATH@
+fi
+
+cd ${SYSINFO_PATH}
+exec ${PYTHON_EXEC} -O sysinfo.py "$@"
diff --git a/src/bin/sysinfo/sysinfo.py.in b/src/bin/sysinfo/sysinfo.py.in
index 24cf309..477b9de 100755
--- a/src/bin/sysinfo/sysinfo.py.in
+++ b/src/bin/sysinfo/sysinfo.py.in
@@ -22,11 +22,8 @@ ISC sysinfo program.
import sys; sys.path.append ('@@PYTHONPATH@@')
import getopt
-import isc.util.process
from isc.sysinfo import *
-isc.util.process.rename()
-
def usage():
print("Usage: %s [-h] [-o <output-file>]" % sys.argv[0], \
file=sys.stderr)
@@ -88,7 +85,8 @@ def main():
write_value(f, ' + Machine name: %s\n', s.get_platform_machine)
write_value(f, ' + Hostname: %s\n', s.get_platform_hostname)
- write_value(f, ' + Uptime: %d seconds\n', s.get_uptime)
+ write_value(f, ' + Uptime: %d seconds', s.get_uptime)
+ write_value(f, ' (%s)\n', s.get_uptime_desc)
write_value(f, ' + Loadavg: %f %f %f\n', s.get_loadavg)
diff --git a/src/bin/tests/process_rename_test.py.in b/src/bin/tests/process_rename_test.py.in
index 1156b29..055ebdc 100644
--- a/src/bin/tests/process_rename_test.py.in
+++ b/src/bin/tests/process_rename_test.py.in
@@ -39,6 +39,11 @@ class TestRename(unittest.TestCase):
Then scan them by looking at the source text
(without actually running them)
"""
+
+ # Scripts named in this list are not expected to be renamed and
+ # should be excluded from the scan.
+ EXCLUDED_SCRIPTS = ['isc-sysinfo']
+
# Regexp to find all the *_SCRIPTS = something lines (except for
# noinst_SCRIPTS, which are scripts for tests), including line
# continuations (backslash and newline)
@@ -59,6 +64,8 @@ class TestRename(unittest.TestCase):
for (var, _) in lines.findall(re.sub(excluded_lines, '',
makefile)):
for (script, _) in scripts.findall(var):
+ if script in EXCLUDED_SCRIPTS:
+ continue
self.__scan(d, script, fun)
if __name__ == "__main__":
diff --git a/src/lib/acl/dnsname_check.h b/src/lib/acl/dnsname_check.h
index 7498d99..7403c16 100644
--- a/src/lib/acl/dnsname_check.h
+++ b/src/lib/acl/dnsname_check.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DNSNAME_CHECK_H
-#define __DNSNAME_CHECK_H 1
+#ifndef DNSNAME_CHECK_H
+#define DNSNAME_CHECK_H 1
#include <dns/name.h>
@@ -76,7 +76,7 @@ private:
} // namespace acl
} // namespace isc
-#endif // __DNSNAME_CHECK_H
+#endif // DNSNAME_CHECK_H
// Local Variables:
// mode: c++
diff --git a/src/lib/acl/ip_check.h b/src/lib/acl/ip_check.h
index 794b943..9d70b0a 100644
--- a/src/lib/acl/ip_check.h
+++ b/src/lib/acl/ip_check.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __IP_CHECK_H
-#define __IP_CHECK_H
+#ifndef IP_CHECK_H
+#define IP_CHECK_H
#include <sys/socket.h>
@@ -410,7 +410,7 @@ const size_t IPCheck<Context>::IPV4_SIZE;
} // namespace acl
} // namespace isc
-#endif // __IP_CHECK_H
+#endif // IP_CHECK_H
// Local Variables:
// mode: c++
diff --git a/src/lib/acl/tests/sockaddr.h b/src/lib/acl/tests/sockaddr.h
index bd30451..2a4457a 100644
--- a/src/lib/acl/tests/sockaddr.h
+++ b/src/lib/acl/tests/sockaddr.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ACL_TEST_SOCKADDR_H
-#define __ACL_TEST_SOCKADDR_H 1
+#ifndef ACL_TEST_SOCKADDR_H
+#define ACL_TEST_SOCKADDR_H 1
#include <sys/types.h>
#include <sys/socket.h>
@@ -62,7 +62,7 @@ getSockAddr(const char* const addr) {
} // end of namespace "acl"
} // end of namespace "isc"
-#endif // __ACL_TEST_SOCKADDR_H
+#endif // ACL_TEST_SOCKADDR_H
// Local Variables:
// mode: c++
diff --git a/src/lib/asiodns/asiodns.h b/src/lib/asiodns/asiodns.h
index 8791a72..3032ebd 100644
--- a/src/lib/asiodns/asiodns.h
+++ b/src/lib/asiodns/asiodns.h
@@ -12,12 +12,12 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ASIODNS_H
-#define __ASIODNS_H 1
+#ifndef ASIODNS_H
+#define ASIODNS_H 1
#include <asiodns/dns_service.h>
#include <asiodns/dns_server.h>
#include <asiodns/dns_lookup.h>
#include <asiodns/dns_answer.h>
-#endif // __ASIODNS_H
+#endif // ASIODNS_H
diff --git a/src/lib/asiodns/dns_answer.h b/src/lib/asiodns/dns_answer.h
index 3654369..4b4576b 100644
--- a/src/lib/asiodns/dns_answer.h
+++ b/src/lib/asiodns/dns_answer.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ASIOLINK_DNS_ANSWER_H
-#define __ASIOLINK_DNS_ANSWER_H 1
+#ifndef ASIOLINK_DNS_ANSWER_H
+#define ASIOLINK_DNS_ANSWER_H 1
#include <asiolink/io_message.h>
#include <util/buffer.h>
@@ -74,4 +74,4 @@ public:
} // namespace asiodns
} // namespace isc
-#endif // __ASIOLINK_DNS_ANSWER_H
+#endif // ASIOLINK_DNS_ANSWER_H
diff --git a/src/lib/asiodns/dns_lookup.h b/src/lib/asiodns/dns_lookup.h
index 5dc84ac..309755c 100644
--- a/src/lib/asiodns/dns_lookup.h
+++ b/src/lib/asiodns/dns_lookup.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ASIOLINK_DNS_LOOKUP_H
-#define __ASIOLINK_DNS_LOOKUP_H 1
+#ifndef ASIOLINK_DNS_LOOKUP_H
+#define ASIOLINK_DNS_LOOKUP_H 1
#include <asiolink/io_message.h>
#include <asiodns/dns_server.h>
@@ -84,4 +84,4 @@ private:
} // namespace asiodns
} // namespace isc
-#endif // __ASIOLINK_DNS_LOOKUP_H
+#endif // ASIOLINK_DNS_LOOKUP_H
diff --git a/src/lib/asiodns/dns_server.h b/src/lib/asiodns/dns_server.h
index bc39805..3b8758f 100644
--- a/src/lib/asiodns/dns_server.h
+++ b/src/lib/asiodns/dns_server.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ASIOLINK_DNS_SERVER_H
-#define __ASIOLINK_DNS_SERVER_H 1
+#ifndef ASIOLINK_DNS_SERVER_H
+#define ASIOLINK_DNS_SERVER_H 1
#include <asiolink/io_message.h>
@@ -152,4 +152,4 @@ private:
} // namespace asiodns
} // namespace isc
-#endif // __ASIOLINK_DNS_SERVER_H
+#endif // ASIOLINK_DNS_SERVER_H
diff --git a/src/lib/asiodns/dns_service.h b/src/lib/asiodns/dns_service.h
index 0b578fb..01b6310 100644
--- a/src/lib/asiodns/dns_service.h
+++ b/src/lib/asiodns/dns_service.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ASIOLINK_DNS_SERVICE_H
-#define __ASIOLINK_DNS_SERVICE_H 1
+#ifndef ASIOLINK_DNS_SERVICE_H
+#define ASIOLINK_DNS_SERVICE_H 1
#include <resolve/resolver_interface.h>
@@ -210,7 +210,7 @@ private:
} // namespace asiodns
} // namespace isc
-#endif // __ASIOLINK_DNS_SERVICE_H
+#endif // ASIOLINK_DNS_SERVICE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/asiodns/io_fetch.h b/src/lib/asiodns/io_fetch.h
index 78c2da9..c31ee09 100644
--- a/src/lib/asiodns/io_fetch.h
+++ b/src/lib/asiodns/io_fetch.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __IO_FETCH_H
-#define __IO_FETCH_H 1
+#ifndef IO_FETCH_H
+#define IO_FETCH_H 1
#include <config.h>
@@ -229,4 +229,4 @@ private:
} // namespace asiodns
} // namespace isc
-#endif // __IO_FETCH_H
+#endif // IO_FETCH_H
diff --git a/src/lib/asiodns/sync_udp_server.h b/src/lib/asiodns/sync_udp_server.h
index 9718422..ddac1f9 100644
--- a/src/lib/asiodns/sync_udp_server.h
+++ b/src/lib/asiodns/sync_udp_server.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __SYNC_UDP_SERVER_H
-#define __SYNC_UDP_SERVER_H 1
+#ifndef SYNC_UDP_SERVER_H
+#define SYNC_UDP_SERVER_H 1
#ifndef ASIO_HPP
#error "asio.hpp must be included before including this, see asiolink.h as to why"
@@ -145,4 +145,4 @@ private:
} // namespace asiodns
} // namespace isc
-#endif // __SYNC_UDP_SERVER_H
+#endif // SYNC_UDP_SERVER_H
diff --git a/src/lib/asiodns/tcp_server.h b/src/lib/asiodns/tcp_server.h
index 7675daf..46f484b 100644
--- a/src/lib/asiodns/tcp_server.h
+++ b/src/lib/asiodns/tcp_server.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TCP_SERVER_H
-#define __TCP_SERVER_H 1
+#ifndef TCP_SERVER_H
+#define TCP_SERVER_H 1
#ifndef ASIO_HPP
#error "asio.hpp must be included before including this, see asiolink.h as to why"
@@ -147,4 +147,4 @@ private:
} // namespace asiodns
} // namespace isc
-#endif // __TCP_SERVER_H
+#endif // TCP_SERVER_H
diff --git a/src/lib/asiodns/udp_server.h b/src/lib/asiodns/udp_server.h
index b32c06c..c2b1b96 100644
--- a/src/lib/asiodns/udp_server.h
+++ b/src/lib/asiodns/udp_server.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __UDP_SERVER_H
-#define __UDP_SERVER_H 1
+#ifndef UDP_SERVER_H
+#define UDP_SERVER_H 1
#ifndef ASIO_HPP
#error "asio.hpp must be included before including this, see asiolink.h as to why"
@@ -96,4 +96,4 @@ private:
} // namespace asiodns
} // namespace isc
-#endif // __UDP_SERVER_H
+#endif // UDP_SERVER_H
diff --git a/src/lib/asiolink/asiolink.h b/src/lib/asiolink/asiolink.h
index 51d3a14..708f368 100644
--- a/src/lib/asiolink/asiolink.h
+++ b/src/lib/asiolink/asiolink.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ASIOLINK_H
-#define __ASIOLINK_H 1
+#ifndef ASIOLINK_H
+#define ASIOLINK_H 1
// IMPORTANT NOTE: only very few ASIO headers files can be included in
// this file. In particular, asio.hpp should never be included here.
@@ -74,4 +74,4 @@
/// the placeholder of callback handlers:
/// http://think-async.com/Asio/asio-1.3.1/doc/asio/reference/asio_handler_allocate.html
-#endif // __ASIOLINK_H
+#endif // ASIOLINK_H
diff --git a/src/lib/asiolink/dummy_io_cb.h b/src/lib/asiolink/dummy_io_cb.h
index bcaefe9..c4644c5 100644
--- a/src/lib/asiolink/dummy_io_cb.h
+++ b/src/lib/asiolink/dummy_io_cb.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DUMMY_IO_CB_H
-#define __DUMMY_IO_CB_H
+#ifndef DUMMY_IO_CB_H
+#define DUMMY_IO_CB_H
#include <iostream>
@@ -59,4 +59,4 @@ public:
} // namespace asiolink
} // namespace isc
-#endif // __DUMMY_IO_CB_H
+#endif // DUMMY_IO_CB_H
diff --git a/src/lib/asiolink/interval_timer.h b/src/lib/asiolink/interval_timer.h
index 57ec1c3..620abfa 100644
--- a/src/lib/asiolink/interval_timer.h
+++ b/src/lib/asiolink/interval_timer.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ASIOLINK_INTERVAL_TIMER_H
-#define __ASIOLINK_INTERVAL_TIMER_H 1
+#ifndef ASIOLINK_INTERVAL_TIMER_H
+#define ASIOLINK_INTERVAL_TIMER_H 1
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
@@ -130,4 +130,4 @@ private:
} // namespace asiolink
} // namespace isc
-#endif // __ASIOLINK_INTERVAL_TIMER_H
+#endif // ASIOLINK_INTERVAL_TIMER_H
diff --git a/src/lib/asiolink/io_address.h b/src/lib/asiolink/io_address.h
index a3bb61a..6c18a66 100644
--- a/src/lib/asiolink/io_address.h
+++ b/src/lib/asiolink/io_address.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __IO_ADDRESS_H
-#define __IO_ADDRESS_H 1
+#ifndef IO_ADDRESS_H
+#define IO_ADDRESS_H 1
// IMPORTANT NOTE: only very few ASIO headers files can be included in
// this file. In particular, asio.hpp should never be included here.
@@ -215,4 +215,4 @@ private:
} // namespace asiolink
} // namespace isc
-#endif // __IO_ADDRESS_H
+#endif // IO_ADDRESS_H
diff --git a/src/lib/asiolink/io_asio_socket.h b/src/lib/asiolink/io_asio_socket.h
index aeac63d..f6d64a0 100644
--- a/src/lib/asiolink/io_asio_socket.h
+++ b/src/lib/asiolink/io_asio_socket.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __IO_ASIO_SOCKET_H
-#define __IO_ASIO_SOCKET_H 1
+#ifndef IO_ASIO_SOCKET_H
+#define IO_ASIO_SOCKET_H 1
// IMPORTANT NOTE: only very few ASIO headers files can be included in
// this file. In particular, asio.hpp should never be included here.
@@ -385,4 +385,4 @@ private:
} // namespace asiolink
} // namespace isc
-#endif // __IO_ASIO_SOCKET_H
+#endif // IO_ASIO_SOCKET_H
diff --git a/src/lib/asiolink/io_endpoint.h b/src/lib/asiolink/io_endpoint.h
index 973fc8b..89bc247 100644
--- a/src/lib/asiolink/io_endpoint.h
+++ b/src/lib/asiolink/io_endpoint.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __IO_ENDPOINT_H
-#define __IO_ENDPOINT_H 1
+#ifndef IO_ENDPOINT_H
+#define IO_ENDPOINT_H 1
// IMPORTANT NOTE: only very few ASIO headers files can be included in
// this file. In particular, asio.hpp should never be included here.
@@ -184,7 +184,7 @@ public:
std::ostream& operator<<(std::ostream& os, const IOEndpoint& endpoint);
} // namespace asiolink
} // namespace isc
-#endif // __IO_ENDPOINT_H
+#endif // IO_ENDPOINT_H
// Local Variables:
// mode: c++
diff --git a/src/lib/asiolink/io_error.h b/src/lib/asiolink/io_error.h
index c19d91c..2fb2486 100644
--- a/src/lib/asiolink/io_error.h
+++ b/src/lib/asiolink/io_error.h
@@ -13,8 +13,8 @@
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __IO_ERROR_H
-#define __IO_ERROR_H
+#ifndef IO_ERROR_H
+#define IO_ERROR_H
#include <exceptions/exceptions.h>
@@ -34,4 +34,4 @@ public:
} // namespace asiolink
} // namespace isc
-#endif // __IO_ERROR_H
+#endif // IO_ERROR_H
diff --git a/src/lib/asiolink/io_message.h b/src/lib/asiolink/io_message.h
index 81f6da1..7607c72 100644
--- a/src/lib/asiolink/io_message.h
+++ b/src/lib/asiolink/io_message.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __IO_MESSAGE_H
-#define __IO_MESSAGE_H 1
+#ifndef IO_MESSAGE_H
+#define IO_MESSAGE_H 1
// IMPORTANT NOTE: only very few ASIO headers files can be included in
// this file. In particular, asio.hpp should never be included here.
@@ -99,4 +99,4 @@ private:
} // namespace asiolink
} // namespace isc
-#endif // __IO_MESSAGE_H
+#endif // IO_MESSAGE_H
diff --git a/src/lib/asiolink/io_service.h b/src/lib/asiolink/io_service.h
index 75aaee6..e0198dd 100644
--- a/src/lib/asiolink/io_service.h
+++ b/src/lib/asiolink/io_service.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ASIOLINK_IO_SERVICE_H
-#define __ASIOLINK_IO_SERVICE_H 1
+#ifndef ASIOLINK_IO_SERVICE_H
+#define ASIOLINK_IO_SERVICE_H 1
namespace asio {
class io_service;
@@ -76,4 +76,4 @@ private:
} // namespace asiolink
} // namespace isc
-#endif // __ASIOLINK_IO_SERVICE_H
+#endif // ASIOLINK_IO_SERVICE_H
diff --git a/src/lib/asiolink/io_socket.h b/src/lib/asiolink/io_socket.h
index ab6479c..6581faf 100644
--- a/src/lib/asiolink/io_socket.h
+++ b/src/lib/asiolink/io_socket.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __IO_SOCKET_H
-#define __IO_SOCKET_H 1
+#ifndef IO_SOCKET_H
+#define IO_SOCKET_H 1
// IMPORTANT NOTE: only very few ASIO headers files can be included in
// this file. In particular, asio.hpp should never be included here.
@@ -123,4 +123,4 @@ public:
} // namespace asiolink
} // namespace isc
-#endif // __IO_SOCKET_H
+#endif // IO_SOCKET_H
diff --git a/src/lib/asiolink/simple_callback.h b/src/lib/asiolink/simple_callback.h
index a297a1d..4301bd1 100644
--- a/src/lib/asiolink/simple_callback.h
+++ b/src/lib/asiolink/simple_callback.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ASIOLINK_SIMPLE_CALLBACK_H
-#define __ASIOLINK_SIMPLE_CALLBACK_H 1
+#ifndef ASIOLINK_SIMPLE_CALLBACK_H
+#define ASIOLINK_SIMPLE_CALLBACK_H 1
#include <asiolink/io_message.h>
@@ -72,4 +72,4 @@ private:
} // namespace asiolink
} // namespace isc
-#endif // __ASIOLINK_SIMPLE_CALLBACK_H
+#endif // ASIOLINK_SIMPLE_CALLBACK_H
diff --git a/src/lib/asiolink/tcp_endpoint.h b/src/lib/asiolink/tcp_endpoint.h
index a54f6b2..3d6a87a 100644
--- a/src/lib/asiolink/tcp_endpoint.h
+++ b/src/lib/asiolink/tcp_endpoint.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TCP_ENDPOINT_H
-#define __TCP_ENDPOINT_H 1
+#ifndef TCP_ENDPOINT_H
+#define TCP_ENDPOINT_H 1
#ifndef ASIO_HPP
#error "asio.hpp must be included before including this, see asiolink.h as to why"
@@ -116,7 +116,7 @@ private:
} // namespace asiolink
} // namespace isc
-#endif // __TCP_ENDPOINT_H
+#endif // TCP_ENDPOINT_H
// Local Variables:
// mode: c++
diff --git a/src/lib/asiolink/tcp_socket.h b/src/lib/asiolink/tcp_socket.h
index 2505d7b..6b0a43c 100644
--- a/src/lib/asiolink/tcp_socket.h
+++ b/src/lib/asiolink/tcp_socket.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TCP_SOCKET_H
-#define __TCP_SOCKET_H 1
+#ifndef TCP_SOCKET_H
+#define TCP_SOCKET_H 1
#ifndef ASIO_HPP
#error "asio.hpp must be included before including this, see asiolink.h as to why"
@@ -415,4 +415,4 @@ TCPSocket<C>::close() {
} // namespace asiolink
} // namespace isc
-#endif // __TCP_SOCKET_H
+#endif // TCP_SOCKET_H
diff --git a/src/lib/asiolink/udp_endpoint.h b/src/lib/asiolink/udp_endpoint.h
index c5ba3bd..34701b9 100644
--- a/src/lib/asiolink/udp_endpoint.h
+++ b/src/lib/asiolink/udp_endpoint.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __UDP_ENDPOINT_H
-#define __UDP_ENDPOINT_H 1
+#ifndef UDP_ENDPOINT_H
+#define UDP_ENDPOINT_H 1
#ifndef ASIO_HPP
#error "asio.hpp must be included before including this, see asiolink.h as to why"
@@ -116,7 +116,7 @@ private:
} // namespace asiolink
} // namespace isc
-#endif // __UDP_ENDPOINT_H
+#endif // UDP_ENDPOINT_H
// Local Variables:
// mode: c++
diff --git a/src/lib/asiolink/udp_socket.h b/src/lib/asiolink/udp_socket.h
index c061fba..5712957 100644
--- a/src/lib/asiolink/udp_socket.h
+++ b/src/lib/asiolink/udp_socket.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __UDP_SOCKET_H
-#define __UDP_SOCKET_H 1
+#ifndef UDP_SOCKET_H
+#define UDP_SOCKET_H 1
#ifndef ASIO_HPP
#error "asio.hpp must be included before including this, see asiolink.h as to why"
@@ -321,4 +321,4 @@ UDPSocket<C>::close() {
} // namespace asiolink
} // namespace isc
-#endif // __UDP_SOCKET_H
+#endif // UDP_SOCKET_H
diff --git a/src/lib/bench/benchmark.h b/src/lib/bench/benchmark.h
index a5c6fd4..3e380dc 100644
--- a/src/lib/bench/benchmark.h
+++ b/src/lib/bench/benchmark.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __BENCHMARK_H
-#define __BENCHMARK_H 1
+#ifndef BENCHMARK_H
+#define BENCHMARK_H 1
#include <sys/time.h>
@@ -402,7 +402,7 @@ private:
}
}
-#endif // __BENCHMARK_H
+#endif // BENCHMARK_H
// Local Variables:
// mode: c++
diff --git a/src/lib/bench/benchmark_util.h b/src/lib/bench/benchmark_util.h
index 3a373f2..2cb6acc 100644
--- a/src/lib/bench/benchmark_util.h
+++ b/src/lib/bench/benchmark_util.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __BENCHMARK_UTIL_H
-#define __BENCHMARK_UTIL_H 1
+#ifndef BENCHMARK_UTIL_H
+#define BENCHMARK_UTIL_H 1
/// \file
/// Utilities to help write benchmark cases.
@@ -140,7 +140,7 @@ void loadQueryData(std::istream& input, BenchQueries& queries,
const isc::dns::RRClass& qclass, const bool strict = false);
}
}
-#endif // __BENCHMARK_UTIL_H
+#endif // BENCHMARK_UTIL_H
// Local Variables:
// mode: c++
diff --git a/src/lib/bench/example/search_bench.cc b/src/lib/bench/example/search_bench.cc
index 84f95d9..d022d55 100644
--- a/src/lib/bench/example/search_bench.cc
+++ b/src/lib/bench/example/search_bench.cc
@@ -116,7 +116,6 @@ main(int argc, char* argv[]) {
}
}
argc -= optind;
- argv += optind;
if (argc != 0) {
usage();
}
diff --git a/src/lib/cache/cache_entry_key.h b/src/lib/cache/cache_entry_key.h
index 674deb0..308a556 100644
--- a/src/lib/cache/cache_entry_key.h
+++ b/src/lib/cache/cache_entry_key.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __CACHE_ENTRY_KEY_H
-#define __CACHE_ENTRY_KEY_H
+#ifndef CACHE_ENTRY_KEY_H
+#define CACHE_ENTRY_KEY_H
#include <string>
#include <dns/name.h>
@@ -50,5 +50,5 @@ genCacheEntryName(const std::string& namestr, const uint16_t type);
} // namespace cache
} // namespace isc
-#endif // __CACHE_ENTRY_KEY_H
+#endif // CACHE_ENTRY_KEY_H
diff --git a/src/lib/cache/local_zone_data.h b/src/lib/cache/local_zone_data.h
index df77f40..4bfdb94 100644
--- a/src/lib/cache/local_zone_data.h
+++ b/src/lib/cache/local_zone_data.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef _LOCAL_ZONE_DATA
-#define _LOCAL_ZONE_DATA
+#ifndef LOCAL_ZONE_DATA
+#define LOCAL_ZONE_DATA
#include <map>
#include <string>
@@ -60,5 +60,5 @@ typedef boost::shared_ptr<const LocalZoneData> ConstLocalZoneDataPtr;
} // namespace cache
} // namespace isc
-#endif // _LOCAL_ZONE_DATA
+#endif // LOCAL_ZONE_DATA
diff --git a/src/lib/cache/logger.h b/src/lib/cache/logger.h
index 52c9743..3cadb54 100644
--- a/src/lib/cache/logger.h
+++ b/src/lib/cache/logger.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DATASRC_LOGGER_H
-#define __DATASRC_LOGGER_H
+#ifndef DATASRC_LOGGER_H
+#define DATASRC_LOGGER_H
#include <log/macros.h>
#include <cache/cache_messages.h>
diff --git a/src/lib/cache/message_cache.h b/src/lib/cache/message_cache.h
index b418f23..0c19139 100644
--- a/src/lib/cache/message_cache.h
+++ b/src/lib/cache/message_cache.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MESSAGE_CACHE_H
-#define __MESSAGE_CACHE_H
+#ifndef MESSAGE_CACHE_H
+#define MESSAGE_CACHE_H
#include <string>
#include <boost/shared_ptr.hpp>
@@ -90,5 +90,5 @@ typedef boost::shared_ptr<MessageCache> MessageCachePtr;
} // namespace cache
} // namespace isc
-#endif // __MESSAGE_CACHE_H
+#endif // MESSAGE_CACHE_H
diff --git a/src/lib/cache/message_entry.h b/src/lib/cache/message_entry.h
index 6da27cc..206e601 100644
--- a/src/lib/cache/message_entry.h
+++ b/src/lib/cache/message_entry.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MESSAGE_ENTRY_H
-#define __MESSAGE_ENTRY_H
+#ifndef MESSAGE_ENTRY_H
+#define MESSAGE_ENTRY_H
#include <vector>
#include <dns/message.h>
@@ -199,5 +199,5 @@ typedef boost::shared_ptr<MessageEntry> MessageEntryPtr;
} // namespace cache
} // namespace isc
-#endif // __MESSAGE_ENTRY_H
+#endif // MESSAGE_ENTRY_H
diff --git a/src/lib/cache/message_utility.h b/src/lib/cache/message_utility.h
index a77af07..1a79480 100644
--- a/src/lib/cache/message_utility.h
+++ b/src/lib/cache/message_utility.h
@@ -14,8 +14,8 @@
// $Id$
-#ifndef __MESSAGE_UTILITY_H
-#define __MESSAGE_UTILITY_H
+#ifndef MESSAGE_UTILITY_H
+#define MESSAGE_UTILITY_H
#include <dns/message.h>
@@ -63,4 +63,4 @@ bool canMessageBeCached(const isc::dns::Message& msg);
} // namespace isc
-#endif//__MESSAGE_UTILITY_H
+#endif//MESSAGE_UTILITY_H
diff --git a/src/lib/cache/resolver_cache.h b/src/lib/cache/resolver_cache.h
index 5630bd7..9813cc2 100644
--- a/src/lib/cache/resolver_cache.h
+++ b/src/lib/cache/resolver_cache.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RESOLVER_CACHE_H
-#define __RESOLVER_CACHE_H
+#ifndef RESOLVER_CACHE_H
+#define RESOLVER_CACHE_H
#include <map>
#include <string>
@@ -319,5 +319,5 @@ private:
} // namespace cache
} // namespace isc
-#endif // __RESOLVER_CACHE_H
+#endif // RESOLVER_CACHE_H
diff --git a/src/lib/cache/rrset_cache.h b/src/lib/cache/rrset_cache.h
index a4ea54e..304c6e8 100644
--- a/src/lib/cache/rrset_cache.h
+++ b/src/lib/cache/rrset_cache.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RRSET_CACHE_H
-#define __RRSET_CACHE_H
+#ifndef RRSET_CACHE_H
+#define RRSET_CACHE_H
#include <cache/rrset_entry.h>
#include <nsas/hash_table.h>
@@ -89,5 +89,5 @@ typedef boost::shared_ptr<const RRsetCache> ConstRRsetCachePtr;
} // namespace cache
} // namespace isc
-#endif // __RRSET_CACHE_H
+#endif // RRSET_CACHE_H
diff --git a/src/lib/cache/rrset_copy.h b/src/lib/cache/rrset_copy.h
index e1dc489..6b74bc0 100644
--- a/src/lib/cache/rrset_copy.h
+++ b/src/lib/cache/rrset_copy.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RRSET_COPY_
-#define __RRSET_COPY_
+#ifndef RRSET_COPY
+#define RRSET_COPY
#include <dns/rrset.h>
@@ -38,5 +38,5 @@ rrsetCopy(const isc::dns::AbstractRRset& src, isc::dns::AbstractRRset& dst);
} // namespace cache
} // namespace isc
-#endif // __RRSET_COPY_
+#endif // RRSET_COPY
diff --git a/src/lib/cache/rrset_entry.h b/src/lib/cache/rrset_entry.h
index 129300d..0efda36 100644
--- a/src/lib/cache/rrset_entry.h
+++ b/src/lib/cache/rrset_entry.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RRSET_ENTRY_H
-#define __RRSET_ENTRY_H
+#ifndef RRSET_ENTRY_H
+#define RRSET_ENTRY_H
#include <dns/rrset.h>
#include <dns/message.h>
@@ -132,5 +132,5 @@ typedef boost::shared_ptr<RRsetEntry> RRsetEntryPtr;
} // namespace cache
} // namespace isc
-#endif // __RRSET_ENTRY_H
+#endif // RRSET_ENTRY_H
diff --git a/src/lib/cc/data.h b/src/lib/cc/data.h
index c1147a2..bb84ae2 100644
--- a/src/lib/cc/data.h
+++ b/src/lib/cc/data.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef _ISC_DATA_H
-#define _ISC_DATA_H 1
+#ifndef ISC_DATA_H
+#define ISC_DATA_H 1
#include <string>
#include <vector>
@@ -567,7 +567,7 @@ std::ostream& operator<<(std::ostream& out, const Element& e);
bool operator==(const Element& a, const Element& b);
bool operator!=(const Element& a, const Element& b);
} }
-#endif // _ISC_DATA_H
+#endif // ISC_DATA_H
// Local Variables:
// mode: c++
diff --git a/src/lib/cc/session.h b/src/lib/cc/session.h
index 9b08232..a818291 100644
--- a/src/lib/cc/session.h
+++ b/src/lib/cc/session.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef _ISC_SESSION_H
-#define _ISC_SESSION_H 1
+#ifndef ISC_SESSION_H
+#define ISC_SESSION_H 1
#include <string>
@@ -161,7 +161,7 @@ namespace isc {
} // namespace cc
} // namespace isc
-#endif // _ISC_SESSION_H
+#endif // ISC_SESSION_H
// Local Variables:
// mode: c++
diff --git a/src/lib/config/ccsession.h b/src/lib/config/ccsession.h
index 4b99a44..b4a44d0 100644
--- a/src/lib/config/ccsession.h
+++ b/src/lib/config/ccsession.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __CCSESSION_H
-#define __CCSESSION_H 1
+#ifndef CCSESSION_H
+#define CCSESSION_H 1
#include <config/config_data.h>
#include <config/module_spec.h>
@@ -576,7 +576,7 @@ getRelatedLoggers(isc::data::ConstElementPtr loggers);
} // namespace config
} // namespace isc
-#endif // __CCSESSION_H
+#endif // CCSESSION_H
// Local Variables:
// mode: c++
diff --git a/src/lib/config/config_data.h b/src/lib/config/config_data.h
index 3fdbc25..0bb1bfd 100644
--- a/src/lib/config/config_data.h
+++ b/src/lib/config/config_data.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __CONFIG_DATA_H
-#define __CONFIG_DATA_H 1
+#ifndef CONFIG_DATA_H
+#define CONFIG_DATA_H 1
#include <string>
#include <vector>
diff --git a/src/lib/config/config_log.h b/src/lib/config/config_log.h
index 21709fd..14f681e 100644
--- a/src/lib/config/config_log.h
+++ b/src/lib/config/config_log.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __CONFIG_LOG__H
-#define __CONFIG_LOG__H
+#ifndef CONFIG_LOG_H
+#define CONFIG_LOG_H
#include <log/macros.h>
#include "config_messages.h"
@@ -38,4 +38,4 @@ const int DBG_CONFIG_PROCESS = DBGLVL_TRACE_BASIC;
} // namespace config
} // namespace isc
-#endif // __CONFIG_LOG__H
+#endif // CONFIG_LOG_H
diff --git a/src/lib/config/module_spec.h b/src/lib/config/module_spec.h
index 27dcfe3..d755125 100644
--- a/src/lib/config/module_spec.h
+++ b/src/lib/config/module_spec.h
@@ -13,8 +13,8 @@
// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
// WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#ifndef _MODULE_SPEC_H
-#define _MODULE_SPEC_H 1
+#ifndef MODULE_SPEC_H
+#define MODULE_SPEC_H 1
#include <cc/data.h>
diff --git a/src/lib/config/tests/fake_session.h b/src/lib/config/tests/fake_session.h
index c91b519..7d3cfde 100644
--- a/src/lib/config/tests/fake_session.h
+++ b/src/lib/config/tests/fake_session.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef _ISC_FAKESESSION_H
-#define _ISC_FAKESESSION_H 1
+#ifndef ISC_FAKESESSION_H
+#define ISC_FAKESESSION_H 1
#include <string>
@@ -111,7 +111,7 @@ private:
} // namespace cc
} // namespace isc
-#endif // _ISC_FAKESESSION_H
+#endif // ISC_FAKESESSION_H
// Local Variables:
// mode: c++
diff --git a/src/lib/cryptolink/crypto_hmac.h b/src/lib/cryptolink/crypto_hmac.h
index 2eb0d0e..ac82785 100644
--- a/src/lib/cryptolink/crypto_hmac.h
+++ b/src/lib/cryptolink/crypto_hmac.h
@@ -18,8 +18,8 @@
#include <cryptolink/cryptolink.h>
-#ifndef _ISC_CRYPTO_HMAC_H
-#define _ISC_CRYPTO_HMAC_H
+#ifndef ISC_CRYPTO_HMAC_H
+#define ISC_CRYPTO_HMAC_H
namespace isc {
namespace cryptolink {
@@ -205,5 +205,5 @@ void deleteHMAC(HMAC* hmac);
} // namespace cryptolink
} // namespace isc
-#endif // __ISC_CRYPTO_HMAC
+#endif // ISC_CRYPTO_HMAC_H
diff --git a/src/lib/cryptolink/cryptolink.h b/src/lib/cryptolink/cryptolink.h
index d0f7d38..859065b 100644
--- a/src/lib/cryptolink/cryptolink.h
+++ b/src/lib/cryptolink/cryptolink.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef _ISC_CRYPTO_H
-#define _ISC_CRYPTO_H
+#ifndef ISC_CRYPTO_H
+#define ISC_CRYPTO_H
#include <string>
#include <util/buffer.h>
@@ -205,4 +205,4 @@ private:
} // namespace cryptolink
} // namespace isc
-#endif // _ISC_CRYPTO_H
+#endif // ISC_CRYPTO_H
diff --git a/src/lib/datasrc/client.h b/src/lib/datasrc/client.h
index dab081f..3756a68 100644
--- a/src/lib/datasrc/client.h
+++ b/src/lib/datasrc/client.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DATA_SOURCE_CLIENT_H
-#define __DATA_SOURCE_CLIENT_H 1
+#ifndef DATA_SOURCE_CLIENT_H
+#define DATA_SOURCE_CLIENT_H 1
#include <utility>
diff --git a/src/lib/datasrc/client_list.cc b/src/lib/datasrc/client_list.cc
index 865a1ce..e7fb63b 100644
--- a/src/lib/datasrc/client_list.cc
+++ b/src/lib/datasrc/client_list.cc
@@ -12,17 +12,21 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#include <util/memory_segment_local.h>
#include "client_list.h"
#include "client.h"
#include "factory.h"
#include "memory/memory_client.h"
+#include "memory/zone_table_segment.h"
+#include "memory/zone_writer.h"
+#include "memory/zone_data_loader.h"
#include "logger.h"
#include <dns/masterload.h>
+#include <util/memory_segment_local.h>
#include <memory>
#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
using namespace isc::data;
using namespace isc::dns;
@@ -32,6 +36,7 @@ using boost::lexical_cast;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
using isc::datasrc::memory::InMemoryClient;
+using isc::datasrc::memory::ZoneTableSegment;
namespace isc {
namespace datasrc {
@@ -39,21 +44,24 @@ namespace datasrc {
ConfigurableClientList::DataSourceInfo::DataSourceInfo(
DataSourceClient* data_src_client,
const DataSourceClientContainerPtr& container, bool has_cache,
- const RRClass& rrclass, MemorySegment& mem_sgmt) :
+ const RRClass& rrclass, const shared_ptr<ZoneTableSegment>& segment) :
data_src_client_(data_src_client),
container_(container)
{
if (has_cache) {
- cache_.reset(new InMemoryClient(mem_sgmt, rrclass));
+ cache_.reset(new InMemoryClient(segment, rrclass));
+ ztable_segment_ = segment;
}
}
ConfigurableClientList::DataSourceInfo::DataSourceInfo(
- const RRClass& rrclass, MemorySegment& mem_sgmt, bool has_cache) :
+ const RRClass& rrclass, const shared_ptr<ZoneTableSegment>& segment,
+ bool has_cache) :
data_src_client_(NULL)
{
if (has_cache) {
- cache_.reset(new InMemoryClient(mem_sgmt, rrclass));
+ cache_.reset(new InMemoryClient(segment, rrclass));
+ ztable_segment_ = segment;
}
}
@@ -64,21 +72,10 @@ ConfigurableClientList::DataSourceInfo::getCacheClient() const {
ConfigurableClientList::ConfigurableClientList(const RRClass& rrclass) :
rrclass_(rrclass),
- mem_sgmt_(new util::MemorySegmentLocal),
configuration_(new isc::data::ListElement),
allow_cache_(false)
{}
-ConfigurableClientList::~ConfigurableClientList() {
- // Explicitly clear the contained data source clients, and check memory
- // leak. assert() (with abort on failure) may be too harsh, but
- // it's probably better to find more leaks initially. Once it's stabilized
- // we should probably revisit it.
-
- data_sources_.clear();
- assert(mem_sgmt_->allMemoryDeallocated());
-}
-
void
ConfigurableClientList::configure(const ConstElementPtr& config,
bool allow_cache)
@@ -90,6 +87,8 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
size_t i(0); // Outside of the try to be able to access it in the catch
try {
vector<DataSourceInfo> new_data_sources;
+ shared_ptr<ZoneTableSegment> ztable_segment(
+ ZoneTableSegment::create(*config, rrclass_));
for (; i < config->size(); ++i) {
// Extract the parameters
const ConstElementPtr dconf(config->get(i));
@@ -126,7 +125,8 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
isc_throw(ConfigurationError, "The cache must be enabled "
"for the MasterFiles type");
}
- new_data_sources.push_back(DataSourceInfo(rrclass_, *mem_sgmt_,
+ new_data_sources.push_back(DataSourceInfo(rrclass_,
+ ztable_segment,
true));
} else {
// Ask the factory to create the data source for us
@@ -135,7 +135,7 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
// And put it into the vector
new_data_sources.push_back(DataSourceInfo(ds.first, ds.second,
want_cache, rrclass_,
- *mem_sgmt_));
+ ztable_segment));
}
if (want_cache) {
@@ -337,33 +337,93 @@ ConfigurableClientList::findInternal(MutableResult& candidate,
// and the need_updater parameter is true, get the zone there.
}
+// We still provide this method for backward compatibility. But to not have
+// duplicate code, it is a thin wrapper around getCachedZoneWriter only.
ConfigurableClientList::ReloadResult
ConfigurableClientList::reload(const Name& name) {
+ const ZoneWriterPair result(getCachedZoneWriter(name));
+ if (result.first != ZONE_SUCCESS) {
+ return (result.first);
+ }
+
+ assert(result.second);
+ result.second->load();
+ result.second->install();
+ result.second->cleanup();
+
+ return (ZONE_SUCCESS);
+}
+
+namespace {
+
+// We would like to use boost::bind for this. However, the loadZoneData takes
+// a reference, while we have a shared pointer to the iterator -- and we need
+// to keep it alive as long as the ZoneWriter is alive. Therefore we can't
+// really just dereference it and pass it, since it would get destroyed once
+// the getCachedZoneWriter would end. This class holds the shared pointer
+// alive, otherwise is mostly simple.
+//
+// It might be doable with nested boost::bind, but it would probably look
+// more awkward and complicated than this.
+class IteratorLoader {
+public:
+ IteratorLoader(const RRClass& rrclass, const Name& name,
+ const ZoneIteratorPtr& iterator) :
+ rrclass_(rrclass),
+ name_(name),
+ iterator_(iterator)
+ {}
+ memory::ZoneData* operator()(util::MemorySegment& segment) {
+ return (memory::loadZoneData(segment, rrclass_, name_, *iterator_));
+ }
+private:
+ const RRClass rrclass_;
+ const Name name_;
+ ZoneIteratorPtr iterator_;
+};
+
+// We can't use the loadZoneData function directly in boost::bind, since
+// it is overloaded and the compiler can't choose the correct version
+// reliably and fails. So we simply wrap it into an unique name.
+memory::ZoneData*
+loadZoneDataFromFile(util::MemorySegment& segment, const RRClass& rrclass,
+ const Name& name, const string& filename)
+{
+ return (memory::loadZoneData(segment, rrclass, name, filename));
+}
+
+}
+
+ConfigurableClientList::ZoneWriterPair
+ConfigurableClientList::getCachedZoneWriter(const Name& name) {
if (!allow_cache_) {
- return (CACHE_DISABLED);
+ return (ZoneWriterPair(CACHE_DISABLED, ZoneWriterPtr()));
}
// Try to find the correct zone.
MutableResult result;
findInternal(result, name, true, true);
if (!result.finder) {
- return (ZONE_NOT_FOUND);
+ return (ZoneWriterPair(ZONE_NOT_FOUND, ZoneWriterPtr()));
}
- // Try to convert the finder to in-memory one. If it is the cache,
- // it should work.
- // It is of a different type or there's no cache.
+ // Try to get the in-memory cache for the zone. If there's none,
+ // we can't provide the result.
if (!result.info->cache_) {
- return (ZONE_NOT_CACHED);
+ return (ZoneWriterPair(ZONE_NOT_CACHED, ZoneWriterPtr()));
}
+ memory::LoadAction load_action;
DataSourceClient* client(result.info->data_src_client_);
- if (client) {
- // Now do the final reload. If it does not exist in client,
+ if (client != NULL) {
+ // Now finally provide the writer.
+ // If it does not exist in client,
// DataSourceError is thrown, which is exactly the result what we
// want, so no need to handle it.
ZoneIteratorPtr iterator(client->getIterator(name));
if (!iterator) {
isc_throw(isc::Unexpected, "Null iterator from " << name);
}
- result.info->cache_->load(name, *iterator);
+ // And wrap the iterator into the correct functor (which
+ // keeps it alive as long as it is needed).
+ load_action = IteratorLoader(rrclass_, name, iterator);
} else {
// The MasterFiles special case
const string filename(result.info->cache_->getFileName(name));
@@ -371,9 +431,14 @@ ConfigurableClientList::reload(const Name& name) {
isc_throw(isc::Unexpected, "Confused about missing both filename "
"and data source");
}
- result.info->cache_->load(name, filename);
+ // boost::bind is enough here.
+ load_action = boost::bind(loadZoneDataFromFile, _1, rrclass_, name,
+ filename);
}
- return (ZONE_RELOADED);
+ return (ZoneWriterPair(ZONE_SUCCESS,
+ ZoneWriterPtr(
+ result.info->ztable_segment_->
+ getZoneWriter(load_action, name, rrclass_))));
}
// NOTE: This function is not tested, it would be complicated. However, the
diff --git a/src/lib/datasrc/client_list.h b/src/lib/datasrc/client_list.h
index 8694b4a..d1a35b5 100644
--- a/src/lib/datasrc/client_list.h
+++ b/src/lib/datasrc/client_list.h
@@ -21,6 +21,7 @@
#include <dns/rrclass.h>
#include <cc/data.h>
#include <exceptions/exceptions.h>
+#include "memory/zone_table_segment.h"
#include <vector>
#include <boost/shared_ptr.hpp>
@@ -42,6 +43,7 @@ typedef boost::shared_ptr<DataSourceClientContainer>
// and hide real definitions except for itself and tests.
namespace memory {
class InMemoryClient;
+class ZoneWriter;
}
/// \brief The list of data source clients.
@@ -219,9 +221,6 @@ public:
/// \param rrclass For which class the list should work.
ConfigurableClientList(const isc::dns::RRClass& rrclass);
- /// \brief Destructor
- virtual ~ConfigurableClientList();
-
/// \brief Exception thrown when there's an error in configuration.
class ConfigurationError : public Exception {
public:
@@ -271,7 +270,8 @@ public:
CACHE_DISABLED, ///< The cache is not enabled in this list.
ZONE_NOT_CACHED, ///< Zone is served directly, not from cache.
ZONE_NOT_FOUND, ///< Zone does not exist or not cached.
- ZONE_RELOADED ///< The zone was successfully reloaded.
+ ZONE_SUCCESS ///< The zone was successfully reloaded or
+ /// the writer provided.
};
/// \brief Reloads a cached zone.
@@ -288,6 +288,36 @@ public:
/// the original data source no longer contains the cached zone.
ReloadResult reload(const dns::Name& zone);
+private:
+ /// \brief Convenience type shortcut
+ typedef boost::shared_ptr<memory::ZoneWriter> ZoneWriterPtr;
+public:
+
+ /// \brief Return value of getCachedZoneWriter()
+ ///
+ /// A pair containing status and the zone writer, for the
+ /// getCachedZoneWriter() method.
+ typedef std::pair<ReloadResult, ZoneWriterPtr> ZoneWriterPair;
+
+ /// \brief Return a zone writer that can be used to reload a zone.
+ ///
+ /// This looks up a cached copy of zone and returns the ZoneWriter
+ /// that can be used to reload the content of the zone. This can
+ /// be used instead of reload() -- reload() works synchronously, which
+ /// is not what is needed every time.
+ ///
+ /// \param zone The origin of the zone to reload.
+ /// \return The result has two parts. The first one is a status describing
+ /// if it worked or not (and in case it didn't, also why). If the
+ /// status is ZONE_SUCCESS, the second part contains a shared pointer
+ /// to the writer. If the status is anything else, the second part is
+ /// NULL.
+ /// \throw DataSourceError or anything else that the data source
+ /// containing the zone might throw is propagated.
+ /// \throw DataSourceError if something unexpected happens, like when
+ /// the original data source no longer contains the cached zone.
+ ZoneWriterPair getCachedZoneWriter(const dns::Name& zone);
+
/// \brief Implementation of the ClientList::find.
virtual FindResult find(const dns::Name& zone,
bool want_exact_match = false,
@@ -299,12 +329,16 @@ public:
struct DataSourceInfo {
// Plays a role of default constructor too (for vector)
DataSourceInfo(const dns::RRClass& rrclass,
- util::MemorySegment& mem_sgmt,
+ const boost::shared_ptr
+ <isc::datasrc::memory::ZoneTableSegment>&
+ ztable_segment,
bool has_cache = false);
DataSourceInfo(DataSourceClient* data_src_client,
const DataSourceClientContainerPtr& container,
bool has_cache, const dns::RRClass& rrclass,
- util::MemorySegment& mem_sgmt);
+ const boost::shared_ptr
+ <isc::datasrc::memory::ZoneTableSegment>&
+ ztable_segment);
DataSourceClient* data_src_client_;
DataSourceClientContainerPtr container_;
@@ -315,6 +349,7 @@ public:
// No other applications or tests may use it.
const DataSourceClient* getCacheClient() const;
boost::shared_ptr<memory::InMemoryClient> cache_;
+ boost::shared_ptr<memory::ZoneTableSegment> ztable_segment_;
};
/// \brief The collection of data sources.
@@ -369,12 +404,6 @@ private:
bool want_exact_match, bool want_finder) const;
const isc::dns::RRClass rrclass_;
- /// \brief Memory segment for in-memory cache.
- ///
- /// Note that this must be placed before data_sources_ so it won't be
- /// destroyed before the built objects in the destructor.
- boost::scoped_ptr<util::MemorySegment> mem_sgmt_;
-
/// \brief Currently active configuration.
isc::data::ConstElementPtr configuration_;
diff --git a/src/lib/datasrc/data_source.h b/src/lib/datasrc/data_source.h
index 37c536e..bf5a7d7 100644
--- a/src/lib/datasrc/data_source.h
+++ b/src/lib/datasrc/data_source.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DATA_SOURCE_H
-#define __DATA_SOURCE_H
+#ifndef DATA_SOURCE_H
+#define DATA_SOURCE_H
#include <stdint.h>
diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h
index 6895509..320f327 100644
--- a/src/lib/datasrc/database.h
+++ b/src/lib/datasrc/database.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DATABASE_DATASRC_H
-#define __DATABASE_DATASRC_H
+#ifndef DATABASE_DATASRC_H
+#define DATABASE_DATASRC_H
#include <string>
@@ -1425,7 +1425,7 @@ private:
}
}
-#endif // __DATABASE_DATASRC_H
+#endif // DATABASE_DATASRC_H
// Local Variables:
// mode: c++
diff --git a/src/lib/datasrc/datasrc_config.h.pre.in b/src/lib/datasrc/datasrc_config.h.pre.in
index 9074df6..221cab0 100644
--- a/src/lib/datasrc/datasrc_config.h.pre.in
+++ b/src/lib/datasrc/datasrc_config.h.pre.in
@@ -11,8 +11,9 @@
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DATASRC_CONFIG_H
-#define __DATASRC_CONFIG_H 1
+
+#ifndef DATASRC_CONFIG_H
+#define DATASRC_CONFIG_H 1
namespace isc {
namespace datasrc {
@@ -28,4 +29,4 @@ const char* const BACKEND_LIBRARY_PATH = "@@PKGLIBDIR@@/";
} // end namespace datasrc
} // end namespace isc
-#endif // __DATASRC_CONFIG_H
+#endif // DATASRC_CONFIG_H
diff --git a/src/lib/datasrc/factory.h b/src/lib/datasrc/factory.h
index 2731f58..45e4f9b 100644
--- a/src/lib/datasrc/factory.h
+++ b/src/lib/datasrc/factory.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DATA_SOURCE_FACTORY_H
-#define __DATA_SOURCE_FACTORY_H 1
+#ifndef DATA_SOURCE_FACTORY_H
+#define DATA_SOURCE_FACTORY_H 1
#include <datasrc/data_source.h>
#include <datasrc/client.h>
diff --git a/src/lib/datasrc/iterator.h b/src/lib/datasrc/iterator.h
index 99d3331..e1c6929 100644
--- a/src/lib/datasrc/iterator.h
+++ b/src/lib/datasrc/iterator.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DATASRC_ZONE_ITERATOR_H
-#define __DATASRC_ZONE_ITERATOR_H 1
+#ifndef DATASRC_ZONE_ITERATOR_H
+#define DATASRC_ZONE_ITERATOR_H 1
#include <dns/rrset.h>
@@ -98,7 +98,7 @@ public:
}
}
-#endif // __DATASRC_ZONE_ITERATOR_H
+#endif // DATASRC_ZONE_ITERATOR_H
// Local Variables:
// mode: c++
diff --git a/src/lib/datasrc/logger.h b/src/lib/datasrc/logger.h
index db4e5cb..a270082 100644
--- a/src/lib/datasrc/logger.h
+++ b/src/lib/datasrc/logger.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DATASRC_LOGGER_H
-#define __DATASRC_LOGGER_H
+#ifndef DATASRC_LOGGER_H
+#define DATASRC_LOGGER_H
#include <log/macros.h>
#include <datasrc/datasrc_messages.h>
diff --git a/src/lib/datasrc/memory/benchmarks/rdata_reader_bench.cc b/src/lib/datasrc/memory/benchmarks/rdata_reader_bench.cc
index 4e6af56..7bb919f 100644
--- a/src/lib/datasrc/memory/benchmarks/rdata_reader_bench.cc
+++ b/src/lib/datasrc/memory/benchmarks/rdata_reader_bench.cc
@@ -183,7 +183,6 @@ main(int argc, char* argv[]) {
}
}
argc -= optind;
- argv += optind;
if (argc != 0) {
usage();
}
diff --git a/src/lib/datasrc/memory/benchmarks/rrset_render_bench.cc b/src/lib/datasrc/memory/benchmarks/rrset_render_bench.cc
index bc418e8..266f4f5 100644
--- a/src/lib/datasrc/memory/benchmarks/rrset_render_bench.cc
+++ b/src/lib/datasrc/memory/benchmarks/rrset_render_bench.cc
@@ -179,7 +179,6 @@ main(int argc, char* argv[]) {
}
}
argc -= optind;
- argv += optind;
if (argc != 0) {
usage();
}
diff --git a/src/lib/datasrc/memory/domaintree.h b/src/lib/datasrc/memory/domaintree.h
index 272245d..4816452 100644
--- a/src/lib/datasrc/memory/domaintree.h
+++ b/src/lib/datasrc/memory/domaintree.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef _DOMAINTREE_H
-#define _DOMAINTREE_H 1
+#ifndef DOMAINTREE_H
+#define DOMAINTREE_H 1
//! \file datasrc/memory/domaintree.h
///
@@ -2126,7 +2126,7 @@ DomainTree<T>::dumpDotHelper(std::ostream& os,
} // namespace datasrc
} // namespace isc
-#endif // _DOMAINTREE_H
+#endif // DOMAINTREE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/datasrc/memory/memory_client.cc b/src/lib/datasrc/memory/memory_client.cc
index 2f5fe67..65e1e3b 100644
--- a/src/lib/datasrc/memory/memory_client.cc
+++ b/src/lib/datasrc/memory/memory_client.cc
@@ -22,6 +22,7 @@
#include <datasrc/memory/treenode_rrset.h>
#include <datasrc/memory/zone_finder.h>
#include <datasrc/memory/zone_data_loader.h>
+#include <datasrc/memory/zone_table_segment.h>
#include <util/memory_segment_local.h>
@@ -42,12 +43,14 @@ using namespace std;
using namespace isc::dns;
using namespace isc::dns::rdata;
using namespace isc::datasrc::memory;
+using namespace isc::util;
namespace isc {
namespace datasrc {
namespace memory {
using detail::SegmentObjectHolder;
+using boost::shared_ptr;
namespace { // unnamed namespace
@@ -64,25 +67,19 @@ public:
} // end of unnamed namespace
-InMemoryClient::InMemoryClient(util::MemorySegment& mem_sgmt,
+InMemoryClient::InMemoryClient(shared_ptr<ZoneTableSegment> ztable_segment,
RRClass rrclass) :
- mem_sgmt_(mem_sgmt),
+ ztable_segment_(ztable_segment),
rrclass_(rrclass),
- zone_count_(0)
-{
- SegmentObjectHolder<ZoneTable, RRClass> holder(
- mem_sgmt_, ZoneTable::create(mem_sgmt_, rrclass), rrclass_);
-
- file_name_tree_ = FileNameTree::create(mem_sgmt_, false);
-
- zone_table_ = holder.release();
-}
+ zone_count_(0),
+ file_name_tree_(FileNameTree::create(
+ ztable_segment_->getMemorySegment(), false))
+{}
InMemoryClient::~InMemoryClient() {
+ MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
FileNameDeleter deleter;
- FileNameTree::destroy(mem_sgmt_, file_name_tree_, deleter);
-
- ZoneTable::destroy(mem_sgmt_, zone_table_, rrclass_);
+ FileNameTree::destroy(mem_sgmt, file_name_tree_, deleter);
}
result::Result
@@ -90,8 +87,9 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
const std::string& filename,
ZoneData* zone_data)
{
+ MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
SegmentObjectHolder<ZoneData, RRClass> holder(
- mem_sgmt_, zone_data, rrclass_);
+ mem_sgmt, zone_data, rrclass_);
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEMORY_MEM_ADD_ZONE).
arg(zone_name).arg(rrclass_);
@@ -99,7 +97,7 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
// Set the filename in file_name_tree_ now, so that getFileName()
// can use it (during zone reloading).
FileNameNode* node(NULL);
- switch (file_name_tree_->insert(mem_sgmt_, zone_name, &node)) {
+ switch (file_name_tree_->insert(mem_sgmt, zone_name, &node)) {
case FileNameTree::SUCCESS:
case FileNameTree::ALREADYEXISTS:
// These are OK
@@ -114,9 +112,10 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
const std::string* tstr = node->setData(new std::string(filename));
delete tstr;
- const ZoneTable::AddResult result(zone_table_->addZone(mem_sgmt_, rrclass_,
- zone_name,
- holder.release()));
+ ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
+ const ZoneTable::AddResult result(zone_table->addZone(mem_sgmt, rrclass_,
+ zone_name,
+ holder.release()));
if (result.code == result::SUCCESS) {
// Only increment the zone count if the zone doesn't already
// exist.
@@ -124,7 +123,7 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
}
// Destroy the old instance of the zone if there was any
if (result.zone_data != NULL) {
- ZoneData::destroy(mem_sgmt_, result.zone_data, rrclass_);
+ ZoneData::destroy(mem_sgmt, result.zone_data, rrclass_);
}
return (result.code);
@@ -145,7 +144,8 @@ InMemoryClient::findZone(const isc::dns::Name& zone_name) const {
LOG_DEBUG(logger, DBG_TRACE_DATA,
DATASRC_MEMORY_MEM_FIND_ZONE).arg(zone_name);
- ZoneTable::FindResult result(zone_table_->findZone(zone_name));
+ const ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
+ const ZoneTable::FindResult result(zone_table->findZone(zone_name));
ZoneFinderPtr finder;
if (result.code != result::NOTFOUND) {
@@ -157,7 +157,8 @@ InMemoryClient::findZone(const isc::dns::Name& zone_name) const {
const ZoneData*
InMemoryClient::findZoneData(const isc::dns::Name& zone_name) {
- ZoneTable::FindResult result(zone_table_->findZone(zone_name));
+ const ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
+ const ZoneTable::FindResult result(zone_table->findZone(zone_name));
return (result.zone_data);
}
@@ -168,14 +169,16 @@ InMemoryClient::load(const isc::dns::Name& zone_name,
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEMORY_MEM_LOAD).arg(zone_name).
arg(filename);
- ZoneData* zone_data = loadZoneData(mem_sgmt_, rrclass_, zone_name,
+ MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
+ ZoneData* zone_data = loadZoneData(mem_sgmt, rrclass_, zone_name,
filename);
return (loadInternal(zone_name, filename, zone_data));
}
result::Result
InMemoryClient::load(const isc::dns::Name& zone_name, ZoneIterator& iterator) {
- ZoneData* zone_data = loadZoneData(mem_sgmt_, rrclass_, zone_name,
+ MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
+ ZoneData* zone_data = loadZoneData(mem_sgmt, rrclass_, zone_name,
iterator);
return (loadInternal(zone_name, string(), zone_data));
}
@@ -207,7 +210,7 @@ private:
bool separate_rrs_;
bool ready_;
public:
- MemoryIterator(const RRClass rrclass,
+ MemoryIterator(const RRClass& rrclass,
const ZoneTree& tree, const Name& origin,
bool separate_rrs) :
rrclass_(rrclass),
@@ -306,7 +309,8 @@ public:
ZoneIteratorPtr
InMemoryClient::getIterator(const Name& name, bool separate_rrs) const {
- ZoneTable::FindResult result(zone_table_->findZone(name));
+ const ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
+ const ZoneTable::FindResult result(zone_table->findZone(name));
if (result.code != result::SUCCESS) {
isc_throw(DataSourceError, "No such zone: " + name.toText());
}
diff --git a/src/lib/datasrc/memory/memory_client.h b/src/lib/datasrc/memory/memory_client.h
index 3313c5b..3218c75 100644
--- a/src/lib/datasrc/memory/memory_client.h
+++ b/src/lib/datasrc/memory/memory_client.h
@@ -22,6 +22,8 @@
#include <datasrc/memory/zone_table.h>
#include <datasrc/memory/zone_data.h>
+#include <boost/shared_ptr.hpp>
+
#include <string>
namespace isc {
@@ -34,6 +36,8 @@ class RRsetList;
namespace datasrc {
namespace memory {
+class ZoneTableSegment;
+
/// \brief A data source client that holds all necessary data in memory.
///
/// The \c InMemoryClient class provides an access to a conceptual data
@@ -60,7 +64,7 @@ public:
/// This constructor internally involves resource allocation, and if
/// it fails, a corresponding standard exception will be thrown.
/// It never throws an exception otherwise.
- InMemoryClient(util::MemorySegment& mem_sgmt,
+ InMemoryClient(boost::shared_ptr<ZoneTableSegment> ztable_segment,
isc::dns::RRClass rrclass);
/// The destructor.
@@ -186,10 +190,9 @@ private:
const std::string& filename,
ZoneData* zone_data);
- util::MemorySegment& mem_sgmt_;
+ boost::shared_ptr<ZoneTableSegment> ztable_segment_;
const isc::dns::RRClass rrclass_;
unsigned int zone_count_;
- ZoneTable* zone_table_;
FileNameTree* file_name_tree_;
};
diff --git a/src/lib/datasrc/memory/treenode_rrset.cc b/src/lib/datasrc/memory/treenode_rrset.cc
index f51b2f9..e7ed20c 100644
--- a/src/lib/datasrc/memory/treenode_rrset.cc
+++ b/src/lib/datasrc/memory/treenode_rrset.cc
@@ -342,7 +342,7 @@ TreeNodeRRset::isSameKind(const AbstractRRset& abs_other) const {
// Same for the owner name. Comparing the nodes also detect
// the case where RR classes are different (see the method description
// of the header for details).
- if (node_ != other->node_ ) {
+ if (node_ != other->node_) {
return (false);
}
// If one is constructed with a "real name" and the other isn't
diff --git a/src/lib/datasrc/memory/zone_data_loader.cc b/src/lib/datasrc/memory/zone_data_loader.cc
index 97c8092..d759901 100644
--- a/src/lib/datasrc/memory/zone_data_loader.cc
+++ b/src/lib/datasrc/memory/zone_data_loader.cc
@@ -165,7 +165,7 @@ ZoneDataLoader::getCurrentName() const {
ZoneData*
loadZoneDataInternal(util::MemorySegment& mem_sgmt,
- const isc::dns::RRClass rrclass,
+ const isc::dns::RRClass& rrclass,
const Name& zone_name,
boost::function<void(LoadCallback)> rrset_installer)
{
@@ -223,7 +223,7 @@ generateRRsetFromIterator(ZoneIterator* iterator, LoadCallback callback) {
ZoneData*
loadZoneData(util::MemorySegment& mem_sgmt,
- const isc::dns::RRClass rrclass,
+ const isc::dns::RRClass& rrclass,
const isc::dns::Name& zone_name,
const std::string& zone_file)
{
@@ -236,7 +236,7 @@ loadZoneData(util::MemorySegment& mem_sgmt,
ZoneData*
loadZoneData(util::MemorySegment& mem_sgmt,
- const isc::dns::RRClass rrclass,
+ const isc::dns::RRClass& rrclass,
const isc::dns::Name& zone_name,
ZoneIterator& iterator)
{
diff --git a/src/lib/datasrc/memory/zone_data_loader.h b/src/lib/datasrc/memory/zone_data_loader.h
index 298af46..6f02fcb 100644
--- a/src/lib/datasrc/memory/zone_data_loader.h
+++ b/src/lib/datasrc/memory/zone_data_loader.h
@@ -48,7 +48,7 @@ struct EmptyZone : public InvalidParameter {
/// \param zone_name The name of the zone that is being loaded.
/// \param zone_file Filename which contains the zone data for \c zone_name.
ZoneData* loadZoneData(util::MemorySegment& mem_sgmt,
- const isc::dns::RRClass rrclass,
+ const isc::dns::RRClass& rrclass,
const isc::dns::Name& zone_name,
const std::string& zone_file);
@@ -65,7 +65,7 @@ ZoneData* loadZoneData(util::MemorySegment& mem_sgmt,
/// \param zone_name The name of the zone that is being loaded.
/// \param iterator Iterator that returns RRsets to load into the zone.
ZoneData* loadZoneData(util::MemorySegment& mem_sgmt,
- const isc::dns::RRClass rrclass,
+ const isc::dns::RRClass& rrclass,
const isc::dns::Name& zone_name,
ZoneIterator& iterator);
diff --git a/src/lib/datasrc/memory/zone_table.cc b/src/lib/datasrc/memory/zone_table.cc
index 836b020..c0237f5 100644
--- a/src/lib/datasrc/memory/zone_table.cc
+++ b/src/lib/datasrc/memory/zone_table.cc
@@ -47,23 +47,22 @@ typedef boost::function<void(ZoneData*)> ZoneDataDeleterType;
}
ZoneTable*
-ZoneTable::create(util::MemorySegment& mem_sgmt, RRClass zone_class) {
+ZoneTable::create(util::MemorySegment& mem_sgmt, const RRClass& zone_class) {
SegmentObjectHolder<ZoneTableTree, ZoneDataDeleterType> holder(
mem_sgmt, ZoneTableTree::create(mem_sgmt),
boost::bind(deleteZoneData, &mem_sgmt, _1, zone_class));
void* p = mem_sgmt.allocate(sizeof(ZoneTable));
- ZoneTable* zone_table = new(p) ZoneTable(holder.get());
+ ZoneTable* zone_table = new(p) ZoneTable(zone_class, holder.get());
holder.release();
return (zone_table);
}
void
-ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable,
- RRClass zone_class)
+ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable)
{
ZoneTableTree::destroy(mem_sgmt, ztable->zones_.get(),
boost::bind(deleteZoneData, &mem_sgmt, _1,
- zone_class));
+ ztable->rrclass_));
mem_sgmt.deallocate(ztable, sizeof(ZoneTable));
}
diff --git a/src/lib/datasrc/memory/zone_table.h b/src/lib/datasrc/memory/zone_table.h
index 024558e..1b369b9 100644
--- a/src/lib/datasrc/memory/zone_table.h
+++ b/src/lib/datasrc/memory/zone_table.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DATASRC_MEMORY_ZONE_TABLE_H
-#define __DATASRC_MEMORY_ZONE_TABLE_H 1
+#ifndef DATASRC_MEMORY_ZONE_TABLE_H
+#define DATASRC_MEMORY_ZONE_TABLE_H 1
#include <util/memory_segment.h>
@@ -102,7 +102,9 @@ private:
/// This constructor internally involves resource allocation, and if
/// it fails, a corresponding standard exception will be thrown.
/// It never throws an exception otherwise.
- ZoneTable(ZoneTableTree* zones) : zones_(zones)
+ ZoneTable(const dns::RRClass& rrclass, ZoneTableTree* zones) :
+ rrclass_(rrclass),
+ zones_(zones)
{}
public:
@@ -119,7 +121,7 @@ public:
/// \param zone_class The RR class of the zone. It must be the RR class
/// that is supposed to be associated to the zone table.
static ZoneTable* create(util::MemorySegment& mem_sgmt,
- dns::RRClass zone_class);
+ const dns::RRClass& zone_class);
/// \brief Destruct and deallocate \c ZoneTable
///
@@ -135,8 +137,7 @@ public:
/// \param ztable A non NULL pointer to a valid \c ZoneTable object
/// that was originally created by the \c create() method (the behavior
/// is undefined if this condition isn't met).
- static void destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable,
- dns::RRClass zone_class);
+ static void destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable);
/// Add a new zone to the \c ZoneTable.
///
@@ -185,12 +186,13 @@ public:
FindResult findZone(const isc::dns::Name& name) const;
private:
+ const dns::RRClass rrclass_;
boost::interprocess::offset_ptr<ZoneTableTree> zones_;
};
}
}
}
-#endif // __DATASRC_MEMORY_ZONE_TABLE_H
+#endif // DATASRC_MEMORY_ZONE_TABLE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/datasrc/memory/zone_table_segment.cc b/src/lib/datasrc/memory/zone_table_segment.cc
index 7a80e3c..50587c4 100644
--- a/src/lib/datasrc/memory/zone_table_segment.cc
+++ b/src/lib/datasrc/memory/zone_table_segment.cc
@@ -15,17 +15,20 @@
#include <datasrc/memory/zone_table_segment.h>
#include <datasrc/memory/zone_table_segment_local.h>
+using namespace isc::dns;
+
namespace isc {
namespace datasrc {
namespace memory {
ZoneTableSegment*
-ZoneTableSegment::create(const isc::data::Element&) {
+ZoneTableSegment::create(const isc::data::Element&, const RRClass& rrclass) {
/// FIXME: For now, we always return ZoneTableSegmentLocal. This
/// should be updated eventually to parse the passed Element
/// argument and construct a corresponding ZoneTableSegment
/// implementation.
- return (new ZoneTableSegmentLocal);
+
+ return (new ZoneTableSegmentLocal(rrclass));
}
void
diff --git a/src/lib/datasrc/memory/zone_table_segment.h b/src/lib/datasrc/memory/zone_table_segment.h
index 8731718..88e69f6 100644
--- a/src/lib/datasrc/memory/zone_table_segment.h
+++ b/src/lib/datasrc/memory/zone_table_segment.h
@@ -12,9 +12,10 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ZONE_TABLE_SEGMENT_H__
-#define __ZONE_TABLE_SEGMENT_H__
+#ifndef ZONE_TABLE_SEGMENT_H
+#define ZONE_TABLE_SEGMENT_H
+#include <dns/rrclass.h>
#include <datasrc/memory/zone_table.h>
#include "load_action.h"
#include <cc/data.h>
@@ -42,38 +43,21 @@ class ZoneWriter;
/// map from domain names to zone locators) in memory.
struct ZoneTableHeader {
public:
+ ZoneTableHeader(ZoneTable* zone_table) :
+ table_(zone_table)
+ {}
+
/// \brief Returns a pointer to the underlying zone table.
ZoneTable* getTable() {
- return (table.get());
+ return (table_.get());
}
/// \brief const version of \c getTable().
const ZoneTable* getTable() const {
- return (table.get());
+ return (table_.get());
}
-
- /// \brief Method to set the internal table
- ///
- /// The interface is tentative, we don't know if this is the correct place
- /// and way to set the data. But for now, we need something to be there
- /// at least for the tests. So we have this. For this reason, there are
- /// no tests for this method directly. Do not use in actual
- /// implementation.
- ///
- /// It can be used only once, to initially set it. It can't replace the
- /// one already there.
- ///
- /// \param table Pointer to the table to use.
- /// \throw isc::Unexpected if called the second time.
- void setTable(ZoneTable* table) {
- if (this->table.get() != NULL) {
- isc_throw(isc::Unexpected, "Replacing table");
- }
- this->table = table;
- }
-
private:
- boost::interprocess::offset_ptr<ZoneTable> table;
+ boost::interprocess::offset_ptr<ZoneTable> table_;
};
/// \brief Manages a ZoneTableHeader, an entry point into a table of
@@ -91,7 +75,7 @@ protected:
/// An instance implementing this interface is expected to be
/// created by the factory method (\c create()), so this constructor
/// is protected.
- ZoneTableSegment()
+ ZoneTableSegment(isc::dns::RRClass)
{}
public:
/// \brief Destructor
@@ -119,7 +103,20 @@ public:
/// \param config The configuration based on which a derived object
/// is returned.
/// \return Returns a ZoneTableSegment object
- static ZoneTableSegment* create(const isc::data::Element& config);
+ static ZoneTableSegment* create(const isc::data::Element& config,
+ const isc::dns::RRClass& rrclass);
+
+ /// \brief Temporary/Testing version of create.
+ ///
+ /// This exists as a temporary solution during the migration phase
+ /// towards using the ZoneTableSegment. It doesn't take a config,
+ /// but a memory segment instead. If you can, you should use the
+ /// other version, this one will be gone soon.
+ ///
+ /// \param segment The memory segment to use.
+ /// \return Returns a new ZoneTableSegment object.
+ /// \todo Remove this method.
+ static ZoneTableSegment* create(isc::util::MemorySegment& segment);
/// \brief Destroy a ZoneTableSegment
///
@@ -149,4 +146,4 @@ public:
} // namespace datasrc
} // namespace isc
-#endif // __ZONE_TABLE_SEGMENT_H__
+#endif // ZONE_TABLE_SEGMENT_H
diff --git a/src/lib/datasrc/memory/zone_table_segment_local.cc b/src/lib/datasrc/memory/zone_table_segment_local.cc
index 2630d1e..fdaf678 100644
--- a/src/lib/datasrc/memory/zone_table_segment_local.cc
+++ b/src/lib/datasrc/memory/zone_table_segment_local.cc
@@ -15,12 +15,29 @@
#include <datasrc/memory/zone_table_segment_local.h>
#include "zone_writer_local.h"
+using namespace isc::dns;
using namespace isc::util;
namespace isc {
namespace datasrc {
namespace memory {
+ZoneTableSegmentLocal::ZoneTableSegmentLocal(const RRClass& rrclass) :
+ ZoneTableSegment(rrclass),
+ header_(ZoneTable::create(mem_sgmt_, rrclass))
+{
+}
+
+ZoneTableSegmentLocal::~ZoneTableSegmentLocal() {
+ // Explicitly clear the contained data, and check memory
+ // leak. assert() (with abort on failure) may be too harsh, but
+ // it's probably better to find more leaks initially. Once it's stabilized
+ // we should probably revisit it.
+
+ ZoneTable::destroy(mem_sgmt_, header_.getTable());
+ assert(mem_sgmt_.allMemoryDeallocated());
+}
+
// After more methods' definitions are added here, it would be a good
// idea to move getHeader() and getMemorySegment() definitions to the
// header file.
diff --git a/src/lib/datasrc/memory/zone_table_segment_local.h b/src/lib/datasrc/memory/zone_table_segment_local.h
index b83bd49..e08ca39 100644
--- a/src/lib/datasrc/memory/zone_table_segment_local.h
+++ b/src/lib/datasrc/memory/zone_table_segment_local.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ZONE_TABLE_SEGMENT_LOCAL_H__
-#define __ZONE_TABLE_SEGMENT_LOCAL_H__
+#ifndef ZONE_TABLE_SEGMENT_LOCAL_H
+#define ZONE_TABLE_SEGMENT_LOCAL_H
#include <datasrc/memory/zone_table_segment.h>
#include <util/memory_segment_local.h>
@@ -37,11 +37,10 @@ protected:
/// Instances are expected to be created by the factory method
/// (\c ZoneTableSegment::create()), so this constructor is
/// protected.
- ZoneTableSegmentLocal()
- {}
+ ZoneTableSegmentLocal(const isc::dns::RRClass& rrclass);
public:
/// \brief Destructor
- virtual ~ZoneTableSegmentLocal() {}
+ virtual ~ZoneTableSegmentLocal();
/// \brief Return the ZoneTableHeader for the local zone table
/// segment implementation.
@@ -59,12 +58,12 @@ public:
const dns::Name& origin,
const dns::RRClass& rrclass);
private:
- ZoneTableHeader header_;
isc::util::MemorySegmentLocal mem_sgmt_;
+ ZoneTableHeader header_;
};
} // namespace memory
} // namespace datasrc
} // namespace isc
-#endif // __ZONE_TABLE_SEGMENT_LOCAL_H__
+#endif // ZONE_TABLE_SEGMENT_LOCAL_H
diff --git a/src/lib/datasrc/memory_datasrc.h b/src/lib/datasrc/memory_datasrc.h
index be545d4..4e277e0 100644
--- a/src/lib/datasrc/memory_datasrc.h
+++ b/src/lib/datasrc/memory_datasrc.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MEMORY_DATA_SOURCE_H
-#define __MEMORY_DATA_SOURCE_H 1
+#ifndef MEMORY_DATA_SOURCE_H
+#define MEMORY_DATA_SOURCE_H 1
#include <string>
@@ -360,7 +360,7 @@ extern "C" void destroyInstance(DataSourceClient* instance);
}
}
-#endif // __DATA_SOURCE_MEMORY_H
+#endif // MEMORY_DATA_SOURCE_H
// Local Variables:
// mode: c++
// End:
diff --git a/src/lib/datasrc/rbnode_rrset.h b/src/lib/datasrc/rbnode_rrset.h
index 1c23e05..cbb1b71 100644
--- a/src/lib/datasrc/rbnode_rrset.h
+++ b/src/lib/datasrc/rbnode_rrset.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RBNODE_RRSET_H
-#define __RBNODE_RRSET_H
+#ifndef RBNODE_RRSET_H
+#define RBNODE_RRSET_H
#include <dns/messagerenderer.h>
#include <dns/name.h>
@@ -227,4 +227,4 @@ private:
} // namespace datasrc
} // namespace isc
-#endif // __RBNODE_RRSET_H
+#endif // RBNODE_RRSET_H
diff --git a/src/lib/datasrc/rbtree.h b/src/lib/datasrc/rbtree.h
index eb971e8..d0efa0a 100644
--- a/src/lib/datasrc/rbtree.h
+++ b/src/lib/datasrc/rbtree.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef _RBTREE_H
-#define _RBTREE_H 1
+#ifndef RBTREE_H
+#define RBTREE_H 1
//! \file datasrc/rbtree.h
///
@@ -1986,7 +1986,7 @@ RBTree<T>::dumpDotHelper(std::ostream& os, const RBNode<T>* node,
}
}
-#endif // _RBTREE_H
+#endif // RBTREE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/datasrc/result.h b/src/lib/datasrc/result.h
index f7ca363..5a28d08 100644
--- a/src/lib/datasrc/result.h
+++ b/src/lib/datasrc/result.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DATASRC_RESULT_H
-#define __DATASRC_RESULT_H 1
+#ifndef DATASRC_RESULT_H
+#define DATASRC_RESULT_H 1
namespace isc {
namespace datasrc {
diff --git a/src/lib/datasrc/sqlite3_accessor.h b/src/lib/datasrc/sqlite3_accessor.h
index 3e44d5b..a8112d4 100644
--- a/src/lib/datasrc/sqlite3_accessor.h
+++ b/src/lib/datasrc/sqlite3_accessor.h
@@ -13,8 +13,8 @@
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DATASRC_SQLITE3_ACCESSOR_H
-#define __DATASRC_SQLITE3_ACCESSOR_H
+#ifndef DATASRC_SQLITE3_ACCESSOR_H
+#define DATASRC_SQLITE3_ACCESSOR_H
#include <datasrc/database.h>
#include <datasrc/data_source.h>
@@ -291,7 +291,7 @@ extern "C" void destroyInstance(DataSourceClient* instance);
}
}
-#endif // __DATASRC_SQLITE3_CONNECTION_H
+#endif // DATASRC_SQLITE3_ACCESSOR_H
// Local Variables:
// mode: c++
diff --git a/src/lib/datasrc/tests/client_list_unittest.cc b/src/lib/datasrc/tests/client_list_unittest.cc
index d995d5c..d1ff852 100644
--- a/src/lib/datasrc/tests/client_list_unittest.cc
+++ b/src/lib/datasrc/tests/client_list_unittest.cc
@@ -12,14 +12,14 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#include <util/memory_segment_local.h>
-
#include <datasrc/client_list.h>
#include <datasrc/client.h>
#include <datasrc/iterator.h>
#include <datasrc/data_source.h>
#include <datasrc/memory/memory_client.h>
+#include <datasrc/memory/zone_table_segment.h>
#include <datasrc/memory/zone_finder.h>
+#include <datasrc/memory/zone_writer.h>
#include <dns/rrclass.h>
#include <dns/rrttl.h>
@@ -27,15 +27,20 @@
#include <gtest/gtest.h>
+#include <boost/shared_ptr.hpp>
+
#include <set>
#include <fstream>
using namespace isc::datasrc;
using isc::datasrc::memory::InMemoryClient;
+using isc::datasrc::memory::ZoneTableSegment;
using isc::datasrc::memory::InMemoryZoneFinder;
using namespace isc::data;
using namespace isc::dns;
-using namespace boost;
+// don't import the entire boost namespace. It will unexpectedly hide uintXX_t
+// for some systems.
+using boost::shared_ptr;
using namespace std;
namespace {
@@ -255,7 +260,9 @@ public:
" \"type\": \"test_type\","
" \"params\": [\"example.org\", \"example.com\", "
" \"noiter.org\", \"null.org\"]"
- "}]"))
+ "}]")),
+ config_(Element::fromJSON("{}")),
+ ztable_segment_(ZoneTableSegment::create(*config_, rrclass_))
{
for (size_t i(0); i < ds_count; ++ i) {
shared_ptr<MockDataSourceClient>
@@ -263,7 +270,7 @@ public:
ds_.push_back(ds);
ds_info_.push_back(ConfigurableClientList::DataSourceInfo(
ds.get(), DataSourceClientContainerPtr(),
- false, rrclass_, mem_sgmt_));
+ false, rrclass_, ztable_segment_));
}
}
@@ -283,13 +290,14 @@ public:
// Create cache from the temporary data source, and push it to the
// client list.
- const shared_ptr<InMemoryClient> cache(new InMemoryClient(mem_sgmt_,
- rrclass_));
+ const shared_ptr<InMemoryClient> cache(
+ new InMemoryClient(ztable_segment_, rrclass_));
cache->load(zone, *mock_client.getIterator(zone, false));
ConfigurableClientList::DataSourceInfo& dsrc_info =
list_->getDataSources()[index];
dsrc_info.cache_ = cache;
+ dsrc_info.ztable_segment_ = ztable_segment_;
}
// Check the positive result is as we expect it.
void positiveResult(const ClientList::FindResult& result,
@@ -309,7 +317,7 @@ public:
result.life_keeper_);
if (from_cache) {
EXPECT_NE(shared_ptr<InMemoryZoneFinder>(),
- dynamic_pointer_cast<InMemoryZoneFinder>(
+ boost::dynamic_pointer_cast<InMemoryZoneFinder>(
result.finder_)) << "Finder is not from cache";
EXPECT_TRUE(NULL !=
dynamic_cast<InMemoryClient*>(result.dsrc_client_));
@@ -362,12 +370,12 @@ public:
shared_ptr<InMemoryClient>());
}
const RRClass rrclass_;
- isc::util::MemorySegmentLocal mem_sgmt_;
shared_ptr<TestedList> list_;
const ClientList::FindResult negative_result_;
vector<shared_ptr<MockDataSourceClient> > ds_;
vector<ConfigurableClientList::DataSourceInfo> ds_info_;
- const ConstElementPtr config_elem_, config_elem_zones_;
+ const ConstElementPtr config_elem_, config_elem_zones_, config_;
+ shared_ptr<ZoneTableSegment> ztable_segment_;
};
// Test the test itself
@@ -844,116 +852,169 @@ TEST_F(ListTest, BadMasterFile) {
true);
}
+// This allows us to test two versions of the reloading code
+// (One by calling reload(), one by obtaining a ZoneWriter and
+// playing with that). Once we deprecate reload(), we should revert this
+// change and not use typed tests any more.
+template<class UpdateType>
+class ReloadTest : public ListTest {
+public:
+ ConfigurableClientList::ReloadResult doReload(const Name& origin);
+};
+
+// Version with calling reload()
+class ReloadUpdateType {};
+template<>
+ConfigurableClientList::ReloadResult
+ReloadTest<ReloadUpdateType>::doReload(const Name& origin) {
+ return (list_->reload(origin));
+};
+
+// Version with the ZoneWriter
+class WriterUpdateType {};
+template<>
+ConfigurableClientList::ReloadResult
+ReloadTest<WriterUpdateType>::doReload(const Name& origin) {
+ ConfigurableClientList::ZoneWriterPair
+ result(list_->getCachedZoneWriter(origin));
+ if (result.first == ConfigurableClientList::ZONE_SUCCESS) {
+ // Can't use ASSERT_NE here, it would want to return(), which
+ // it can't in non-void function.
+ if (result.second) {
+ result.second->load();
+ result.second->install();
+ result.second->cleanup();
+ } else {
+ ADD_FAILURE() << "getCachedZoneWriter returned ZONE_SUCCESS, "
+ "but the writer is NULL";
+ }
+ } else {
+ EXPECT_EQ(static_cast<memory::ZoneWriter*>(NULL),
+ result.second.get());
+ }
+ return (result.first);
+}
+
+// Typedefs for the GTEST guts to make it work
+typedef ::testing::Types<ReloadUpdateType, WriterUpdateType> UpdateTypes;
+TYPED_TEST_CASE(ReloadTest, UpdateTypes);
+
// Test we can reload a zone
-TEST_F(ListTest, reloadSuccess) {
- list_->configure(config_elem_zones_, true);
+TYPED_TEST(ReloadTest, reloadSuccess) {
+ this->list_->configure(this->config_elem_zones_, true);
const Name name("example.org");
- prepareCache(0, name);
+ this->prepareCache(0, name);
// The cache currently contains a tweaked version of zone, which doesn't
// have apex NS. So the lookup should result in NXRRSET.
EXPECT_EQ(ZoneFinder::NXRRSET,
- list_->find(name).finder_->find(name, RRType::NS())->code);
+ this->list_->find(name).finder_->find(name, RRType::NS())->code);
// Now reload the full zone. It should be there now.
- EXPECT_EQ(ConfigurableClientList::ZONE_RELOADED, list_->reload(name));
+ EXPECT_EQ(ConfigurableClientList::ZONE_SUCCESS, this->doReload(name));
EXPECT_EQ(ZoneFinder::SUCCESS,
- list_->find(name).finder_->find(name, RRType::NS())->code);
+ this->list_->find(name).finder_->find(name, RRType::NS())->code);
}
// The cache is not enabled. The load should be rejected.
-TEST_F(ListTest, reloadNotEnabled) {
- list_->configure(config_elem_zones_, false);
+TYPED_TEST(ReloadTest, reloadNotEnabled) {
+ this->list_->configure(this->config_elem_zones_, false);
const Name name("example.org");
// We put the cache in even when not enabled. This won't confuse the thing.
- prepareCache(0, name);
+ this->prepareCache(0, name);
// See the reloadSuccess test. This should result in NXRRSET.
EXPECT_EQ(ZoneFinder::NXRRSET,
- list_->find(name).finder_->find(name, RRType::NS())->code);
+ this->list_->find(name).finder_->find(name, RRType::NS())->code);
// Now reload. It should reject it.
- EXPECT_EQ(ConfigurableClientList::CACHE_DISABLED, list_->reload(name));
+ EXPECT_EQ(ConfigurableClientList::CACHE_DISABLED, this->doReload(name));
// Nothing changed here
EXPECT_EQ(ZoneFinder::NXRRSET,
- list_->find(name).finder_->find(name, RRType::NS())->code);
+ this->list_->find(name).finder_->find(name, RRType::NS())->code);
}
// Test several cases when the zone does not exist
-TEST_F(ListTest, reloadNoSuchZone) {
- list_->configure(config_elem_zones_, true);
+TYPED_TEST(ReloadTest, reloadNoSuchZone) {
+ this->list_->configure(this->config_elem_zones_, true);
const Name name("example.org");
// We put the cache in even when not enabled. This won't confuse the
// reload method, as that one looks at the real state of things, not
// at the configuration.
- prepareCache(0, Name("example.com"));
+ this->prepareCache(0, Name("example.com"));
// Not in the data sources
EXPECT_EQ(ConfigurableClientList::ZONE_NOT_FOUND,
- list_->reload(Name("example.cz")));
+ this->doReload(Name("exmaple.cz")));
// Not cached
- EXPECT_EQ(ConfigurableClientList::ZONE_NOT_FOUND, list_->reload(name));
+ EXPECT_EQ(ConfigurableClientList::ZONE_NOT_FOUND, this->doReload(name));
// Partial match
EXPECT_EQ(ConfigurableClientList::ZONE_NOT_FOUND,
- list_->reload(Name("sub.example.com")));
+ this->doReload(Name("sub.example.com")));
// Nothing changed here - these zones don't exist
EXPECT_EQ(static_cast<isc::datasrc::DataSourceClient*>(NULL),
- list_->find(name).dsrc_client_);
+ this->list_->find(name).dsrc_client_);
EXPECT_EQ(static_cast<isc::datasrc::DataSourceClient*>(NULL),
- list_->find(Name("example.cz")).dsrc_client_);
+ this->list_->find(Name("example.cz")).dsrc_client_);
EXPECT_EQ(static_cast<isc::datasrc::DataSourceClient*>(NULL),
- list_->find(Name("sub.example.com"), true).dsrc_client_);
+ this->list_->find(Name("sub.example.com"), true).dsrc_client_);
// Not reloaded, so NS shouldn't be visible yet.
EXPECT_EQ(ZoneFinder::NXRRSET,
- list_->find(Name("example.com")).finder_->
+ this->list_->find(Name("example.com")).finder_->
find(Name("example.com"), RRType::NS())->code);
}
// Check we gracefuly throw an exception when a zone disappeared in
// the underlying data source when we want to reload it
-TEST_F(ListTest, reloadZoneGone) {
- list_->configure(config_elem_, true);
+TYPED_TEST(ReloadTest, reloadZoneGone) {
+ this->list_->configure(this->config_elem_, true);
const Name name("example.org");
// We put in a cache for non-existant zone. This emulates being loaded
// and then the zone disappearing. We prefill the cache, so we can check
// it.
- prepareCache(0, name);
+ this->prepareCache(0, name);
// The (cached) zone contains zone's SOA
EXPECT_EQ(ZoneFinder::SUCCESS,
- list_->find(name).finder_->find(name, RRType::SOA())->code);
+ this->list_->find(name).finder_->find(name,
+ RRType::SOA())->code);
// The zone is not there, so abort the reload.
- EXPECT_THROW(list_->reload(name), DataSourceError);
+ EXPECT_THROW(this->doReload(name), DataSourceError);
// The (cached) zone is not hurt.
EXPECT_EQ(ZoneFinder::SUCCESS,
- list_->find(name).finder_->find(name, RRType::SOA())->code);
+ this->list_->find(name).finder_->find(name,
+ RRType::SOA())->code);
}
// The underlying data source throws. Check we don't modify the state.
-TEST_F(ListTest, reloadZoneThrow) {
- list_->configure(config_elem_zones_, true);
+TYPED_TEST(ReloadTest, reloadZoneThrow) {
+ this->list_->configure(this->config_elem_zones_, true);
const Name name("noiter.org");
- prepareCache(0, name);
+ this->prepareCache(0, name);
// The zone contains stuff now
EXPECT_EQ(ZoneFinder::SUCCESS,
- list_->find(name).finder_->find(name, RRType::SOA())->code);
+ this->list_->find(name).finder_->find(name,
+ RRType::SOA())->code);
// The iterator throws, so abort the reload.
- EXPECT_THROW(list_->reload(name), isc::NotImplemented);
+ EXPECT_THROW(this->doReload(name), isc::NotImplemented);
// The zone is not hurt.
EXPECT_EQ(ZoneFinder::SUCCESS,
- list_->find(name).finder_->find(name, RRType::SOA())->code);
+ this->list_->find(name).finder_->find(name,
+ RRType::SOA())->code);
}
-TEST_F(ListTest, reloadNullIterator) {
- list_->configure(config_elem_zones_, true);
+TYPED_TEST(ReloadTest, reloadNullIterator) {
+ this->list_->configure(this->config_elem_zones_, true);
const Name name("null.org");
- prepareCache(0, name);
+ this->prepareCache(0, name);
// The zone contains stuff now
EXPECT_EQ(ZoneFinder::SUCCESS,
- list_->find(name).finder_->find(name, RRType::SOA())->code);
+ this->list_->find(name).finder_->find(name,
+ RRType::SOA())->code);
// The iterator throws, so abort the reload.
- EXPECT_THROW(list_->reload(name), isc::Unexpected);
+ EXPECT_THROW(this->doReload(name), isc::Unexpected);
// The zone is not hurt.
EXPECT_EQ(ZoneFinder::SUCCESS,
- list_->find(name).finder_->find(name, RRType::SOA())->code);
+ this->list_->find(name).finder_->find(name,
+ RRType::SOA())->code);
}
// Test we can reload the master files too (special-cased)
-TEST_F(ListTest, reloadMasterFile) {
+TYPED_TEST(ReloadTest, reloadMasterFile) {
const char* const install_cmd = INSTALL_PROG " -c " TEST_DATA_DIR
"/root.zone " TEST_DATA_BUILDDIR "/root.zone.copied";
if (system(install_cmd) != 0) {
@@ -971,21 +1032,21 @@ TEST_F(ListTest, reloadMasterFile) {
" \".\": \"" TEST_DATA_BUILDDIR "/root.zone.copied\""
" }"
"}]"));
- list_->configure(elem, true);
+ this->list_->configure(elem, true);
// Add a record that is not in the zone
EXPECT_EQ(ZoneFinder::NXDOMAIN,
- list_->find(Name(".")).finder_->find(Name("nosuchdomain"),
- RRType::TXT())->code);
+ this->list_->find(Name(".")).finder_->find(Name("nosuchdomain"),
+ RRType::TXT())->code);
ofstream f;
f.open(TEST_DATA_BUILDDIR "/root.zone.copied", ios::out | ios::app);
f << "nosuchdomain.\t\t3600\tIN\tTXT\ttest" << std::endl;
f.close();
// Do the reload.
- EXPECT_EQ(ConfigurableClientList::ZONE_RELOADED, list_->reload(Name(".")));
+ EXPECT_EQ(ConfigurableClientList::ZONE_SUCCESS, this->doReload(Name(".")));
// It is here now.
EXPECT_EQ(ZoneFinder::SUCCESS,
- list_->find(Name(".")).finder_->find(Name("nosuchdomain"),
- RRType::TXT())->code);
+ this->list_->find(Name(".")).finder_->find(Name("nosuchdomain"),
+ RRType::TXT())->code);
}
}
diff --git a/src/lib/datasrc/tests/memory/Makefile.am b/src/lib/datasrc/tests/memory/Makefile.am
index 6a3d9a9..67e63b9 100644
--- a/src/lib/datasrc/tests/memory/Makefile.am
+++ b/src/lib/datasrc/tests/memory/Makefile.am
@@ -32,6 +32,7 @@ run_unittests_SOURCES += ../../tests/faked_nsec3.h ../../tests/faked_nsec3.cc
run_unittests_SOURCES += memory_segment_test.h
run_unittests_SOURCES += segment_object_holder_unittest.cc
run_unittests_SOURCES += memory_client_unittest.cc
+run_unittests_SOURCES += zone_table_segment_test.h
run_unittests_SOURCES += zone_table_segment_unittest.cc
run_unittests_SOURCES += zone_writer_unittest.cc
diff --git a/src/lib/datasrc/tests/memory/memory_client_unittest.cc b/src/lib/datasrc/tests/memory/memory_client_unittest.cc
index 8785a10..c1d2f30 100644
--- a/src/lib/datasrc/tests/memory/memory_client_unittest.cc
+++ b/src/lib/datasrc/tests/memory/memory_client_unittest.cc
@@ -36,16 +36,22 @@
#include <testutils/dnsmessage_test.h>
#include "memory_segment_test.h"
+#include "zone_table_segment_test.h"
#include <gtest/gtest.h>
+#include <boost/lexical_cast.hpp>
+#include <boost/shared_ptr.hpp>
+
#include <new> // for bad_alloc
+using namespace isc::data;
using namespace isc::dns;
using namespace isc::dns::rdata;
using namespace isc::datasrc;
using namespace isc::datasrc::memory;
using namespace isc::testutils;
+using boost::shared_ptr;
using std::vector;
namespace {
@@ -156,20 +162,22 @@ public:
class MemoryClientTest : public ::testing::Test {
protected:
MemoryClientTest() : zclass_(RRClass::IN()),
- client_(new InMemoryClient(mem_sgmt_, zclass_))
+ ztable_segment_(new test::ZoneTableSegmentTest(
+ zclass_, mem_sgmt_)),
+ client_(new InMemoryClient(ztable_segment_, zclass_))
{}
~MemoryClientTest() {
- if (client_ != NULL) {
- delete client_;
- }
+ delete client_;
}
void TearDown() {
delete client_;
client_ = NULL;
+ ztable_segment_.reset();
EXPECT_TRUE(mem_sgmt_.allMemoryDeallocated()); // catch any leak here.
}
const RRClass zclass_;
test::MemorySegmentTest mem_sgmt_;
+ shared_ptr<ZoneTableSegment> ztable_segment_;
InMemoryClient* client_;
};
@@ -289,14 +297,19 @@ TEST_F(MemoryClientTest, loadMemoryAllocationFailures) {
// Just to check that things get cleaned up
for (int i = 1; i < 16; i++) {
- SCOPED_TRACE("For throw count = " + i);
+ SCOPED_TRACE("For throw count = " +
+ boost::lexical_cast<std::string>(i));
mem_sgmt_.setThrowCount(i);
EXPECT_THROW({
+ shared_ptr<ZoneTableSegment> ztable_segment(
+ new test::ZoneTableSegmentTest(
+ zclass_, mem_sgmt_));
+
// Include the InMemoryClient construction too here. Now,
// even allocations done from InMemoryClient constructor
// fail (due to MemorySegmentTest throwing) and we check for
// leaks when this happens.
- InMemoryClient client2(mem_sgmt_, zclass_);
+ InMemoryClient client2(ztable_segment, zclass_);
client2.load(Name("example.org"),
TEST_DATA_DIR "/example.org.zone");
}, std::bad_alloc);
diff --git a/src/lib/datasrc/tests/memory/zone_table_segment_test.h b/src/lib/datasrc/tests/memory/zone_table_segment_test.h
new file mode 100644
index 0000000..2078036
--- /dev/null
+++ b/src/lib/datasrc/tests/memory/zone_table_segment_test.h
@@ -0,0 +1,116 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef DATASRC_MEMORY_ZONE_TABLE_SEGMENT_TEST_H
+#define DATASRC_MEMORY_ZONE_TABLE_SEGMENT_TEST_H 1
+
+#include <datasrc/memory/zone_table_segment.h>
+#include <datasrc/memory/zone_table.h>
+#include <datasrc/memory/zone_data.h>
+#include <datasrc/memory/zone_writer_local.h>
+
+namespace isc {
+namespace datasrc {
+namespace memory {
+namespace test {
+
+// A special ZoneTableSegment that can be used for tests. It can be
+// passed a MemorySegment that can be used later to test if all memory
+// was de-allocated on it.
+class ZoneTableSegmentTest : public ZoneTableSegment {
+public:
+ ZoneTableSegmentTest(isc::dns::RRClass rrclass,
+ isc::util::MemorySegment& mem_sgmt) :
+ ZoneTableSegment(rrclass),
+ mem_sgmt_(mem_sgmt),
+ header_(ZoneTable::create(mem_sgmt_, rrclass))
+ {}
+
+ virtual ~ZoneTableSegmentTest() {
+ ZoneTable::destroy(mem_sgmt_, header_.getTable());
+ }
+
+ virtual ZoneTableHeader& getHeader() {
+ return (header_);
+ }
+
+ virtual const ZoneTableHeader& getHeader() const {
+ return (header_);
+ }
+
+ virtual isc::util::MemorySegment& getMemorySegment() {
+ return (mem_sgmt_);
+ }
+
+ virtual ZoneWriter* getZoneWriter(const LoadAction& load_action,
+ const dns::Name& name,
+ const dns::RRClass& rrclass)
+ {
+ return (new Writer(this, load_action, name, rrclass));
+ }
+
+private:
+ isc::util::MemorySegment& mem_sgmt_;
+ ZoneTableHeader header_;
+
+ // A writer for this segment. The implementation is similar
+ // to ZoneWriterLocal, but all the error handling is stripped
+ // for simplicity. Also, we do everything inside the
+ // install(), for the same reason. We just need something
+ // inside the tests, not a full-blown implementation
+ // for background loading.
+ class Writer : public ZoneWriter {
+ public:
+ Writer(ZoneTableSegmentTest* segment, const LoadAction& load_action,
+ const dns::Name& name, const dns::RRClass& rrclass) :
+ segment_(segment),
+ load_action_(load_action),
+ name_(name),
+ rrclass_(rrclass)
+ {}
+
+ void load() {}
+
+ void install() {
+ ZoneTable* table(segment_->getHeader().getTable());
+ const ZoneTable::AddResult
+ result(table->addZone(segment_->getMemorySegment(), rrclass_,
+ name_,
+ load_action_(segment_->
+ getMemorySegment())));
+ if (result.zone_data != NULL) {
+ ZoneData::destroy(segment_->getMemorySegment(),
+ result.zone_data, rrclass_);
+ }
+ }
+
+ virtual void cleanup() {}
+ private:
+ ZoneTableSegmentTest* segment_;
+ LoadAction load_action_;
+ dns::Name name_;
+ dns::RRClass rrclass_;
+ };
+};
+
+} // namespace test
+} // namespace memory
+} // namespace datasrc
+} // namespace isc
+
+#endif // DATASRC_MEMORY_ZONE_TABLE_SEGMENT_TEST_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc b/src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc
index 928b6c4..ac114e2 100644
--- a/src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc
+++ b/src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc
@@ -12,78 +12,68 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#include <datasrc/memory/zone_table_segment.h>
#include <datasrc/memory/zone_writer_local.h>
-#include <gtest/gtest.h>
+#include <datasrc/memory/zone_table_segment_local.h>
+#include <util/memory_segment_local.h>
+#include <gtest/gtest.h>
#include <boost/scoped_ptr.hpp>
-using boost::scoped_ptr;
-using isc::dns::Name;
-using isc::dns::RRClass;
+using namespace isc::dns;
using namespace isc::datasrc::memory;
using namespace isc::data;
using namespace isc::util;
using namespace std;
+using boost::scoped_ptr;
namespace {
class ZoneTableSegmentTest : public ::testing::Test {
protected:
ZoneTableSegmentTest() :
- config_(Element::fromJSON("{}")),
- segment_(ZoneTableSegment::create((*config_.get())))
+ ztable_segment_(ZoneTableSegment::create(isc::data::NullElement(),
+ RRClass::IN()))
{}
- ~ZoneTableSegmentTest() {
- if (segment_ != NULL) {
- ZoneTableSegment::destroy(segment_);
- }
- }
-
void TearDown() {
- // Catch any future leaks here.
- const MemorySegment& mem_sgmt = segment_->getMemorySegment();
- EXPECT_TRUE(mem_sgmt.allMemoryDeallocated());
-
- ZoneTableSegment::destroy(segment_);
- segment_ = NULL;
+ ZoneTableSegment::destroy(ztable_segment_);
+ ztable_segment_ = NULL;
}
- const ElementPtr config_;
- ZoneTableSegment* segment_;
+ ZoneTableSegment* ztable_segment_;
};
TEST_F(ZoneTableSegmentTest, create) {
// By default, a local zone table segment is created.
- EXPECT_NE(static_cast<void*>(NULL), segment_);
+ EXPECT_NE(static_cast<void*>(NULL), ztable_segment_);
}
// Helper function to check const and non-const methods.
template <typename TS, typename TH, typename TT>
void
-testGetHeader(ZoneTableSegment* segment) {
- TH& header = static_cast<TS*>(segment)->getHeader();
+testGetHeader(ZoneTableSegment* ztable_segment) {
+ TH& header = static_cast<TS*>(ztable_segment)->getHeader();
- // The zone table is unset.
+ // The zone table must be set.
TT* table = header.getTable();
- EXPECT_EQ(static_cast<void*>(NULL), table);
+ EXPECT_NE(static_cast<void*>(NULL), table);
}
TEST_F(ZoneTableSegmentTest, getHeader) {
// non-const version.
- testGetHeader<ZoneTableSegment, ZoneTableHeader, ZoneTable>(segment_);
+ testGetHeader<ZoneTableSegment, ZoneTableHeader, ZoneTable>
+ (ztable_segment_);
// const version.
testGetHeader<const ZoneTableSegment, const ZoneTableHeader,
- const ZoneTable>(segment_);
+ const ZoneTable>(ztable_segment_);
}
TEST_F(ZoneTableSegmentTest, getMemorySegment) {
// This doesn't do anything fun except test the API.
- MemorySegment& mem_sgmt = segment_->getMemorySegment();
- EXPECT_TRUE(mem_sgmt.allMemoryDeallocated());
+ MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
+ mem_sgmt.allMemoryDeallocated(); // use mem_sgmt
}
ZoneData*
@@ -95,8 +85,8 @@ loadAction(MemorySegment&) {
// Test we can get a writer.
TEST_F(ZoneTableSegmentTest, getZoneWriter) {
scoped_ptr<ZoneWriter>
- writer(segment_->getZoneWriter(loadAction, Name("example.org"),
- RRClass::IN()));
+ writer(ztable_segment_->getZoneWriter(loadAction, Name("example.org"),
+ RRClass::IN()));
// We have to get something
EXPECT_NE(static_cast<void*>(NULL), writer.get());
// And for now, it should be the local writer
diff --git a/src/lib/datasrc/tests/memory/zone_table_unittest.cc b/src/lib/datasrc/tests/memory/zone_table_unittest.cc
index 80f2a6e..3c53a59 100644
--- a/src/lib/datasrc/tests/memory/zone_table_unittest.cc
+++ b/src/lib/datasrc/tests/memory/zone_table_unittest.cc
@@ -46,11 +46,11 @@ protected:
{}
~ZoneTableTest() {
if (zone_table != NULL) {
- ZoneTable::destroy(mem_sgmt_, zone_table, zclass_);
+ ZoneTable::destroy(mem_sgmt_, zone_table);
}
}
void TearDown() {
- ZoneTable::destroy(mem_sgmt_, zone_table, zclass_);
+ ZoneTable::destroy(mem_sgmt_, zone_table);
zone_table = NULL;
EXPECT_TRUE(mem_sgmt_.allMemoryDeallocated()); // catch any leak here.
}
diff --git a/src/lib/datasrc/tests/memory/zone_writer_unittest.cc b/src/lib/datasrc/tests/memory/zone_writer_unittest.cc
index bc9b103..13bcc3b 100644
--- a/src/lib/datasrc/tests/memory/zone_writer_unittest.cc
+++ b/src/lib/datasrc/tests/memory/zone_writer_unittest.cc
@@ -41,7 +41,8 @@ public:
// FIXME: The NullElement probably isn't the best one, but we don't
// know how the config will look, so it just fills the argument
// (which is currently ignored)
- segment_(ZoneTableSegment::create(isc::data::NullElement())),
+ segment_(ZoneTableSegment::create(isc::data::NullElement(),
+ RRClass::IN())),
writer_(new
ZoneWriterLocal(dynamic_cast<ZoneTableSegmentLocal*>(segment_.
get()),
@@ -51,20 +52,10 @@ public:
load_throw_(false),
load_null_(false),
load_data_(false)
- {
- // TODO: The setTable is only a temporary interface
- segment_->getHeader().
- setTable(ZoneTable::create(segment_->getMemorySegment(),
- RRClass::IN()));
- }
+ {}
void TearDown() {
// Release the writer
writer_.reset();
- // Release the table we used
- ZoneTable::destroy(segment_->getMemorySegment(),
- segment_->getHeader().getTable(), RRClass::IN());
- // And check we freed all memory
- EXPECT_TRUE(segment_->getMemorySegment().allMemoryDeallocated());
}
protected:
scoped_ptr<ZoneTableSegment> segment_;
diff --git a/src/lib/datasrc/tests/test_client.h b/src/lib/datasrc/tests/test_client.h
index 2c692d3..1e35cd3 100644
--- a/src/lib/datasrc/tests/test_client.h
+++ b/src/lib/datasrc/tests/test_client.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TEST_DATA_SOURCE_CLIENT_H
-#define __TEST_DATA_SOURCE_CLIENT_H 1
+#ifndef TEST_DATA_SOURCE_CLIENT_H
+#define TEST_DATA_SOURCE_CLIENT_H 1
#include <dns/name.h>
#include <dns/rrclass.h>
@@ -64,7 +64,7 @@ createSQLite3Client(dns::RRClass zclass, const dns::Name& zname,
} // end of datasrc
} // end of isc
-#endif // __TEST_DATA_SOURCE_CLIENT_H
+#endif // TEST_DATA_SOURCE_CLIENT_H
// Local Variables:
// mode: c++
diff --git a/src/lib/datasrc/tests/zone_finder_context_unittest.cc b/src/lib/datasrc/tests/zone_finder_context_unittest.cc
index 14429ae..1a4cae2 100644
--- a/src/lib/datasrc/tests/zone_finder_context_unittest.cc
+++ b/src/lib/datasrc/tests/zone_finder_context_unittest.cc
@@ -14,14 +14,13 @@
#include <exceptions/exceptions.h>
-#include <util/memory_segment_local.h>
-
#include <dns/masterload.h>
#include <dns/name.h>
#include <dns/rrclass.h>
#include <datasrc/zone.h>
#include <datasrc/memory/memory_client.h>
+#include <datasrc/memory/zone_table_segment.h>
#include <datasrc/database.h>
#include <datasrc/sqlite3_accessor.h>
@@ -41,10 +40,12 @@
using namespace std;
using boost::shared_ptr;
+using namespace isc::data;
using namespace isc::util;
using namespace isc::dns;
using namespace isc::datasrc;
using isc::datasrc::memory::InMemoryClient;
+using isc::datasrc::memory::ZoneTableSegment;
using namespace isc::testutils;
namespace {
@@ -58,15 +59,17 @@ typedef shared_ptr<DataSourceClient> DataSourceClientPtr;
// This is the type used as the test parameter. Note that this is
// intentionally a plain old type (i.e. a function pointer), not a class;
// otherwise it could cause initialization fiasco at the instantiation time.
-typedef DataSourceClientPtr (*ClientCreator)(MemorySegment&, RRClass,
- const Name&);
+typedef DataSourceClientPtr (*ClientCreator)(RRClass, const Name&);
// Creator for the in-memory client to be tested
DataSourceClientPtr
-createInMemoryClient(MemorySegment& mem_sgmt, RRClass zclass,
- const Name& zname)
+createInMemoryClient(RRClass zclass, const Name& zname)
{
- shared_ptr<InMemoryClient> client(new InMemoryClient(mem_sgmt, zclass));
+ const ElementPtr config(Element::fromJSON("{}"));
+ shared_ptr<ZoneTableSegment> ztable_segment(
+ ZoneTableSegment::create(*config, zclass));
+ shared_ptr<InMemoryClient> client(new InMemoryClient(ztable_segment,
+ zclass));
client->load(zname, TEST_ZONE_FILE);
return (client);
@@ -78,7 +81,7 @@ addRRset(ZoneUpdaterPtr updater, ConstRRsetPtr rrset) {
}
DataSourceClientPtr
-createSQLite3Client(MemorySegment&, RRClass zclass, const Name& zname) {
+createSQLite3Client(RRClass zclass, const Name& zname) {
// We always begin with an empty template SQLite3 DB file and install
// the zone data from the zone file to ensure both cases have the
// same test data.
@@ -105,7 +108,7 @@ class ZoneFinderContextTest :
{
protected:
ZoneFinderContextTest() : qclass_(RRClass::IN()), qzone_("example.org") {
- client_ = (*GetParam())(mem_sgmt_, qclass_, qzone_);
+ client_ = (*GetParam())(qclass_, qzone_);
REQUESTED_A.push_back(RRType::A());
REQUESTED_AAAA.push_back(RRType::AAAA());
REQUESTED_BOTH.push_back(RRType::A());
@@ -116,7 +119,6 @@ protected:
ASSERT_TRUE(finder_);
}
- MemorySegmentLocal mem_sgmt_;
const RRClass qclass_;
const Name qzone_;
DataSourceClientPtr client_;
diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h
index 36a1cff..9572ed0 100644
--- a/src/lib/datasrc/zone.h
+++ b/src/lib/datasrc/zone.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ZONE_H
-#define __ZONE_H 1
+#ifndef ZONE_H
+#define ZONE_H 1
#include <dns/name.h>
#include <dns/rrset.h>
@@ -1065,7 +1065,7 @@ typedef boost::shared_ptr<ZoneJournalReader> ZoneJournalReaderPtr;
} // end of datasrc
} // end of isc
-#endif // __ZONE_H
+#endif // ZONE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/datasrc/zonetable.h b/src/lib/datasrc/zonetable.h
index 93a021c..911391c 100644
--- a/src/lib/datasrc/zonetable.h
+++ b/src/lib/datasrc/zonetable.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ZONETABLE_H
-#define __ZONETABLE_H 1
+#ifndef ZONETABLE_H
+#define ZONETABLE_H 1
#include <util/memory_segment.h>
@@ -153,7 +153,7 @@ private:
};
}
}
-#endif // __ZONETABLE_H
+#endif // ZONETABLE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dhcp/Makefile.am b/src/lib/dhcp/Makefile.am
index 140bb00..43a1b04 100644
--- a/src/lib/dhcp/Makefile.am
+++ b/src/lib/dhcp/Makefile.am
@@ -16,7 +16,6 @@ CLEANFILES = *.gcno *.gcda
lib_LTLIBRARIES = libb10-dhcp++.la libb10-dhcpsrv.la
libb10_dhcp___la_SOURCES =
libb10_dhcp___la_SOURCES += libdhcp++.cc libdhcp++.h
-libb10_dhcp___la_SOURCES += lease_mgr.cc lease_mgr.h
libb10_dhcp___la_SOURCES += iface_mgr.cc iface_mgr.h
libb10_dhcp___la_SOURCES += iface_mgr_linux.cc
libb10_dhcp___la_SOURCES += iface_mgr_bsd.cc
@@ -39,7 +38,9 @@ libb10_dhcpsrv_la_SOURCES = cfgmgr.cc cfgmgr.h
libb10_dhcpsrv_la_SOURCES += pool.cc pool.h
libb10_dhcpsrv_la_SOURCES += subnet.cc subnet.h
libb10_dhcpsrv_la_SOURCES += triplet.h
+libb10_dhcpsrv_la_SOURCES += lease_mgr.cc lease_mgr.h
libb10_dhcpsrv_la_SOURCES += addr_utilities.cc addr_utilities.h
+libb10_dhcpsrv_la_SOURCES += alloc_engine.cc alloc_engine.h
libb10_dhcpsrv_la_CXXFLAGS = $(AM_CXXFLAGS)
libb10_dhcpsrv_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
libb10_dhcpsrv_la_LIBADD = $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
diff --git a/src/lib/dhcp/addr_utilities.cc b/src/lib/dhcp/addr_utilities.cc
index de1e8b4..db35ca6 100644
--- a/src/lib/dhcp/addr_utilities.cc
+++ b/src/lib/dhcp/addr_utilities.cc
@@ -45,9 +45,13 @@ const uint8_t bitMask6[]= { 0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
/// @param len prefix length
isc::asiolink::IOAddress firstAddrInPrefix6(const isc::asiolink::IOAddress& prefix,
uint8_t len) {
-
uint8_t packed[V6ADDRESS_LEN];
+ if (len > 128) {
+ isc_throw(isc::BadValue,
+ "Too large netmask. 0..128 is allowed in IPv6");
+ }
+
// First we copy the whole address as 16 bytes.
memcpy(packed, prefix.getAddress().to_v6().to_bytes().data(), 16);
@@ -104,7 +108,7 @@ isc::asiolink::IOAddress firstAddrInPrefix4(const isc::asiolink::IOAddress& pref
isc::asiolink::IOAddress lastAddrInPrefix4(const isc::asiolink::IOAddress& prefix,
uint8_t len) {
uint32_t addr = prefix;
- if (len>32) {
+ if (len > 32) {
isc_throw(isc::BadValue, "Too large netmask. 0..32 is allowed in IPv4");
}
@@ -123,6 +127,11 @@ isc::asiolink::IOAddress lastAddrInPrefix6(const isc::asiolink::IOAddress& prefi
uint8_t packed[V6ADDRESS_LEN];
+ if (len > 128) {
+ isc_throw(isc::BadValue,
+ "Too large netmask. 0..128 is allowed in IPv6");
+ }
+
// First we copy the whole address as 16 bytes.
memcpy(packed, prefix.getAddress().to_v6().to_bytes().data(), 16);
diff --git a/src/lib/dhcp/alloc_engine.cc b/src/lib/dhcp/alloc_engine.cc
new file mode 100644
index 0000000..8ebefdc
--- /dev/null
+++ b/src/lib/dhcp/alloc_engine.cc
@@ -0,0 +1,274 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <alloc_engine.h>
+
+#include <cstring>
+
+using namespace isc::asiolink;
+
+namespace isc {
+namespace dhcp {
+
+AllocEngine::IterativeAllocator::IterativeAllocator()
+ :Allocator() {
+}
+
+isc::asiolink::IOAddress
+AllocEngine::IterativeAllocator::increaseAddress(const isc::asiolink::IOAddress& addr) {
+ uint8_t packed[V6ADDRESS_LEN];
+ int len;
+
+ // First we copy the whole address as 16 bytes.
+ if (addr.getFamily()==AF_INET) {
+ // IPv4
+ std::memcpy(packed, addr.getAddress().to_v4().to_bytes().data(), 4);
+ len = 4;
+ } else {
+ // IPv6
+ std::memcpy(packed, addr.getAddress().to_v6().to_bytes().data(), 16);
+ len = 16;
+ }
+
+ for (int i = len - 1; i >= 0; --i) {
+ ++packed[i];
+ if (packed[i] != 0) {
+ break;
+ }
+ }
+
+ return (IOAddress::from_bytes(addr.getFamily(), packed));
+}
+
+
+isc::asiolink::IOAddress
+AllocEngine::IterativeAllocator::pickAddress(const Subnet6Ptr& subnet,
+ const DuidPtr&,
+ const IOAddress&) {
+
+ // Let's get the last allocated address. It is usually set correctly,
+ // but there are times when it won't be (like after removing a pool or
+ // perhaps restaring the server).
+ IOAddress last = subnet->getLastAllocated();
+
+ const Pool6Collection& pools = subnet->getPools();
+
+ if (pools.size() == 0) {
+ isc_throw(AllocFailed, "No pools defined in selected subnet");
+ }
+
+ // first we need to find a pool the last address belongs to.
+ Pool6Collection::const_iterator it;
+ for (it = pools.begin(); it != pools.end(); ++it) {
+ if ((*it)->inRange(last)) {
+ break;
+ }
+ }
+
+ // last one was bogus for one of several reasons:
+ // - we just booted up and that's the first address we're allocating
+ // - a subnet was removed or other reconfiguration just completed
+ // - perhaps allocation algorithm was changed
+ if (it == pools.end()) {
+ // ok to access first element directly. We checked that pools is non-empty
+ IOAddress next = pools[0]->getFirstAddress();
+ subnet->setLastAllocated(next);
+ return (next);
+ }
+
+ // Ok, we have a pool that the last address belonged to, let's use it.
+
+ IOAddress next = increaseAddress(last); // basically addr++
+ if ((*it)->inRange(next)) {
+ // the next one is in the pool as well, so we haven't hit pool boundary yet
+ subnet->setLastAllocated(next);
+ return (next);
+ }
+
+ // We hit pool boundary, let's try to jump to the next pool and try again
+ ++it;
+ if (it == pools.end()) {
+ // Really out of luck today. That was the last pool. Let's rewind
+ // to the beginning.
+ next = pools[0]->getFirstAddress();
+ subnet->setLastAllocated(next);
+ return (next);
+ }
+
+ // there is a next pool, let's try first adddress from it
+ next = (*it)->getFirstAddress();
+ subnet->setLastAllocated(next);
+ return (next);
+}
+
+AllocEngine::HashedAllocator::HashedAllocator()
+ :Allocator() {
+ isc_throw(NotImplemented, "Hashed allocator is not implemented");
+}
+
+
+isc::asiolink::IOAddress
+AllocEngine::HashedAllocator::pickAddress(const Subnet6Ptr&,
+ const DuidPtr&,
+ const IOAddress&) {
+ isc_throw(NotImplemented, "Hashed allocator is not implemented");
+}
+
+AllocEngine::RandomAllocator::RandomAllocator()
+ :Allocator() {
+ isc_throw(NotImplemented, "Random allocator is not implemented");
+}
+
+
+isc::asiolink::IOAddress
+AllocEngine::RandomAllocator::pickAddress(const Subnet6Ptr&,
+ const DuidPtr&,
+ const IOAddress&) {
+ isc_throw(NotImplemented, "Random allocator is not implemented");
+}
+
+
+AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts)
+ :attempts_(attempts) {
+ switch (engine_type) {
+ case ALLOC_ITERATIVE:
+ allocator_ = boost::shared_ptr<Allocator>(new IterativeAllocator());
+ break;
+ case ALLOC_HASHED:
+ allocator_ = boost::shared_ptr<Allocator>(new HashedAllocator());
+ break;
+ case ALLOC_RANDOM:
+ allocator_ = boost::shared_ptr<Allocator>(new RandomAllocator());
+ break;
+
+ default:
+ isc_throw(BadValue, "Invalid/unsupported allocation algorithm");
+ }
+}
+
+Lease6Ptr
+AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
+ const DuidPtr& duid,
+ uint32_t iaid,
+ const IOAddress& hint,
+ bool fake_allocation /* = false */ ) {
+
+ // That check is not necessary. We create allocator in AllocEngine
+ // constructor
+ if (!allocator_) {
+ isc_throw(InvalidOperation, "No allocator selected");
+ }
+
+ // check if there's existing lease for that subnet/duid/iaid combination.
+ Lease6Ptr existing = LeaseMgr::instance().getLease6(*duid, iaid, subnet->getID());
+ if (existing) {
+ // we have a lease already. This is a returning client, probably after
+ // his reboot.
+ return (existing);
+ }
+
+ // check if the hint is in pool and is available
+ if (subnet->inPool(hint)) {
+ existing = LeaseMgr::instance().getLease6(hint);
+ if (!existing) {
+ /// @todo: check if the hint is reserved once we have host support
+ /// implemented
+
+ // the hint is valid and not currently used, let's create a lease for it
+ Lease6Ptr lease = createLease(subnet, duid, iaid, hint, fake_allocation);
+
+ // It can happen that the lease allocation failed (we could have lost
+ // the race condition. That means that the hint is lo longer usable and
+ // we need to continue the regular allocation path.
+ if (lease) {
+ return (lease);
+ }
+ }
+ }
+
+ unsigned int i = attempts_;
+ do {
+ IOAddress candidate = allocator_->pickAddress(subnet, duid, hint);
+
+ /// @todo: check if the address is reserved once we have host support
+ /// implemented
+
+ Lease6Ptr existing = LeaseMgr::instance().getLease6(candidate);
+ // there's no existing lease for selected candidate, so it is
+ // free. Let's allocate it.
+ if (!existing) {
+ Lease6Ptr lease = createLease(subnet, duid, iaid, candidate,
+ fake_allocation);
+ if (lease) {
+ return (lease);
+ }
+
+ // Although the address was free just microseconds ago, it may have
+ // been taken just now. If the lease insertion fails, we continue
+ // allocation attempts.
+ }
+
+ // continue trying allocation until we run out of attempts
+ // (or attempts are set to 0, which means infinite)
+ --i;
+ } while ( i || !attempts_);
+
+ isc_throw(AllocFailed, "Failed to allocate address after " << attempts_
+ << " tries");
+}
+
+Lease6Ptr AllocEngine::createLease(const Subnet6Ptr& subnet,
+ const DuidPtr& duid,
+ uint32_t iaid,
+ const IOAddress& addr,
+ bool fake_allocation /*= false */ ) {
+
+ Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr, duid, iaid,
+ subnet->getPreferred(), subnet->getValid(),
+ subnet->getT1(), subnet->getT2(), subnet->getID()));
+
+ if (!fake_allocation) {
+ // That is a real (REQUEST) allocation
+ bool status = LeaseMgr::instance().addLease(lease);
+
+ if (status) {
+
+ return (lease);
+ } else {
+ // One of many failures with LeaseMgr (e.g. lost connection to the
+ // database, database failed etc.). One notable case for that
+ // is that we are working in multi-process mode and we lost a race
+ // (some other process got that address first)
+ return (Lease6Ptr());
+ }
+ } else {
+ // That is only fake (SOLICIT without rapid-commit) allocation
+
+ // It is for advertise only. We should not insert the lease into LeaseMgr,
+ // but rather check that we could have inserted it.
+ Lease6Ptr existing = LeaseMgr::instance().getLease6(addr);
+ if (!existing) {
+ return (lease);
+ } else {
+ return (Lease6Ptr());
+ }
+ }
+}
+
+AllocEngine::~AllocEngine() {
+ // no need to delete allocator. smart_ptr will do the trick for us
+}
+
+}; // end of isc::dhcp namespace
+}; // end of isc namespace
diff --git a/src/lib/dhcp/alloc_engine.h b/src/lib/dhcp/alloc_engine.h
new file mode 100644
index 0000000..496703a
--- /dev/null
+++ b/src/lib/dhcp/alloc_engine.h
@@ -0,0 +1,228 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef ALLOC_ENGINE_H
+#define ALLOC_ENGINE_H
+
+#include <boost/shared_ptr.hpp>
+#include <boost/noncopyable.hpp>
+#include <dhcp/duid.h>
+#include <dhcp/subnet.h>
+#include <asiolink/io_address.h>
+#include <dhcp/lease_mgr.h>
+
+namespace isc {
+namespace dhcp {
+
+/// An exception that is thrown when allocation module fails (e.g. due to
+/// lack of available addresses)
+class AllocFailed : public isc::Exception {
+public:
+
+ /// @brief constructor
+ ///
+ /// @param file name of the file, where exception occurred
+ /// @param line line of the file, where exception occurred
+ /// @param what text description of the issue that caused exception
+ AllocFailed(const char* file, size_t line, const char* what)
+ : isc::Exception(file, line, what) {}
+};
+
+/// @brief DHCPv4 and DHCPv6 allocation engine
+///
+/// This class represents DHCP allocation engine. It is responsible
+/// for picking subnets, choosing and allocating a lease, extending,
+/// renewing, releasing and possibly expiring leases.
+///
+/// @todo: Does not handle out of leases well
+/// @todo: Does not handle out of allocation attempts well
+class AllocEngine : public boost::noncopyable {
+protected:
+
+ /// @brief base class for all address/prefix allocation algorithms
+ ///
+ /// This is an abstract class that should not be used directly, but rather
+ /// specialized implementations should be used instead.
+ class Allocator {
+ public:
+
+ /// @brief picks one address out of available pools in a given subnet
+ ///
+ /// This method returns one address from the available pools in the
+ /// specified subnet. It should not check if the address is used or
+ /// reserved - AllocEngine will check that and will call pickAddress
+ /// again if necessary. The number of times this method is called will
+ /// increase as the number of available leases will decrease.
+ virtual isc::asiolink::IOAddress
+ pickAddress(const Subnet6Ptr& subnet, const DuidPtr& duid,
+ const isc::asiolink::IOAddress& hint) = 0;
+
+ /// @brief virtual destructor
+ virtual ~Allocator() {
+ }
+ protected:
+ };
+
+ /// @brief Address/prefix allocator that iterates over all addresses
+ ///
+ /// This class implements iterative algorithm that returns all addresses in
+ /// a pool iteratively, one after another. Once the last address is reached,
+ /// it starts allocating from the beginning of the first pool (i.e. it loops
+ /// over).
+ class IterativeAllocator : public Allocator {
+ public:
+
+ /// @brief default constructor
+ ///
+ /// Does not do anything
+ IterativeAllocator();
+
+ /// @brief returns the next address from pools in a subnet
+ ///
+ /// @param subnet next address will be returned from pool of that subnet
+ /// @param duid Client's DUID (ignored)
+ /// @param hint client's hint (ignored)
+ /// @return the next address
+ virtual isc::asiolink::IOAddress
+ pickAddress(const Subnet6Ptr& subnet,
+ const DuidPtr& duid,
+ const isc::asiolink::IOAddress& hint);
+ private:
+
+ /// @brief returns an address by one
+ /// @param addr address to be increased
+ /// @return address increased by one
+ isc::asiolink::IOAddress increaseAddress(const isc::asiolink::IOAddress& addr);
+
+ };
+
+ /// @brief Address/prefix allocator that gets an address based on a hash
+ ///
+ /// @todo: This is a skeleton class for now and is missing implementation.
+ class HashedAllocator : public Allocator {
+ public:
+
+ /// @brief default constructor (does nothing)
+ HashedAllocator();
+
+ /// @brief returns an address based on hash calculated from client's DUID.
+ ///
+ /// @todo: Implement this method
+ ///
+ /// @param subnet an address will be picked from pool of that subnet
+ /// @param duid Client's DUID
+ /// @param hint a hint (last address that was picked)
+ /// @return selected address
+ virtual isc::asiolink::IOAddress pickAddress(const Subnet6Ptr& subnet,
+ const DuidPtr& duid,
+ const isc::asiolink::IOAddress& hint);
+ };
+
+ /// @brief Random allocator that picks address randomly
+ ///
+ /// @todo: This is a skeleton class for now and is missing implementation.
+ class RandomAllocator : public Allocator {
+ public:
+
+ /// @brief default constructor (does nothing)
+ RandomAllocator();
+
+ /// @brief returns an random address from pool of specified subnet
+ ///
+ /// @todo: Implement this method
+ ///
+ /// @param subnet an address will be picked from pool of that subnet
+ /// @param duid Client's DUID (ignored)
+ /// @param hint the last address that was picked (ignored)
+ /// @return a random address from the pool
+ virtual isc::asiolink::IOAddress
+ pickAddress(const Subnet6Ptr& subnet, const DuidPtr& duid,
+ const isc::asiolink::IOAddress& hint);
+ };
+
+ public:
+
+ /// @brief specifies allocation type
+ typedef enum {
+ ALLOC_ITERATIVE, // iterative - one address after another
+ ALLOC_HASHED, // hashed - client's DUID/client-id is hashed
+ ALLOC_RANDOM // random - an address is randomly selected
+ } AllocType;
+
+
+ /// @brief Default constructor.
+ ///
+ /// Instantiates necessary services, required to run DHCPv6 server.
+ /// In particular, creates IfaceMgr that will be responsible for
+ /// network interaction. Will instantiate lease manager, and load
+ /// old or create new DUID.
+ ///
+ /// @param engine_type selects allocation algorithm
+ /// @param attempts number of attempts for each lease allocation before
+ /// we give up (0 means unlimited)
+ AllocEngine(AllocType engine_type, unsigned int attempts);
+
+ /// @brief Allocates an IPv6 lease
+ ///
+ /// This method uses currently selected allocator to pick an address from
+ /// specified subnet, creates a lease for that address and then inserts
+ /// it into LeaseMgr (if this allocation is not fake).
+ ///
+ /// @param subnet subnet the allocation should come from
+ /// @param duid Client'd DUID
+ /// @param iaid iaid field from the IA_NA container that client sent
+ /// @param hint a hint that the client provided
+ /// @param fake_allocation is this real i.e. REQUEST (false) or just picking
+ /// an address for SOLICIT that is not really allocated (true)
+ /// @return Allocated IPv6 lease (or NULL if allocation failed)
+ Lease6Ptr
+ allocateAddress6(const Subnet6Ptr& subnet,
+ const DuidPtr& duid,
+ uint32_t iaid,
+ const isc::asiolink::IOAddress& hint,
+ bool fake_allocation);
+
+ /// @brief Destructor. Used during DHCPv6 service shutdown.
+ virtual ~AllocEngine();
+private:
+
+ /// @brief creates a lease and inserts it in LeaseMgr if necessary
+ ///
+ /// Creates a lease based on specified parameters and tries to insert it
+ /// into the database. That may fail in some cases, i.e. when there is another
+ /// allocation process and we lost a race to a specific lease.
+ ///
+ /// @param subnet subnet the lease is allocated from
+ /// @param duid client's DUID
+ /// @param iaid IAID from the IA_NA container the client sent to us
+ /// @param addr an address that was selected and is confirmed to be available
+ /// @param fake_allocation is this real i.e. REQUEST (false) or just picking
+ /// an address for SOLICIT that is not really allocated (true)
+ /// @return allocated lease (or NULL in the unlikely case of the lease just
+ /// becomed unavailable)
+ Lease6Ptr createLease(const Subnet6Ptr& subnet, const DuidPtr& duid,
+ uint32_t iaid, const isc::asiolink::IOAddress& addr,
+ bool fake_allocation = false);
+
+ /// @brief a pointer to currently used allocator
+ boost::shared_ptr<Allocator> allocator_;
+
+ /// @brief number of attempts before we give up lease allocation (0=unlimited)
+ unsigned int attempts_;
+};
+
+}; // namespace isc::dhcp
+}; // namespace isc
+
+#endif // ALLOC_ENGINE_H
diff --git a/src/lib/dhcp/duid.h b/src/lib/dhcp/duid.h
index 53257db..5f8ad58 100644
--- a/src/lib/dhcp/duid.h
+++ b/src/lib/dhcp/duid.h
@@ -12,11 +12,13 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#ifndef DUID_H
+#define DUID_H
+
+#include <asiolink/io_address.h>
+#include <vector>
#include <stdint.h>
#include <unistd.h>
-#include <vector>
-#include <asiolink/io_address.h>
-
namespace isc {
namespace dhcp {
@@ -70,6 +72,8 @@ class DUID {
std::vector<uint8_t> duid_;
};
+typedef boost::shared_ptr<DUID> DuidPtr;
+
/// @brief Holds Client identifier or client IPv4 address
///
/// This class is intended to be a generic IPv4 client identifier. It can hold
@@ -96,3 +100,5 @@ class ClientId : DUID {
}; // end of isc::dhcp namespace
}; // end of isc namespace
+
+#endif /* DUID_H */
diff --git a/src/lib/dhcp/lease_mgr.cc b/src/lib/dhcp/lease_mgr.cc
index 8291df3..59582fb 100644
--- a/src/lib/dhcp/lease_mgr.cc
+++ b/src/lib/dhcp/lease_mgr.cc
@@ -12,6 +12,10 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include "lease_mgr.h"
+#include <exceptions/exceptions.h>
+#include <boost/foreach.hpp>
+#include <boost/algorithm/string.hpp>
#include <sstream>
#include <iostream>
#include <map>
@@ -20,16 +24,50 @@
#include <sstream>
#include <algorithm>
#include <iterator>
-#include <exceptions/exceptions.h>
-#include <boost/foreach.hpp>
-#include <boost/algorithm/string.hpp>
-#include "lease_mgr.h"
+#include <time.h>
using namespace std;
using namespace isc::dhcp;
+LeaseMgr* LeaseMgr::instance_ = NULL;
+
+Lease6::Lease6(LeaseType type, const isc::asiolink::IOAddress& addr, DuidPtr duid,
+ uint32_t iaid, uint32_t preferred, uint32_t valid, uint32_t t1,
+ uint32_t t2, SubnetID subnet_id, uint8_t prefixlen)
+ :type_(type), addr_(addr), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
+ preferred_lft_(preferred), valid_lft_(valid), t1_(t1), t2_(t2),
+ subnet_id_(subnet_id), fixed_(false), fqdn_fwd_(false),
+ fqdn_rev_(false) {
+ if (!duid) {
+ isc_throw(InvalidOperation, "DUID must be specified for a lease");
+ }
+
+ cltt_ = time(NULL);
+}
+
+LeaseMgr& LeaseMgr::instance() {
+ if (!instance_) {
+ isc_throw(InvalidOperation, "LeaseManager not instantiated yet");
+ }
+ return (*instance_);
+}
+
+void LeaseMgr::destroy_instance() {
+ if (!instance_) {
+ isc_throw(InvalidOperation, "LeaseManager not instantiated yet");
+ }
+ delete instance_;
+ instance_ = NULL;
+}
+
LeaseMgr::LeaseMgr(const std::string& dbconfig) {
+ if (instance_) {
+ isc_throw(InvalidOperation, "LeaseManager already instantiated");
+ }
+
+ // remember the pointer to the singleton instance
+ instance_ = this;
if (dbconfig.length() == 0) {
return;
@@ -65,4 +103,5 @@ std::string LeaseMgr::getParameter(const std::string& name) const {
}
LeaseMgr::~LeaseMgr() {
+ instance_ = NULL;
}
diff --git a/src/lib/dhcp/lease_mgr.h b/src/lib/dhcp/lease_mgr.h
index 4b7a1af..e859dea 100644
--- a/src/lib/dhcp/lease_mgr.h
+++ b/src/lib/dhcp/lease_mgr.h
@@ -12,14 +12,19 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#ifndef LEASE_MGR_H
+#define LEASE_MGR_H
+
#include <string>
#include <fstream>
#include <vector>
#include <map>
#include <asiolink/io_address.h>
+#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <dhcp/option.h>
#include <dhcp/duid.h>
+#include <dhcp/subnet.h>
/// @file dhcp/lease_mgr.h
/// @brief An abstract API for lease database
@@ -55,10 +60,6 @@
namespace isc {
namespace dhcp {
-/// @brief specifies unique subnet identifier
-/// @todo: Move this to subnet.h once ticket #2237 is merged
-typedef uint32_t SubnetID;
-
/// @brief Structure that holds a lease for IPv4 address
///
/// For performance reasons it is a simple structure, not a class. If we chose
@@ -161,6 +162,10 @@ struct Lease6 {
LEASE_IA_PD /// the lease contains IPv6 prefix (for prefix delegation)
} LeaseType;
+ Lease6(LeaseType type, const isc::asiolink::IOAddress& addr, DuidPtr duid,
+ uint32_t iaid, uint32_t preferred, uint32_t valid, uint32_t t1,
+ uint32_t t2, SubnetID subnet_id, uint8_t prefixlen_ = 0);
+
/// @brief specifies lease type (normal addr, temporary addr, prefix)
LeaseType type_;
@@ -208,6 +213,8 @@ struct Lease6 {
/// entity, we are keeping it in the lease. In case of multiple addresses/prefixes
/// for the same IA, each must have consistent T1 and T2 values. Specified in
/// seconds since cltt.
+ /// This value will also be useful for failover to calculate the next expected
+ /// client transmission time.
uint32_t t1_;
/// @brief T2 timer
@@ -268,33 +275,42 @@ typedef std::vector< boost::shared_ptr<Lease6Ptr> > Lease6Collection;
/// interface to all backends. As this is an abstract class, it should not
/// be used directly, but rather specialized derived class should be used
/// instead.
-class LeaseMgr {
+///
+/// This class is a meta-singleton. At any given time, there is only one
+/// instance of any classes derived from that class. That is achieved with
+/// defining only a single protected constructor, so every derived class has
+/// to use it. Furthermore, this sole constructor registers the first instance
+/// (and throws InvalidOperation if there is an attempt to create a second one).
+class LeaseMgr : public boost::noncopyable {
public:
-
/// Client Hardware address
typedef std::vector<uint8_t> HWAddr;
- /// @brief The sole lease manager constructor
+ /// @brief returns a single instance of LeaseMgr
///
- /// dbconfig is a generic way of passing parameters. Parameters
- /// are passed in the "name=value" format, separated by spaces.
- /// Values may be enclosed in double quotes, if needed.
- ///
- /// @param dbconfig database configuration
- LeaseMgr(const std::string& dbconfig);
+ /// LeaseMgr is a singleton and this method is the only way of
+ /// accessing it. LeaseMgr must be created first. See
+ /// isc::dhcp::LeaseMgrFactory class (work of ticket #2342.
+ /// Otherwise instance() will throw InvalidOperation exception.
+ /// @throw InvalidOperation if LeaseMgr not instantiated
+ static LeaseMgr& instance();
- /// @brief Destructor (closes file)
- virtual ~LeaseMgr();
+ /// @brief destroys the only instance of LeaseMgr
+ ///
+ /// This method is used mostly in tests, where LeaseMgr is destroyed
+ /// at the end of each test, just to be created at the beginning of
+ /// the next one.
+ static void destroy_instance();
/// @brief Adds an IPv4 lease.
///
/// @param lease lease to be added
- virtual bool addLease(Lease4Ptr lease) = 0;
+ virtual bool addLease(const Lease4Ptr& lease) = 0;
/// @brief Adds an IPv6 lease.
///
/// @param lease lease to be added
- virtual bool addLease(Lease6Ptr lease) = 0;
+ virtual bool addLease(const Lease6Ptr& lease) = 0;
/// @brief Returns existing IPv4 lease for specified IPv4 address and subnet_id
///
@@ -382,7 +398,7 @@ public:
/// @param addr address of the searched lease
///
/// @return smart pointer to the lease (or NULL if a lease is not found)
- virtual Lease6Ptr getLease6(isc::asiolink::IOAddress addr) const = 0;
+ virtual Lease6Ptr getLease6(const isc::asiolink::IOAddress& addr) const = 0;
/// @brief Returns existing IPv6 leases for a given DUID+IA combination
///
@@ -413,14 +429,14 @@ public:
/// @param lease4 The lease to be updated.
///
/// If no such lease is present, an exception will be thrown.
- virtual void updateLease4(Lease4Ptr lease4) = 0;
+ virtual void updateLease4(const Lease4Ptr& lease4) = 0;
/// @brief Updates IPv4 lease.
///
/// @param lease4 The lease to be updated.
///
/// If no such lease is present, an exception will be thrown.
- virtual void updateLease6(Lease6Ptr lease6) = 0;
+ virtual void updateLease6(const Lease6Ptr& lease6) = 0;
/// @brief Deletes a lease.
///
@@ -434,7 +450,7 @@ public:
/// @param addr IPv4 address of the lease to be deleted.
///
/// @return true if deletion was successful, false if no such lease exists
- virtual bool deleteLease6(isc::asiolink::IOAddress addr) = 0;
+ virtual bool deleteLease6(const isc::asiolink::IOAddress& addr) = 0;
/// @brief Returns backend name.
///
@@ -464,6 +480,22 @@ public:
/// is currently postponed.
protected:
+ /// @brief The sole lease manager constructor
+ ///
+ /// dbconfig is a generic way of passing parameters. Parameters are passed
+ /// in the "name=value" format, separated by spaces. Values may be enclosed
+ /// in double quotes, if needed. This ctor guarantees that there will be
+ /// only one instance of any derived classes. If there is a second instance
+ /// being created with the first one still around, it will throw
+ /// InvalidOperation.
+ ///
+ /// @param dbconfig database configuration
+ /// @throw InvalidOperation when trying to create second LeaseMgr
+ LeaseMgr(const std::string& dbconfig);
+
+ /// @brief Destructor
+ virtual ~LeaseMgr();
+
/// @brief returns value of the parameter
std::string getParameter(const std::string& name) const;
@@ -473,8 +505,12 @@ protected:
/// password and other parameters required for DB access. It is not
/// intended to keep any DHCP-related parameters.
std::map<std::string, std::string> parameters_;
+
+ static LeaseMgr* instance_;
};
}; // end of isc::dhcp namespace
}; // end of isc namespace
+
+#endif // LEASE_MGR_H
diff --git a/src/lib/dhcp/libdhcp++.dox b/src/lib/dhcp/libdhcp++.dox
new file mode 100644
index 0000000..013b6f2
--- /dev/null
+++ b/src/lib/dhcp/libdhcp++.dox
@@ -0,0 +1,79 @@
+/**
+ at page libdhcp libdhcp++
+
+ at section libdhcpIntro Libdhcp++ Library Introduction
+
+libdhcp++ is an all-purpose DHCP-manipulation library, written in
+C++. It offers packet parsing and assembly, DHCPv4 and DHCPv6
+options parsing and ssembly, interface detection (currently on
+Linux systems only) and socket operations. It is a generic purpose library that
+can be used by server, client, relay, performance tools and other DHCP-related
+tools. For server specific library, see \ref libdhcpsrv. Please do not
+add any server-specific code to libdhcp++ and use \ref libdhcpsrv instead.
+
+The following classes for packet manipulation are implemented:
+
+- isc::dhcp::Pkt4 - represents DHCPv4 packet.
+- isc::dhcp::Pkt6 - represents DHCPv6 packet.
+
+There are two pointer types defined: Pkt4Ptr and Pkt6Ptr. They are
+smart pointer and are using boost::shared_ptr. There are not const
+versions defined, as we assume that hooks can modify any aspect of
+the packet at almost any stage of processing.
+
+Both packets use collection of Option objects to represent DHCPv4
+and DHCPv6 options. The base class -- Option -- can be used to
+represent generic option that contains collection of
+bytes. Depending on if the option is instantiated as v4 or v6
+option, it will adjust its header (DHCPv4 options use 1 octet for
+type and 1 octet for length, while DHCPv6 options use 2 bytes for
+each).
+
+There are many specialized classes that are intended to handle options with
+specific content:
+- isc::dhcp::Option4AddrLst -- DHCPv4 option, contains one or more IPv4 addresses;
+- isc::dhcp::Option6AddrLst -- DHCPv6 option, contains one or more IPv6 addresses;
+- isc::dhcp::Option6IAAddr -- DHCPv6 option, represents IAADDR_OPTION (an option that
+ contains IPv6 address with extra parameters);
+- isc::dhcp::Option6IA -- DHCPv6 option used to store IA_NA and its suboptions.
+
+All options can store sub-options (i.e. options that are stored within option
+rather than in a message directly). This functionality is commonly used in
+DHCPv6, but is rarely used in DHCPv4. isc::dhcp::Option::addOption(),
+isc::dhcp::Option::delOption(), isc::dhcp::Option::getOption() can be used
+for that purpose.
+
+ at section libdhcpIfaceMgr Interface Manager
+
+Interface Manager (or IfaceMgr) is an abstraction layer about low-level
+network operations. In particlar, it provides information about existing
+network interfaces See isc::dhcp::IfaceMgr::Iface class and
+isc::dhcp::IfaceMgr::detectIfaces() and isc::dhcp::IfaceMgr::getIface().
+
+Currently there is interface detection is implemented in Linux only. There
+are plans to implement such support for other OSes, but they remain low
+priority for now.
+
+Generic parts of the code are isc::dhcp::IfaceMgr class in
+src/lib/dhcp/iface_mgr.cc file. OS-specific code is located in separate
+files, e.g. iface_mgr_linux.cc. Such separation should be maintained when
+additional code will be developed.
+
+For systems that interface detection is not supported on, there is a stub
+mechanism implemented. It assumes that interface name is read from a text
+file. This is a temporary solution and will be removed as soon as proper
+interface detection is implemented. It is not going to be developed further.
+To use this feature, store interfaces.txt file. It uses a simple syntax.
+Each line represents an interface name, followed by IPv4 or IPv6 address
+that follows it. This is usually link-local IPv6 address that the server
+should bind to. In theory this mechanism also supports IPv4, but it was
+never tested. The code currently supports only a single interface defined
+that way.
+
+Another useful methods are dedicated to transmission
+(isc::dhcp::IfaceMgr::send(), 2 overloads) and reception
+(isc::dhcp::IfaceMgr::receive4() and isc::dhcp::IfaceMgr::receive6()).
+Note that receive4() and receive6() methods may return NULL, e.g.
+when timeout is reached or if dhcp daemon receives a signal.
+
+*/
\ No newline at end of file
diff --git a/src/lib/dhcp/libdhcsrv.dox b/src/lib/dhcp/libdhcsrv.dox
new file mode 100644
index 0000000..bb4a8ec
--- /dev/null
+++ b/src/lib/dhcp/libdhcsrv.dox
@@ -0,0 +1,86 @@
+/**
+ @page libdhcpsrv libdhcpsrv - Server DHCP library
+
+This library contains code useful for DHCPv4 and DHCPv6 server operations, like
+Lease Manager that stores leases information, configuration manager that stores
+configuration etc. The code here is server specific. For generic (useful in
+server, client, relay and other tools like perfdhcp) code, please see
+\ref libdhcp.
+
+This library contains several crucial elements of the DHCP server operation:
+
+- isc::dhcp::LeaseMgr - Lease Manager is a name for database backend that stores
+ leases.
+- isc::dhcp::CfgMgr - Configuration Manager that holds DHCP specific
+ configuration information (subnets, pools, options, timer values etc.) in
+ easy to use format.
+- AllocEngine - allocation engine that handles new requestes and allocates new
+ leases.
+
+ at section leasemgr Lease Manager
+
+LeaseMgr provides a common, unified abstract API for all database backends. All
+backends are derived from the base class isc::dhcp::LeaseMgr. Currently the
+only available backend is MySQL (see \ref isc::dhcp::MySqlLeaseMgr).
+
+ at section cfgmgr Configuration Manager
+
+Configuration Manager (\ref isc::dhcp::CfgMgr) stores configuration information
+necessary for DHCPv4 and DHCPv6 server operation. In particular, it stores
+subnets (\ref isc::dhcp::Subnet4 and \ref isc::dhcp::Subnet6) together with
+their pools (\ref isc::dhcp::Pool4 and \ref isc::dhcp::Pool6), options and
+other information specified by the used in BIND10 configuration.
+
+ at section allocengine Allocation Engine
+
+Allocation Engine (\ref isc::dhcp::AllocEngine) is what its name say - an engine
+that handles allocation of new leases. It takes parameters that the client
+provided (client-id, DUID, subnet, a hint if the user provided one, etc.) and
+then attempts to allocate a lease.
+
+There is no single best soluction to the address assignment problem. Server
+is expected to pick an address from its available pools is currently not used.
+There are many possible algorithms that can do that, each with its own advantages
+and drawbacks. This allocation engine must provide robust operation is radically
+different scenarios, so there address selection problem was abstracted into
+separate module, called allocator. Its sole purpose is to pick an address from
+a pool. Allocation engine will then check if the picked address is free and if
+it is not, then will ask allocator to pick again.
+
+At lease 3 allocators will be implemented:
+
+- Iterative - it iterates over all addresses in available pools, one
+by one. The advantages of this approach are speed (typically it only needs to
+increase last address), the guarantee to cover all addresses and predictability.
+This allocator behaves very good in case of nearing depletion. Even when pools
+are almost completely allocated, it still will be able to allocate outstanding
+leases efficiently. Predictability can also be considered a serious flaw in
+some environments, as prediction of the next address is trivial and can be
+leveraged by an attacker. Another drawback of this allocator is that it does
+not attempt to give the same address to returning clients (clients that released
+or expired their leases and are requesting a new lease will likely to get a
+different lease). This allocator is implemented in \ref isc::dhcp::AllocEngine::IterativeAllocator.
+
+- Hashed - ISC-DHCP uses hash of the client-id or DUID to determine, which
+address is tried first. If that address is not available, the result is hashed
+again. That procedure is repeated until available address is found or there
+are no more addresses left. The benefit of that approach is that it provides
+a relative lease stability, so returning old clients are likely to get the same
+address again. The drawbacks are increased computation cost, as each iteration
+requires use of a hashing function. That is especially difficult when the
+pools are almost depleted. It also may be difficult to guarantee that the
+repeated hashing will iterate over all available addresses in all pools. Flawed
+hash algorithm can go into cycles that iterate over only part of the addresses.
+It is difficult to detect such issues as only some initial seed (client-id
+or DUID) values may trigger short cycles. This allocator is currently not
+implemented.
+
+- Random - Another possible approach to address selection is randomization. This
+allocator can pick an address randomly from the configured pool. The benefit
+of this approach is that it is easy to implement and makes attacks based on
+address prediction more difficult. The drawback of this approach is that
+returning clients are almost guaranteed to get a different address. Another
+drawback is that with almost depleted pools it is increasingly difficult to
+"guess" an address that is free. This allocator is currently not implemented.
+
+*/
\ No newline at end of file
diff --git a/src/lib/dhcp/pool.h b/src/lib/dhcp/pool.h
index 46f6578..dd68fdd 100644
--- a/src/lib/dhcp/pool.h
+++ b/src/lib/dhcp/pool.h
@@ -141,6 +141,7 @@ public:
/// @brief the constructor for Pool6 "min-max" style definition
///
+ /// @param type type of the pool (IA, TA or PD)
/// @param first the first address in a pool
/// @param last the last address in a pool
Pool6(Pool6Type type, const isc::asiolink::IOAddress& first,
@@ -148,6 +149,7 @@ public:
/// @brief the constructor for Pool6 "prefix/len" style definition
///
+ /// @param type type of the pool (IA, TA or PD)
/// @param prefix specifies prefix of the pool
/// @param prefix_len specifies length of the prefix of the pool
Pool6(Pool6Type type, const isc::asiolink::IOAddress& prefix,
diff --git a/src/lib/dhcp/subnet.cc b/src/lib/dhcp/subnet.cc
index cb82a9f..f6ce1b1 100644
--- a/src/lib/dhcp/subnet.cc
+++ b/src/lib/dhcp/subnet.cc
@@ -15,7 +15,6 @@
#include <dhcp/addr_utilities.h>
#include <asiolink/io_address.h>
#include <dhcp/subnet.h>
-#include <dhcp/pool.h>
using namespace isc::asiolink;
@@ -27,7 +26,8 @@ Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
const Triplet<uint32_t>& t2,
const Triplet<uint32_t>& valid_lifetime)
:id_(getNextID()), prefix_(prefix), prefix_len_(len), t1_(t1),
- t2_(t2), valid_(valid_lifetime) {
+ t2_(t2), valid_(valid_lifetime),
+ last_allocated_(lastAddrInPrefix(prefix, len)) {
if ( (prefix.getFamily() == AF_INET6 && len > 128) ||
(prefix.getFamily() == AF_INET && len > 32) ) {
isc_throw(BadValue, "Invalid prefix length specified for subnet: " << len);
@@ -105,6 +105,22 @@ Subnet4::validateOption(const OptionPtr& option) const {
}
}
+bool Subnet4::inPool(const isc::asiolink::IOAddress& addr) const {
+
+ // Let's start with checking if it even belongs to that subnet.
+ if (!inRange(addr)) {
+ return (false);
+ }
+
+ for (Pool4Collection::const_iterator pool = pools_.begin(); pool != pools_.end(); ++pool) {
+ if ((*pool)->inRange(addr)) {
+ return (true);
+ }
+ }
+ // there's no pool that address belongs to
+ return (false);
+}
+
Subnet6::Subnet6(const isc::asiolink::IOAddress& prefix, uint8_t length,
const Triplet<uint32_t>& t1,
const Triplet<uint32_t>& t2,
@@ -159,5 +175,22 @@ Subnet6::validateOption(const OptionPtr& option) const {
isc_throw(isc::BadValue, "expected V6 option to be added to the subnet");
}
}
+
+bool Subnet6::inPool(const isc::asiolink::IOAddress& addr) const {
+
+ // Let's start with checking if it even belongs to that subnet.
+ if (!inRange(addr)) {
+ return (false);
+ }
+
+ for (Pool6Collection::const_iterator pool = pools_.begin(); pool != pools_.end(); ++pool) {
+ if ((*pool)->inRange(addr)) {
+ return (true);
+ }
+ }
+ // there's no pool that address belongs to
+ return (false);
+}
+
} // end of isc::dhcp namespace
} // end of isc namespace
diff --git a/src/lib/dhcp/subnet.h b/src/lib/dhcp/subnet.h
index aa680ce..a28c7cd 100644
--- a/src/lib/dhcp/subnet.h
+++ b/src/lib/dhcp/subnet.h
@@ -40,6 +40,13 @@ namespace dhcp {
/// of DHCP option instances configured for the subnet. These options are
/// included in DHCP messages being sent to clients which are connected
/// to the particular subnet.
+///
+/// @todo: Implement support for options here
+
+
+/// @brief Unique indentifier for a subnet (both v4 and v6)
+typedef uint32_t SubnetID;
+
class Subnet {
public:
@@ -186,6 +193,11 @@ public:
/// Type of the index #1 - option type.
typedef OptionContainer::nth_index<1>::type OptionContainerTypeIndex;
+ /// Pair of iterators to represent the range of options having the
+ /// same option type value. The first element in this pair represents
+ /// the begining of the range, the second element represents the end.
+ typedef std::pair<OptionContainerTypeIndex::const_iterator,
+ OptionContainerTypeIndex::const_iterator> OptionContainerTypeRange;
/// Type of the index #2 - option persistency flag.
typedef OptionContainer::nth_index<2>::type OptionContainerPersistIndex;
@@ -204,6 +216,20 @@ public:
/// @brief Delete all options configured for the subnet.
void delOptions();
+ /// @brief checks if the specified address is in pools
+ ///
+ /// Note the difference between inSubnet() and inPool(). For a given
+ /// subnet (e.g. 2001::/64) there may be one or more pools defined
+ /// that may or may not cover entire subnet, e.g. pool 2001::1-2001::10).
+ /// inPool() returning true implies inSubnet(), but the reverse implication
+ /// is not always true. For the given example, 2001::1234:abcd would return
+ /// true for inSubnet(), but false for inPool() check.
+ ///
+ /// @param addr this address will be checked if it belongs to any pools in
+ /// that subnet
+ /// @return true if the address is in any of the pools
+ virtual bool inPool(const isc::asiolink::IOAddress& addr) const = 0;
+
/// @brief return valid-lifetime for addresses in that prefix
Triplet<uint32_t> getValid() const {
return (valid_);
@@ -224,10 +250,40 @@ public:
/// @return reference to collection of options configured for a subnet.
/// The returned reference is valid as long as the Subnet object which
/// returned it still exists.
- const OptionContainer& getOptions() {
+ const OptionContainer& getOptions() const {
return (options_);
}
+ /// @brief returns the last address that was tried from this pool
+ ///
+ /// This method returns the last address that was attempted to be allocated
+ /// from this subnet. This is used as helper information for the next
+ /// iteration of the allocation algorithm.
+ ///
+ /// @todo: Define map<SubnetID, IOAddress> somewhere in the
+ /// AllocEngine::IterativeAllocator and keep the data there
+ ///
+ /// @return address that was last tried from this pool
+ isc::asiolink::IOAddress getLastAllocated() const {
+ return (last_allocated_);
+ }
+
+ /// @brief sets the last address that was tried from this pool
+ ///
+ /// This method sets the last address that was attempted to be allocated
+ /// from this subnet. This is used as helper information for the next
+ /// iteration of the allocation algorithm.
+ ///
+ /// @todo: Define map<SubnetID, IOAddress> somewhere in the
+ /// AllocEngine::IterativeAllocator and keep the data there
+ void setLastAllocated(const isc::asiolink::IOAddress& addr) {
+ last_allocated_ = addr;
+ }
+
+ /// @brief returns unique ID for that subnet
+ /// @return unique ID for that subnet
+ SubnetID getID() const { return (id_); }
+
protected:
/// @brief protected constructor
//
@@ -247,8 +303,8 @@ protected:
/// @brief returns the next unique Subnet-ID
///
/// @return the next unique Subnet-ID
- static uint32_t getNextID() {
- static uint32_t id = 0;
+ static SubnetID getNextID() {
+ static SubnetID id = 0;
return (id++);
}
@@ -261,7 +317,7 @@ protected:
///
/// Subnet-id is a unique value that can be used to find or identify
/// a Subnet4 or Subnet6.
- uint32_t id_;
+ SubnetID id_;
/// @brief a prefix of the subnet
isc::asiolink::IOAddress prefix_;
@@ -280,6 +336,17 @@ protected:
/// @brief a collection of DHCP options configured for a subnet.
OptionContainer options_;
+
+ /// @brief last allocated address
+ ///
+ /// This is the last allocated address that was previously allocated from
+ /// this particular subnet. Some allocation algorithms (e.g. iterative) use
+ /// that value, others do not. It should be noted that although the value
+ /// is usually correct, there are cases when it is invalid, e.g. after
+ /// removing a pool, restarting or changing allocation algorithms. For
+ /// that purpose it should be only considered a help that should not be
+ /// fully trusted.
+ isc::asiolink::IOAddress last_allocated_;
};
/// @brief A configuration holder for IPv4 subnet.
@@ -313,14 +380,21 @@ public:
/// @brief returns all pools
///
- /// The reference is only valid as long as the object that
- /// returned it.
+ /// The reference is only valid as long as the object that returned it.
///
/// @return a collection of all pools
const Pool4Collection& getPools() const {
return pools_;
}
+ /// @brief checks if the specified address is in pools
+ ///
+ /// See the description in \ref Subnet::inPool().
+ ///
+ /// @param addr this address will be checked if it belongs to any pools in that subnet
+ /// @return true if the address is in any of the pools
+ bool inPool(const isc::asiolink::IOAddress& addr) const;
+
protected:
/// @brief Check if option is valid and can be added to a subnet.
@@ -389,6 +463,14 @@ public:
return pools_;
}
+ /// @brief checks if the specified address is in pools
+ ///
+ /// See the description in \ref Subnet::inPool().
+ ///
+ /// @param addr this address will be checked if it belongs to any pools in that subnet
+ /// @return true if the address is in any of the pools
+ bool inPool(const isc::asiolink::IOAddress& addr) const;
+
protected:
/// @brief Check if option is valid and can be added to a subnet.
diff --git a/src/lib/dhcp/tests/Makefile.am b/src/lib/dhcp/tests/Makefile.am
index a816472..fcbdec8 100644
--- a/src/lib/dhcp/tests/Makefile.am
+++ b/src/lib/dhcp/tests/Makefile.am
@@ -28,7 +28,6 @@ TESTS += libdhcp++_unittests libdhcpsrv_unittests
libdhcp___unittests_SOURCES = run_unittests.cc
libdhcp___unittests_SOURCES += libdhcp++_unittest.cc
libdhcp___unittests_SOURCES += iface_mgr_unittest.cc
-libdhcp___unittests_SOURCES += lease_mgr_unittest.cc
libdhcp___unittests_SOURCES += option6_iaaddr_unittest.cc
libdhcp___unittests_SOURCES += option6_ia_unittest.cc
libdhcp___unittests_SOURCES += option6_addrlst_unittest.cc
@@ -49,6 +48,9 @@ libdhcpsrv_unittests_SOURCES = run_unittests.cc
libdhcpsrv_unittests_SOURCES += cfgmgr_unittest.cc triplet_unittest.cc
libdhcpsrv_unittests_SOURCES += pool_unittest.cc subnet_unittest.cc
libdhcpsrv_unittests_SOURCES += addr_utilities_unittest.cc
+libdhcpsrv_unittests_SOURCES += memfile_lease_mgr.cc memfile_lease_mgr.h
+libdhcpsrv_unittests_SOURCES += lease_mgr_unittest.cc
+libdhcpsrv_unittests_SOURCES += alloc_engine_unittest.cc
libdhcpsrv_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
libdhcpsrv_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
@@ -56,6 +58,7 @@ libdhcpsrv_unittests_CXXFLAGS = $(AM_CXXFLAGS)
libdhcpsrv_unittests_LDADD = $(GTEST_LDADD)
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
+libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcpsrv.la
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
diff --git a/src/lib/dhcp/tests/alloc_engine_unittest.cc b/src/lib/dhcp/tests/alloc_engine_unittest.cc
new file mode 100644
index 0000000..945c8e9
--- /dev/null
+++ b/src/lib/dhcp/tests/alloc_engine_unittest.cc
@@ -0,0 +1,343 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <asiolink/io_address.h>
+#include <dhcp/lease_mgr.h>
+#include <dhcp/duid.h>
+#include <dhcp/alloc_engine.h>
+#include <dhcp/cfgmgr.h>
+#include "memfile_lease_mgr.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <iostream>
+#include <sstream>
+#include <map>
+#include <gtest/gtest.h>
+
+using namespace std;
+using namespace isc;
+using namespace isc::asiolink;
+using namespace isc::dhcp;
+using namespace isc::dhcp::test; // Memfile_LeaseMgr
+
+namespace {
+
+class NakedAllocEngine : public AllocEngine {
+public:
+ NakedAllocEngine(AllocEngine::AllocType engine_type, unsigned int attempts)
+ :AllocEngine(engine_type, attempts) {
+ }
+ using AllocEngine::Allocator;
+ using AllocEngine::IterativeAllocator;
+};
+
+// empty class for now, but may be extended once Addr6 becomes bigger
+class AllocEngineTest : public ::testing::Test {
+public:
+ AllocEngineTest() {
+ duid_ = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0x42)));
+ iaid_ = 42;
+
+ // instantiate cfg_mgr
+ CfgMgr& cfg_mgr = CfgMgr::instance();
+
+ subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
+ pool_ = Pool6Ptr(new Pool6(Pool6::TYPE_IA, IOAddress("2001:db8:1::10"),
+ IOAddress("2001:db8:1::20")));
+ subnet_->addPool6(pool_);
+ cfg_mgr.addSubnet6(subnet_);
+
+ leasemgr_ = new Memfile_LeaseMgr("");
+ }
+
+ void checkLease6(const Lease6Ptr& lease) {
+ // that is belongs to the right subnet
+ EXPECT_EQ(lease->subnet_id_, subnet_->getID());
+ EXPECT_TRUE(subnet_->inRange(lease->addr_));
+ EXPECT_TRUE(subnet_->inPool(lease->addr_));
+
+ // that it have proper parameters
+ EXPECT_EQ(iaid_, lease->iaid_);
+ EXPECT_EQ(subnet_->getValid(), lease->valid_lft_);
+ EXPECT_EQ(subnet_->getPreferred(), lease->preferred_lft_);
+ EXPECT_EQ(subnet_->getT1(), lease->t1_);
+ EXPECT_EQ(subnet_->getT2(), lease->t2_);
+ EXPECT_EQ(0, lease->prefixlen_); // this is IA_NA, not IA_PD
+ EXPECT_TRUE(false == lease->fqdn_fwd_);
+ EXPECT_TRUE(false == lease->fqdn_rev_);
+ EXPECT_TRUE(*lease->duid_ == *duid_);
+ // @todo: check cltt
+ }
+
+ ~AllocEngineTest() {
+ LeaseMgr::instance().destroy_instance();
+ leasemgr_ = NULL;
+ }
+
+ DuidPtr duid_;
+ uint32_t iaid_;
+ Subnet6Ptr subnet_;
+ Pool6Ptr pool_;
+ LeaseMgr* leasemgr_;
+};
+
+// This test checks if the Allocation Engine can be instantiated and that it
+// parses parameters string properly.
+TEST_F(AllocEngineTest, constructor) {
+ AllocEngine* x = NULL;
+
+ // Hashed and random allocators are not supported yet
+ ASSERT_THROW(x = new AllocEngine(AllocEngine::ALLOC_HASHED, 5), NotImplemented);
+ ASSERT_THROW(x = new AllocEngine(AllocEngine::ALLOC_RANDOM, 5), NotImplemented);
+
+ ASSERT_NO_THROW(x = new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100));
+
+ delete x;
+}
+
+/// @todo: This method is taken from mysql_lease_mgr_utilities.cc from ticket
+/// #2342. Get rid of one instance once the code is merged
+void
+detailCompareLease6(const Lease6Ptr& first, const Lease6Ptr& second) {
+ EXPECT_EQ(first->type_, second->type_);
+
+ // Compare address strings - odd things happen when they are different
+ // as the EXPECT_EQ appears to call the operator uint32_t() function,
+ // which causes an exception to be thrown for IPv6 addresses.
+ EXPECT_EQ(first->addr_.toText(), second->addr_.toText());
+ EXPECT_EQ(first->prefixlen_, second->prefixlen_);
+ EXPECT_EQ(first->iaid_, second->iaid_);
+ EXPECT_TRUE(first->hwaddr_ == second->hwaddr_);
+ EXPECT_TRUE(*first->duid_ == *second->duid_);
+ EXPECT_EQ(first->preferred_lft_, second->preferred_lft_);
+ EXPECT_EQ(first->valid_lft_, second->valid_lft_);
+ EXPECT_EQ(first->cltt_, second->cltt_);
+ EXPECT_EQ(first->subnet_id_, second->subnet_id_);
+}
+
+
+// This test checks if the simple allocation can succeed
+TEST_F(AllocEngineTest, simpleAlloc) {
+ boost::scoped_ptr<AllocEngine>(engine);
+ ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
+ ASSERT_TRUE(engine);
+
+ Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
+ false);
+
+ // check that we got a lease
+ ASSERT_TRUE(lease);
+
+ // do all checks on the lease
+ checkLease6(lease);
+
+ // Check that the lease is indeed in LeaseMgr
+ Lease6Ptr from_mgr = LeaseMgr::instance().getLease6(lease->addr_);
+ ASSERT_TRUE(from_mgr);
+
+ // Now check that the lease in LeaseMgr has the same parameters
+ detailCompareLease6(lease, from_mgr);
+}
+
+// This test checks if the fake allocation (for SOLICIT) can succeed
+TEST_F(AllocEngineTest, fakeAlloc) {
+ boost::scoped_ptr<AllocEngine>(engine);
+ ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
+ ASSERT_TRUE(engine);
+
+ Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
+ true);
+
+ // check that we got a lease
+ ASSERT_TRUE(lease);
+
+ // do all checks on the lease
+ checkLease6(lease);
+
+ // Check that the lease is NOT in LeaseMgr
+ Lease6Ptr from_mgr = LeaseMgr::instance().getLease6(lease->addr_);
+ ASSERT_FALSE(from_mgr);
+}
+
+// This test checks if the allocation with a hint that is valid (in range,
+// in pool and free) can succeed
+TEST_F(AllocEngineTest, allocWithValidHint) {
+ boost::scoped_ptr<AllocEngine>(engine);
+ ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
+ ASSERT_TRUE(engine);
+
+ Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
+ IOAddress("2001:db8:1::15"),
+ false);
+
+ // check that we got a lease
+ ASSERT_TRUE(lease);
+
+ // we should get what we asked for
+ EXPECT_EQ(lease->addr_.toText(), "2001:db8:1::15");
+
+ // do all checks on the lease
+ checkLease6(lease);
+
+ // Check that the lease is indeed in LeaseMgr
+ Lease6Ptr from_mgr = LeaseMgr::instance().getLease6(lease->addr_);
+ ASSERT_TRUE(from_mgr);
+
+ // Now check that the lease in LeaseMgr has the same parameters
+ detailCompareLease6(lease, from_mgr);
+}
+
+// This test checks if the allocation with a hint that is in range,
+// in pool, but is currently used) can succeed
+TEST_F(AllocEngineTest, allocWithUsedHint) {
+ boost::scoped_ptr<AllocEngine>(engine);
+ ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
+ ASSERT_TRUE(engine);
+
+ // let's create a lease and put it in the LeaseMgr
+ DuidPtr duid2 = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0xff)));
+ Lease6Ptr used(new Lease6(Lease6::LEASE_IA_NA, IOAddress("2001:db8:1::1f"),
+ duid2, 1, 2, 3, 4, 5, subnet_->getID()));
+ ASSERT_TRUE(LeaseMgr::instance().addLease(used));
+
+ // another client comes in and request an address that is in pool, but
+ // unfortunately it is used already. The same address must not be allocated
+ // twice.
+ Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
+ IOAddress("2001:db8:1::1f"),
+ false);
+ // check that we got a lease
+ ASSERT_TRUE(lease);
+
+ // allocated address must be different
+ EXPECT_TRUE(used->addr_.toText() != lease->addr_.toText());
+
+ // we should NOT get what we asked for, because it is used already
+ EXPECT_TRUE(lease->addr_.toText() != "2001:db8:1::1f");
+
+ // do all checks on the lease
+ checkLease6(lease);
+
+ // Check that the lease is indeed in LeaseMgr
+ Lease6Ptr from_mgr = LeaseMgr::instance().getLease6(lease->addr_);
+ ASSERT_TRUE(from_mgr);
+
+ // Now check that the lease in LeaseMgr has the same parameters
+ detailCompareLease6(lease, from_mgr);
+}
+
+// This test checks if the allocation with a hint that is out the blue
+// can succeed. The invalid hint should be ignored completely.
+TEST_F(AllocEngineTest, allocBogusHint) {
+ boost::scoped_ptr<AllocEngine>(engine);
+ ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
+ ASSERT_TRUE(engine);
+
+ // Client would like to get a 3000::abc lease, which does not belong to any
+ // supported lease. Allocation engine should ignore it and carry on
+ // with the normal allocation
+ Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
+ IOAddress("3000::abc"),
+ false);
+ // check that we got a lease
+ ASSERT_TRUE(lease);
+
+ // we should NOT get what we asked for, because it is used already
+ EXPECT_TRUE(lease->addr_.toText() != "3000::abc");
+
+ // do all checks on the lease
+ checkLease6(lease);
+
+ // Check that the lease is indeed in LeaseMgr
+ Lease6Ptr from_mgr = LeaseMgr::instance().getLease6(lease->addr_);
+ ASSERT_TRUE(from_mgr);
+
+ // Now check that the lease in LeaseMgr has the same parameters
+ detailCompareLease6(lease, from_mgr);
+}
+
+// This test verifies that the allocator picks addresses that belong to the
+// pool
+TEST_F(AllocEngineTest, IterativeAllocator) {
+ NakedAllocEngine::Allocator* alloc = new NakedAllocEngine::IterativeAllocator();
+
+ for (int i = 0; i < 1000; ++i) {
+ IOAddress candidate = alloc->pickAddress(subnet_, duid_, IOAddress("::"));
+
+ EXPECT_TRUE(subnet_->inPool(candidate));
+ }
+
+ delete alloc;
+}
+
+
+// This test verifies that the iterative allocator really walks over all addresses
+// in all pools in specified subnet. It also must not pick the same address twice
+// unless it runs out of pool space and must start over.
+TEST_F(AllocEngineTest, IterativeAllocator_manyPools) {
+ NakedAllocEngine::IterativeAllocator* alloc = new NakedAllocEngine::IterativeAllocator();
+
+ // let's start from 2, as there is 2001:db8:1::10 - 2001:db8:1::20 pool already.
+ for (int i = 2; i < 10; ++i) {
+ stringstream min, max;
+
+ min << "2001:db8:1::" << hex << i*16 + 1;
+ max << "2001:db8:1::" << hex << i*16 + 9;
+
+ Pool6Ptr pool(new Pool6(Pool6::TYPE_IA, IOAddress(min.str()),
+ IOAddress(max.str())));
+ // cout << "Adding pool: " << min.str() << "-" << max.str() << endl;
+ subnet_->addPool6(pool);
+ }
+
+ int total = 17 + 8*9; // first pool (::10 - ::20) has 17 addresses in it,
+ // there are 8 extra pools with 9 addresses in each.
+
+ // Let's keep picked addresses here and check their uniqueness.
+ std::map<IOAddress, int> generated_addrs;
+ int cnt = 0;
+ while (++cnt) {
+ IOAddress candidate = alloc->pickAddress(subnet_, duid_, IOAddress("::"));
+ EXPECT_TRUE(subnet_->inPool(candidate));
+
+ // One way to easily verify that the iterative allocator really works is
+ // to uncomment the following line and observe its output that it
+ // covers all defined subnets.
+ // cout << candidate.toText() << endl;
+
+ if (generated_addrs.find(candidate) == generated_addrs.end()) {
+ // we haven't had this
+ generated_addrs[candidate] = 0;
+ } else {
+ // we have seen this address before. That should mean that we
+ // iterated over all addresses.
+ if (generated_addrs.size() == total) {
+ // we have exactly the number of address in all pools
+ break;
+ }
+ ADD_FAILURE() << "Too many or not enough unique addresses generated.";
+ break;
+ }
+
+ if ( cnt>total ) {
+ ADD_FAILURE() << "Too many unique addresses generated.";
+ break;
+ }
+ }
+
+ delete alloc;
+}
+
+}; // end of anonymous namespace
diff --git a/src/lib/dhcp/tests/cfgmgr_unittest.cc b/src/lib/dhcp/tests/cfgmgr_unittest.cc
index 462ca9e..a1ad865 100644
--- a/src/lib/dhcp/tests/cfgmgr_unittest.cc
+++ b/src/lib/dhcp/tests/cfgmgr_unittest.cc
@@ -66,7 +66,7 @@ TEST(CfgMgrTest, subnet4) {
// This test verifies if the configuration manager is able to hold and return
// valid leases
-TEST(CfgMgrTest, subnet6) {
+TEST(CfgMgrTest, DISABLED_subnet6) {
CfgMgr& cfg_mgr = CfgMgr::instance();
ASSERT_TRUE(&cfg_mgr != 0);
@@ -81,7 +81,7 @@ TEST(CfgMgrTest, subnet6) {
cfg_mgr.addSubnet6(subnet1);
// Now we have only one subnet, any request will be served from it
- EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("2001:db8::1")));
+ EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("2000::1")));
cfg_mgr.addSubnet6(subnet2);
cfg_mgr.addSubnet6(subnet3);
diff --git a/src/lib/dhcp/tests/lease_mgr_unittest.cc b/src/lib/dhcp/tests/lease_mgr_unittest.cc
index 97659a1..e46bd09 100644
--- a/src/lib/dhcp/tests/lease_mgr_unittest.cc
+++ b/src/lib/dhcp/tests/lease_mgr_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
@@ -16,281 +16,155 @@
#include <iostream>
#include <sstream>
#include <gtest/gtest.h>
-
#include <asiolink/io_address.h>
#include <dhcp/lease_mgr.h>
+#include <dhcp/duid.h>
+#include "memfile_lease_mgr.h"
using namespace std;
using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
+using namespace isc::dhcp::test; // Memfile_LeaseMgr
-// This is a concrete implementation of a Lease database.
-// It does not do anything useful now, and is used for abstract LeaseMgr
-// class testing. It may later evolve into more useful backend if the
-// need arises. We can reuse code from memfile benchmark. See code in
-// tests/tools/dhcp-ubench/memfile_bench.{cc|h}
-class Memfile_LeaseMgr : public LeaseMgr {
+namespace {
+// empty class for now, but may be extended once Addr6 becomes bigger
+class LeaseMgrTest : public ::testing::Test {
public:
+ LeaseMgrTest() {
+ }
+};
- /// @brief The sole lease manager constructor
- ///
- /// dbconfig is a generic way of passing parameters. Parameters
- /// are passed in the "name=value" format, separated by spaces.
- /// Values may be enclosed in double quotes, if needed.
- ///
- /// @param dbconfig database configuration
- Memfile_LeaseMgr(const std::string& dbconfig);
-
- /// @brief Destructor (closes file)
- virtual ~Memfile_LeaseMgr();
-
- /// @brief Adds an IPv4 lease.
- ///
- /// @param lease lease to be added
- virtual bool addLease(Lease4Ptr lease);
-
- /// @brief Adds an IPv6 lease.
- ///
- /// @param lease lease to be added
- virtual bool addLease(Lease6Ptr lease);
-
- /// @brief Returns existing IPv4 lease for specified IPv4 address.
- ///
- /// @param addr address of the searched lease
- ///
- /// @return a collection of leases
- virtual Lease4Ptr getLease4(isc::asiolink::IOAddress addr) const;
-
- /// @brief Returns existing IPv4 lease for specific address and subnet
- /// @param addr address of the searched lease
- /// @param subnet_id ID of the subnet the lease must belong to
- ///
- /// @return smart pointer to the lease (or NULL if a lease is not found)
- virtual Lease4Ptr getLease4(isc::asiolink::IOAddress addr,
- SubnetID subnet_id) const;
-
- /// @brief Returns existing IPv4 leases for specified hardware address.
- ///
- /// Although in the usual case there will be only one lease, for mobile
- /// clients or clients with multiple static/fixed/reserved leases there
- /// can be more than one. Thus return type is a container, not a single
- /// pointer.
- ///
- /// @param hwaddr hardware address of the client
- ///
- /// @return lease collection
- virtual Lease4Collection getLease4(const HWAddr& hwaddr) const;
-
- /// @brief Returns existing IPv4 leases for specified hardware address
- /// and a subnet
- ///
- /// There can be at most one lease for a given HW address in a single
- /// pool, so this method with either return a single lease or NULL.
- ///
- /// @param hwaddr hardware address of the client
- /// @param subnet_id identifier of the subnet that lease must belong to
- ///
- /// @return a pointer to the lease (or NULL if a lease is not found)
- virtual Lease4Ptr getLease4(const HWAddr& hwaddr,
- SubnetID subnet_id) const;
-
- /// @brief Returns existing IPv4 lease for specified client-id
- ///
- /// @param clientid client identifier
- virtual Lease4Collection getLease4(const ClientId& clientid) const;
-
- /// @brief Returns existing IPv4 lease for specified client-id
- ///
- /// There can be at most one lease for a given HW address in a single
- /// pool, so this method with either return a single lease or NULL.
- ///
- /// @param clientid client identifier
- /// @param subnet_id identifier of the subnet that lease must belong to
- ///
- /// @return a pointer to the lease (or NULL if a lease is not found)
- virtual Lease4Ptr getLease4(const ClientId& clientid,
- SubnetID subnet_id) const;
-
- /// @brief Returns existing IPv6 lease for a given IPv6 address.
- ///
- /// @param addr address of the searched lease
- ///
- /// @return smart pointer to the lease (or NULL if a lease is not found)
- Lease6Ptr getLease6(isc::asiolink::IOAddress addr) const;
-
- /// @brief Returns existing IPv6 lease for a given DUID+IA combination
- ///
- /// @param duid client DUID
- /// @param iaid IA identifier
- ///
- /// @return collection of IPv6 leases
- Lease6Collection getLease6(const DUID& duid, uint32_t iaid) const;
-
- /// @brief Returns existing IPv6 lease for a given DUID+IA combination
- ///
- /// @param duid client DUID
- /// @param iaid IA identifier
- /// @param subnet_id identifier of the subnet the lease must belong to
- ///
- /// @return smart pointer to the lease (or NULL if a lease is not found)
- Lease6Ptr getLease6(const DUID& duid, uint32_t iaid, SubnetID subnet_id) const;
-
- /// @brief Updates IPv4 lease.
- ///
- /// @param lease4 The lease to be updated.
- ///
- /// If no such lease is present, an exception will be thrown.
- void updateLease4(Lease4Ptr lease4);
-
- /// @brief Updates IPv4 lease.
- ///
- /// @param lease4 The lease to be updated.
- ///
- /// If no such lease is present, an exception will be thrown.
- void updateLease6(Lease6Ptr lease6);
-
- /// @brief Deletes a lease.
- ///
- /// @param addr IPv4 address of the lease to be deleted.
- ///
- /// @return true if deletion was successful, false if no such lease exists
- bool deleteLease4(uint32_t addr);
-
- /// @brief Deletes a lease.
- ///
- /// @param addr IPv4 address of the lease to be deleted.
- ///
- /// @return true if deletion was successful, false if no such lease exists
- bool deleteLease6(isc::asiolink::IOAddress addr);
-
- /// @brief Returns backend name.
- ///
- /// Each backend have specific name, e.g. "mysql" or "sqlite".
- std::string getName() const { return "memfile"; }
-
- /// @brief Returns description of the backend.
- ///
- /// This description may be multiline text that describes the backend.
- std::string getDescription() const;
-
- /// @brief Returns backend version.
- std::string getVersion() const { return "test-version"; }
-
- using LeaseMgr::getParameter;
-
-protected:
+// This test checks if the LeaseMgr can be instantiated and that it
+// parses parameters string properly.
+TEST_F(LeaseMgrTest, constructor) {
+ // should not throw any exceptions here
+ Memfile_LeaseMgr * leaseMgr = new Memfile_LeaseMgr("");
+ delete leaseMgr;
-};
+ leaseMgr = new Memfile_LeaseMgr("param1=value1 param2=value2");
-Memfile_LeaseMgr::Memfile_LeaseMgr(const std::string& dbconfig)
- : LeaseMgr(dbconfig) {
-}
+ EXPECT_EQ("value1", leaseMgr->getParameter("param1"));
+ EXPECT_EQ("value2", leaseMgr->getParameter("param2"));
+ EXPECT_THROW(leaseMgr->getParameter("param3"), BadValue);
-Memfile_LeaseMgr::~Memfile_LeaseMgr() {
+ delete leaseMgr;
}
-bool Memfile_LeaseMgr::addLease(boost::shared_ptr<isc::dhcp::Lease4>) {
- return (false);
-}
+// There's no point in calling any other methods in LeaseMgr, as they
+// are purely virtual, so we would only call Memfile_LeaseMgr methods.
+// Those methods are just stubs that does not return anything.
+// It seems likely that we will need to extend the memfile code for
+// allocation engine tests, so we may implement tests that call
+// Memfile_LeaseMgr methods then.
-bool Memfile_LeaseMgr::addLease(boost::shared_ptr<isc::dhcp::Lease6>) {
- return (false);
-}
+TEST_F(LeaseMgrTest, addGetDelete) {
+ Memfile_LeaseMgr * leaseMgr = new Memfile_LeaseMgr("");
-Lease4Ptr Memfile_LeaseMgr::getLease4(isc::asiolink::IOAddress) const {
- return (Lease4Ptr());
-}
+ IOAddress addr("2001:db8:1::456");
-Lease4Collection Memfile_LeaseMgr::getLease4(const HWAddr& ) const {
- return (Lease4Collection());
-}
+ uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+ DuidPtr duid(new DUID(llt, sizeof(llt)));
-Lease4Ptr Memfile_LeaseMgr::getLease4(isc::asiolink::IOAddress ,
- SubnetID) const {
- return (Lease4Ptr());
-}
+ uint32_t iaid = 7; // just a number
-Lease4Ptr Memfile_LeaseMgr::getLease4(const HWAddr&,
- SubnetID) const {
- return (Lease4Ptr());
-}
+ SubnetID subnet_id = 8; // just another number
+ Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr,
+ duid, iaid, 100, 200, 50, 80,
+ subnet_id));
-Lease4Ptr Memfile_LeaseMgr::getLease4(const ClientId&,
- SubnetID) const {
- return (Lease4Ptr());
-}
+ EXPECT_TRUE(leaseMgr->addLease(lease));
-Lease4Collection Memfile_LeaseMgr::getLease4(const ClientId& ) const {
- return (Lease4Collection());
-}
+ // should not be allowed to add a second lease with the same address
+ EXPECT_FALSE(leaseMgr->addLease(lease));
-Lease6Ptr Memfile_LeaseMgr::getLease6(isc::asiolink::IOAddress) const {
- return (Lease6Ptr());
-}
+ Lease6Ptr x = leaseMgr->getLease6(IOAddress("2001:db8:1::234"));
+ EXPECT_EQ(Lease6Ptr(), x);
-Lease6Collection Memfile_LeaseMgr::getLease6(const DUID& , uint32_t ) const {
- return (Lease6Collection());
-}
+ x = leaseMgr->getLease6(IOAddress("2001:db8:1::456"));
+ ASSERT_TRUE(x);
-Lease6Ptr Memfile_LeaseMgr::getLease6(const DUID&, uint32_t,
- SubnetID) const {
- return (Lease6Ptr());
-}
+ EXPECT_EQ(x->addr_.toText(), addr.toText());
+ EXPECT_TRUE(*x->duid_ == *duid);
+ EXPECT_EQ(x->iaid_, iaid);
+ EXPECT_EQ(x->subnet_id_, subnet_id);
-void Memfile_LeaseMgr::updateLease4(Lease4Ptr ) {
-}
+ // These are not important from lease management perspective, but
+ // let's check them anyway.
+ EXPECT_EQ(x->type_, Lease6::LEASE_IA_NA);
+ EXPECT_EQ(x->preferred_lft_, 100);
+ EXPECT_EQ(x->valid_lft_, 200);
+ EXPECT_EQ(x->t1_, 50);
+ EXPECT_EQ(x->t2_, 80);
-void Memfile_LeaseMgr::updateLease6(Lease6Ptr ) {
+ // should return false - there's no such address
+ EXPECT_FALSE(leaseMgr->deleteLease6(IOAddress("2001:db8:1::789")));
-}
+ // this one should succeed
+ EXPECT_TRUE(leaseMgr->deleteLease6(IOAddress("2001:db8:1::456")));
-bool Memfile_LeaseMgr::deleteLease4(uint32_t ) {
- return (false);
-}
+ // after the lease is deleted, it should really be gone
+ x = leaseMgr->getLease6(IOAddress("2001:db8:1::456"));
+ EXPECT_EQ(Lease6Ptr(), x);
-bool Memfile_LeaseMgr::deleteLease6(isc::asiolink::IOAddress ) {
- return (false);
+ delete leaseMgr;
}
-std::string Memfile_LeaseMgr::getDescription() const {
- return (string("This is a dummy memfile backend implementation.\n"
- "It does not offer any useful lease management and its only\n"
- "purpose is to test abstract lease manager API."));
-}
+// This test checks there that leaseMgr is really a singleton and that
+// no more than one can be created.
+TEST_F(LeaseMgrTest, singleton) {
+ Memfile_LeaseMgr* leaseMgr1 = NULL;
+ Memfile_LeaseMgr* leaseMgr2 = NULL;
-namespace {
-// empty class for now, but may be extended once Addr6 becomes bigger
-class LeaseMgrTest : public ::testing::Test {
-public:
- LeaseMgrTest() {
- }
-};
+ EXPECT_THROW(LeaseMgr::instance(), InvalidOperation);
-// This test checks if the LeaseMgr can be instantiated and that it
-// parses parameters string properly.
-TEST_F(LeaseMgrTest, constructor) {
+ EXPECT_NO_THROW( leaseMgr1 = new Memfile_LeaseMgr("") );
- // should not throw any exceptions here
- Memfile_LeaseMgr * leaseMgr = new Memfile_LeaseMgr("");
- delete leaseMgr;
+ EXPECT_NO_THROW(LeaseMgr::instance());
- leaseMgr = new Memfile_LeaseMgr("param1=value1 param2=value2");
+ // There can be only one instance of any LeaseMgr derived
+ // objects instantiated at any time.
+ ASSERT_THROW(leaseMgr2 = new Memfile_LeaseMgr(""), InvalidOperation);
- EXPECT_EQ("value1", leaseMgr->getParameter("param1"));
- EXPECT_EQ("value2", leaseMgr->getParameter("param2"));
- EXPECT_THROW(leaseMgr->getParameter("param3"), BadValue);
+ delete leaseMgr1;
- delete leaseMgr;
+ ASSERT_NO_THROW(leaseMgr2 = new Memfile_LeaseMgr("") );
+
+ delete leaseMgr2;
}
-// There's no point in calling any other methods in LeaseMgr, as they
-// are purely virtual, so we would only call Memfile_LeaseMgr methods.
-// Those methods are just stubs that does not return anything.
-// It seems likely that we will need to extend the memfile code for
-// allocation engine tests, so we may implement tests that call
-// Memfile_LeaseMgr methods then.
+// This test checks if the Lease6 structure can be instantiated correctly
+TEST(Lease6, ctor) {
+
+ IOAddress addr("2001:db8:1::456");
+
+ uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+ DuidPtr duid(new DUID(llt, sizeof(llt)));
+
+ uint32_t iaid = 7; // just a number
+
+ SubnetID subnet_id = 8; // just another number
+
+ Lease6Ptr x(new Lease6(Lease6::LEASE_IA_NA, addr,
+ duid, iaid, 100, 200, 50, 80,
+ subnet_id));
+
+ EXPECT_TRUE(x->addr_ == addr);
+ EXPECT_TRUE(*x->duid_ == *duid);
+ EXPECT_TRUE(x->iaid_ == iaid);
+ EXPECT_TRUE(x->subnet_id_ == subnet_id);
+ EXPECT_TRUE(x->type_ == Lease6::LEASE_IA_NA);
+ EXPECT_TRUE(x->preferred_lft_ == 100);
+ EXPECT_TRUE(x->valid_lft_ == 200);
+ EXPECT_TRUE(x->t1_ == 50);
+ EXPECT_TRUE(x->t2_ == 80);
+
+ // Lease6 must be instantiated with a DUID, not with NULL pointer
+ EXPECT_THROW(new Lease6(Lease6::LEASE_IA_NA, addr,
+ DuidPtr(), iaid, 100, 200, 50, 80,
+ subnet_id), InvalidOperation);
+}
}; // end of anonymous namespace
diff --git a/src/lib/dhcp/tests/memfile_lease_mgr.cc b/src/lib/dhcp/tests/memfile_lease_mgr.cc
new file mode 100644
index 0000000..195fd8b
--- /dev/null
+++ b/src/lib/dhcp/tests/memfile_lease_mgr.cc
@@ -0,0 +1,113 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include "memfile_lease_mgr.h"
+
+using namespace isc::dhcp;
+using namespace isc::dhcp::test;
+
+Memfile_LeaseMgr::Memfile_LeaseMgr(const std::string& dbconfig)
+ : LeaseMgr(dbconfig) {
+}
+
+Memfile_LeaseMgr::~Memfile_LeaseMgr() {
+}
+
+bool Memfile_LeaseMgr::addLease(const Lease4Ptr&) {
+ return (false);
+}
+
+bool Memfile_LeaseMgr::addLease(const Lease6Ptr& lease) {
+ if (getLease6(lease->addr_)) {
+ // there is a lease with specified address already
+ return (false);
+ }
+ storage6_.insert(lease);
+ return (true);
+}
+
+Lease4Ptr Memfile_LeaseMgr::getLease4(isc::asiolink::IOAddress) const {
+ return (Lease4Ptr());
+}
+
+Lease4Collection Memfile_LeaseMgr::getLease4(const HWAddr& ) const {
+ return (Lease4Collection());
+}
+
+Lease4Ptr Memfile_LeaseMgr::getLease4(isc::asiolink::IOAddress ,
+ SubnetID) const {
+ return (Lease4Ptr());
+}
+
+Lease4Ptr Memfile_LeaseMgr::getLease4(const HWAddr&,
+ SubnetID) const {
+ return (Lease4Ptr());
+}
+
+
+Lease4Ptr Memfile_LeaseMgr::getLease4(const ClientId&,
+ SubnetID) const {
+ return (Lease4Ptr());
+}
+
+Lease4Collection Memfile_LeaseMgr::getLease4(const ClientId& ) const {
+ return (Lease4Collection());
+}
+
+Lease6Ptr Memfile_LeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
+ Lease6Storage::iterator l = storage6_.find(addr);
+ if (l == storage6_.end()) {
+ return (Lease6Ptr());
+ } else {
+ return (*l);
+ }
+}
+
+Lease6Collection Memfile_LeaseMgr::getLease6(const DUID& , uint32_t ) const {
+ return (Lease6Collection());
+}
+
+Lease6Ptr Memfile_LeaseMgr::getLease6(const DUID&, uint32_t,
+ SubnetID) const {
+
+ return (Lease6Ptr());
+}
+
+void Memfile_LeaseMgr::updateLease4(const Lease4Ptr& ) {
+}
+
+void Memfile_LeaseMgr::updateLease6(const Lease6Ptr& ) {
+
+}
+
+bool Memfile_LeaseMgr::deleteLease4(uint32_t ) {
+ return (false);
+}
+
+bool Memfile_LeaseMgr::deleteLease6(const isc::asiolink::IOAddress& addr) {
+ Lease6Storage::iterator l = storage6_.find(addr);
+ if (l == storage6_.end()) {
+ // no such lease
+ return (false);
+ } else {
+ storage6_.erase(l);
+ return (true);
+ }
+}
+
+std::string Memfile_LeaseMgr::getDescription() const {
+ return (std::string("This is a dummy memfile backend implementation.\n"
+ "It does not offer any useful lease management and its only\n"
+ "purpose is to test abstract lease manager API."));
+}
diff --git a/src/lib/dhcp/tests/memfile_lease_mgr.h b/src/lib/dhcp/tests/memfile_lease_mgr.h
new file mode 100644
index 0000000..c5a41e6
--- /dev/null
+++ b/src/lib/dhcp/tests/memfile_lease_mgr.h
@@ -0,0 +1,228 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef MEMFILE_LEASE_MGR_H
+#define MEMFILE_LEASE_MGR_H
+
+#include <dhcp/lease_mgr.h>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/indexed_by.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/member.hpp>
+
+namespace isc {
+namespace dhcp {
+namespace test {
+
+// This is a concrete implementation of a Lease database.
+//
+// It is for testing purposes only. It is NOT a production code.
+//
+// It does not do anything useful now, and is used for abstract LeaseMgr
+// class testing. It may later evolve into more useful backend if the
+// need arises. We can reuse code from memfile benchmark. See code in
+// tests/tools/dhcp-ubench/memfile_bench.{cc|h}
+class Memfile_LeaseMgr : public LeaseMgr {
+public:
+
+ /// @brief The sole lease manager constructor
+ ///
+ /// dbconfig is a generic way of passing parameters. Parameters
+ /// are passed in the "name=value" format, separated by spaces.
+ /// Values may be enclosed in double quotes, if needed.
+ ///
+ /// @param dbconfig database configuration
+ Memfile_LeaseMgr(const std::string& dbconfig);
+
+ /// @brief Destructor (closes file)
+ virtual ~Memfile_LeaseMgr();
+
+ /// @brief Adds an IPv4 lease.
+ ///
+ /// @todo Not implemented yet
+ /// @param lease lease to be added
+ virtual bool addLease(const Lease4Ptr& lease);
+
+ /// @brief Adds an IPv6 lease.
+ ///
+ /// @param lease lease to be added
+ virtual bool addLease(const Lease6Ptr& lease);
+
+ /// @brief Returns existing IPv4 lease for specified IPv4 address.
+ ///
+ /// @todo Not implemented yet
+ /// @param addr address of the searched lease
+ ///
+ /// @return a collection of leases
+ virtual Lease4Ptr getLease4(isc::asiolink::IOAddress addr) const;
+
+ /// @brief Returns existing IPv4 lease for specific address and subnet
+ ///
+ /// @todo Not implemented yet
+ /// @param addr address of the searched lease
+ /// @param subnet_id ID of the subnet the lease must belong to
+ ///
+ /// @return smart pointer to the lease (or NULL if a lease is not found)
+ virtual Lease4Ptr getLease4(isc::asiolink::IOAddress addr,
+ SubnetID subnet_id) const;
+
+ /// @brief Returns existing IPv4 leases for specified hardware address.
+ ///
+ /// @todo Not implemented yet
+ ///
+ /// Although in the usual case there will be only one lease, for mobile
+ /// clients or clients with multiple static/fixed/reserved leases there
+ /// can be more than one. Thus return type is a container, not a single
+ /// pointer.
+ ///
+ /// @param hwaddr hardware address of the client
+ ///
+ /// @return lease collection
+ virtual Lease4Collection getLease4(const HWAddr& hwaddr) const;
+
+ /// @brief Returns existing IPv4 leases for specified hardware address
+ /// and a subnet
+ ///
+ /// @todo Not implemented yet
+ ///
+ /// There can be at most one lease for a given HW address in a single
+ /// pool, so this method with either return a single lease or NULL.
+ ///
+ /// @param hwaddr hardware address of the client
+ /// @param subnet_id identifier of the subnet that lease must belong to
+ ///
+ /// @return a pointer to the lease (or NULL if a lease is not found)
+ virtual Lease4Ptr getLease4(const HWAddr& hwaddr,
+ SubnetID subnet_id) const;
+
+ /// @brief Returns existing IPv4 lease for specified client-id
+ ///
+ /// @todo Not implemented yet
+ ///
+ /// @param clientid client identifier
+ virtual Lease4Collection getLease4(const ClientId& clientid) const;
+
+ /// @brief Returns existing IPv4 lease for specified client-id
+ ///
+ /// There can be at most one lease for a given HW address in a single
+ /// pool, so this method with either return a single lease or NULL.
+ ///
+ /// @todo Not implemented yet
+ ///
+ /// @param clientid client identifier
+ /// @param subnet_id identifier of the subnet that lease must belong to
+ ///
+ /// @return a pointer to the lease (or NULL if a lease is not found)
+ virtual Lease4Ptr getLease4(const ClientId& clientid,
+ SubnetID subnet_id) const;
+
+ /// @brief Returns existing IPv6 lease for a given IPv6 address.
+ ///
+ /// @param addr address of the searched lease
+ ///
+ /// @return smart pointer to the lease (or NULL if a lease is not found)
+ Lease6Ptr getLease6(const isc::asiolink::IOAddress& addr) const;
+
+ /// @brief Returns existing IPv6 lease for a given DUID+IA combination
+ ///
+ /// @todo Not implemented yet
+ ///
+ /// @param duid client DUID
+ /// @param iaid IA identifier
+ ///
+ /// @return collection of IPv6 leases
+ Lease6Collection getLease6(const DUID& duid, uint32_t iaid) const;
+
+ /// @brief Returns existing IPv6 lease for a given DUID+IA combination
+ ///
+ /// @todo Not implemented yet
+ ///
+ /// @param duid client DUID
+ /// @param iaid IA identifier
+ /// @param subnet_id identifier of the subnet the lease must belong to
+ ///
+ /// @return smart pointer to the lease (or NULL if a lease is not found)
+ Lease6Ptr getLease6(const DUID& duid, uint32_t iaid, SubnetID subnet_id) const;
+
+ /// @brief Updates IPv4 lease.
+ ///
+ /// @todo Not implemented yet
+ ///
+ /// @param lease4 The lease to be updated.
+ ///
+ /// If no such lease is present, an exception will be thrown.
+ void updateLease4(const Lease4Ptr& lease4);
+
+ /// @brief Updates IPv4 lease.
+ ///
+ /// @todo Not implemented yet
+ ///
+ /// @param lease4 The lease to be updated.
+ ///
+ /// If no such lease is present, an exception will be thrown.
+ void updateLease6(const Lease6Ptr& lease6);
+
+ /// @brief Deletes a lease.
+ ///
+ /// @todo Not implemented yet
+ ///
+ /// @param addr IPv4 address of the lease to be deleted.
+ ///
+ /// @return true if deletion was successful, false if no such lease exists
+ bool deleteLease4(uint32_t addr);
+
+ /// @brief Deletes a lease.
+ ///
+ /// @param addr IPv4 address of the lease to be deleted.
+ ///
+ /// @return true if deletion was successful, false if no such lease exists
+ bool deleteLease6(const isc::asiolink::IOAddress& addr);
+
+ /// @brief Returns backend name.
+ ///
+ /// Each backend have specific name, e.g. "mysql" or "sqlite".
+ std::string getName() const { return ("memfile"); }
+
+ /// @brief Returns description of the backend.
+ ///
+ /// This description may be multiline text that describes the backend.
+ std::string getDescription() const;
+
+ /// @brief Returns backend version.
+ std::string getVersion() const { return ("test-version"); }
+
+ using LeaseMgr::getParameter;
+
+protected:
+
+ typedef boost::multi_index_container< // this is a multi-index container...
+ Lease6Ptr, // it will hold shared_ptr to leases6
+ boost::multi_index::indexed_by< // and will be sorted by
+ // IPv6 address that are unique. That particular key is a member
+ // of the Lease6 structure, is of type IOAddress and can be accessed
+ // by doing &Lease6::addr_
+ boost::multi_index::ordered_unique<
+ boost::multi_index::member<Lease6, isc::asiolink::IOAddress, &Lease6::addr_>
+ >
+ >
+ > Lease6Storage; // Let the whole contraption be called Lease6Storage.
+
+ Lease6Storage storage6_;
+};
+
+}; // end of isc::dhcp::test namespace
+}; // end of isc::dhcp namespace
+}; // end of isc namespace
+
+#endif // MEMFILE_LEASE_MGR_H
diff --git a/src/lib/dhcp/tests/pool_unittest.cc b/src/lib/dhcp/tests/pool_unittest.cc
index 63d4289..e596278 100644
--- a/src/lib/dhcp/tests/pool_unittest.cc
+++ b/src/lib/dhcp/tests/pool_unittest.cc
@@ -179,4 +179,3 @@ TEST(Pool6Test, unique_id) {
}
}; // end of anonymous namespace
-
diff --git a/src/lib/dhcp/tests/subnet_unittest.cc b/src/lib/dhcp/tests/subnet_unittest.cc
index 0e2e846..be25bc1 100644
--- a/src/lib/dhcp/tests/subnet_unittest.cc
+++ b/src/lib/dhcp/tests/subnet_unittest.cc
@@ -123,6 +123,41 @@ TEST(Subnet4Test, addInvalidOption) {
EXPECT_THROW(subnet->addOption(option2), isc::BadValue);
}
+// This test verifies that inRange() and inPool() methods work properly.
+TEST(Subnet4Test, inRangeinPool) {
+ Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.0.0"), 8, 1, 2, 3));
+
+ // this one is in subnet
+ Pool4Ptr pool1(new Pool4(IOAddress("192.2.0.0"), 16));
+ subnet->addPool4(pool1);
+
+ // 192.1.1.1 belongs to the subnet...
+ EXPECT_TRUE(subnet->inRange(IOAddress("192.1.1.1")));
+
+ // ... but it does not belong to any pool within
+ EXPECT_FALSE(subnet->inPool(IOAddress("192.1.1.1")));
+
+ // the last address that is in range, but out of pool
+ EXPECT_TRUE(subnet->inRange(IOAddress("192.1.255.255")));
+ EXPECT_FALSE(subnet->inPool(IOAddress("192.1.255.255")));
+
+ // the first address that is in range, in pool
+ EXPECT_TRUE(subnet->inRange(IOAddress("192.2.0.0")));
+ EXPECT_TRUE (subnet->inPool(IOAddress("192.2.0.0")));
+
+ // let's try something in the middle as well
+ EXPECT_TRUE(subnet->inRange(IOAddress("192.2.3.4")));
+ EXPECT_TRUE (subnet->inPool(IOAddress("192.2.3.4")));
+
+ // the last address that is in range, in pool
+ EXPECT_TRUE(subnet->inRange(IOAddress("192.2.255.255")));
+ EXPECT_TRUE (subnet->inPool(IOAddress("192.2.255.255")));
+
+ // the first address that is in range, but out of pool
+ EXPECT_TRUE(subnet->inRange(IOAddress("192.3.0.0")));
+ EXPECT_FALSE(subnet->inPool(IOAddress("192.3.0.0")));
+}
+
// Tests for Subnet6
TEST(Subnet6Test, constructor) {
@@ -180,7 +215,6 @@ TEST(Subnet6Test, Pool6InSubnet6) {
mypool = subnet->getPool6(IOAddress("2001:db8:1:3::dead:beef"));
EXPECT_EQ(mypool, pool3);
-
}
TEST(Subnet6Test, Subnet6_Pool6_checks) {
@@ -348,4 +382,40 @@ TEST(Subnet6Test, addPersistentOption) {
options = subnet->getOptions();
EXPECT_EQ(0, options.size());
}
+
+// This test verifies that inRange() and inPool() methods work properly.
+TEST(Subnet6Test, inRangeinPool) {
+ Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 32, 1, 2, 3, 4));
+
+ // this one is in subnet
+ Pool6Ptr pool1(new Pool6(Pool6::TYPE_IA, IOAddress("2001:db8::10"),
+ IOAddress("2001:db8::20")));
+ subnet->addPool6(pool1);
+
+ // 192.1.1.1 belongs to the subnet...
+ EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::1")));
+ // ... but it does not belong to any pool within
+ EXPECT_FALSE(subnet->inPool(IOAddress("2001:db8::1")));
+
+ // the last address that is in range, but out of pool
+ EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::f")));
+ EXPECT_FALSE(subnet->inPool(IOAddress("2001:db8::f")));
+
+ // the first address that is in range, in pool
+ EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::10")));
+ EXPECT_TRUE (subnet->inPool(IOAddress("2001:db8::10")));
+
+ // let's try something in the middle as well
+ EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::18")));
+ EXPECT_TRUE (subnet->inPool(IOAddress("2001:db8::18")));
+
+ // the last address that is in range, in pool
+ EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::20")));
+ EXPECT_TRUE (subnet->inPool(IOAddress("2001:db8::20")));
+
+ // the first address that is in range, but out of pool
+ EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::21")));
+ EXPECT_FALSE(subnet->inPool(IOAddress("2001:db8::21")));
+}
+
};
diff --git a/src/lib/dns/Makefile.am b/src/lib/dns/Makefile.am
index 977854d..5cf0732 100644
--- a/src/lib/dns/Makefile.am
+++ b/src/lib/dns/Makefile.am
@@ -95,6 +95,7 @@ libb10_dns___la_SOURCES += edns.h edns.cc
libb10_dns___la_SOURCES += exceptions.h exceptions.cc
libb10_dns___la_SOURCES += labelsequence.h labelsequence.cc
libb10_dns___la_SOURCES += masterload.h masterload.cc
+libb10_dns___la_SOURCES += master_lexer.h master_lexer.cc
libb10_dns___la_SOURCES += message.h message.cc
libb10_dns___la_SOURCES += messagerenderer.h messagerenderer.cc
libb10_dns___la_SOURCES += name.h name.cc
@@ -145,6 +146,8 @@ libdns___include_HEADERS = \
exceptions.h \
labelsequence.h \
message.h \
+ master_lexer.h \
+ masterload.h \
messagerenderer.h \
name.h \
question.h \
diff --git a/src/lib/dns/benchmarks/message_renderer_bench.cc b/src/lib/dns/benchmarks/message_renderer_bench.cc
index abf3192..f5b3e38 100644
--- a/src/lib/dns/benchmarks/message_renderer_bench.cc
+++ b/src/lib/dns/benchmarks/message_renderer_bench.cc
@@ -145,7 +145,6 @@ main(int argc, char* argv[]) {
}
}
argc -= optind;
- argv += optind;
if (argc != 0) {
usage();
}
diff --git a/src/lib/dns/benchmarks/oldmessagerenderer.h b/src/lib/dns/benchmarks/oldmessagerenderer.h
index d408081..acbd757 100644
--- a/src/lib/dns/benchmarks/oldmessagerenderer.h
+++ b/src/lib/dns/benchmarks/oldmessagerenderer.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __OLDMESSAGERENDERER_H
-#define __OLDMESSAGERENDERER_H 1
+#ifndef OLDMESSAGERENDERER_H
+#define OLDMESSAGERENDERER_H 1
//
// This is a copy of an older version of MessageRenderer class. It is kept
@@ -49,7 +49,7 @@ private:
};
}
}
-#endif // __OLDMESSAGERENDERER_H
+#endif // OLDMESSAGERENDERER_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/character_string.h b/src/lib/dns/character_string.h
index 7961274..2a68778 100644
--- a/src/lib/dns/character_string.h
+++ b/src/lib/dns/character_string.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __CHARACTER_STRING_H
-#define __CHARACTER_STRING_H
+#ifndef CHARACTER_STRING_H
+#define CHARACTER_STRING_H
#include <string>
#include <exceptions/exceptions.h>
@@ -54,4 +54,4 @@ namespace characterstr {
} // namespace dns
} // namespace isc
-#endif // __CHARACTER_STRING_H
+#endif // CHARACTER_STRING_H
diff --git a/src/lib/dns/edns.h b/src/lib/dns/edns.h
index a7bc4c4..dcd552f 100644
--- a/src/lib/dns/edns.h
+++ b/src/lib/dns/edns.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __EDNS_H
-#define __EDNS_H 1
+#ifndef EDNS_H
+#define EDNS_H 1
#include <stdint.h>
@@ -438,7 +438,7 @@ EDNS* createEDNSFromRR(const Name& name, const RRClass& rrclass,
std::ostream& operator<<(std::ostream& os, const EDNS& edns);
}
}
-#endif // __EDNS_H
+#endif // EDNS_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/exceptions.h b/src/lib/dns/exceptions.h
index bd696a5..070b152 100644
--- a/src/lib/dns/exceptions.h
+++ b/src/lib/dns/exceptions.h
@@ -17,8 +17,8 @@
// style for the header guide (e.g. module-name_file-name_H) throughout the
// package.
-#ifndef __DNS_EXCEPTIONS_H
-#define __DNS_EXCEPTIONS_H 1
+#ifndef DNS_EXCEPTIONS_H
+#define DNS_EXCEPTIONS_H 1
#include <exceptions/exceptions.h>
@@ -52,7 +52,7 @@ public:
};
}
}
-#endif // __DNS_EXCEPTIONS_H
+#endif // DNS_EXCEPTIONS_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/gen-rdatacode.py.in b/src/lib/dns/gen-rdatacode.py.in
index f3cd5df..e51dfc5 100755
--- a/src/lib/dns/gen-rdatacode.py.in
+++ b/src/lib/dns/gen-rdatacode.py.in
@@ -74,7 +74,7 @@ def import_classheader(class_txt, type_txt, type_code, file):
# for each CLASS_n/TYPE_m.h
rdata_header = open(file, 'r')
content = ''
- guard_macro = '__' + class_txt.upper() + '_' + type_txt.upper()
+ guard_macro = class_txt.upper() + '_' + type_txt.upper()
guard_macro += '_' + type_code + '_H'
for line in rdata_header.readlines():
if re.match('// BEGIN_HEADER_GUARD', line):
diff --git a/src/lib/dns/labelsequence.h b/src/lib/dns/labelsequence.h
index 3f6a03a..6c97454 100644
--- a/src/lib/dns/labelsequence.h
+++ b/src/lib/dns/labelsequence.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LABELSEQUENCE_H
-#define __LABELSEQUENCE_H 1
+#ifndef LABELSEQUENCE_H
+#define LABELSEQUENCE_H 1
#include <dns/name.h>
#include <util/buffer.h>
diff --git a/src/lib/dns/master_lexer.cc b/src/lib/dns/master_lexer.cc
new file mode 100644
index 0000000..2a5c886
--- /dev/null
+++ b/src/lib/dns/master_lexer.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <dns/master_lexer.h>
+
+#include <cassert>
+#include <string>
+
+namespace {
+const char* const error_text[] = {
+ "lexer not started", // NOT_STARTED
+ "unbalanced parentheses", // UNBALANCED_PAREN
+ "unexpected end of input", // UNEXPECTED_END
+ "unbalanced quotes" // UNBALANCED_QUOTES
+};
+const size_t error_text_max_count = sizeof(error_text) / sizeof(error_text[0]);
+}
+
+namespace isc {
+namespace dns {
+
+std::string
+MasterLexer::Token::getErrorText() const {
+ if (type_ != ERROR) {
+ isc_throw(InvalidOperation,
+ "Token::getErrorText() for non error type");
+ }
+
+ // The class integrity ensures the following:
+ assert(val_.error_code_ < error_text_max_count);
+ return (error_text[val_.error_code_]);
+}
+
+
+} // end of namespace dns
+} // end of namespace isc
diff --git a/src/lib/dns/master_lexer.h b/src/lib/dns/master_lexer.h
new file mode 100644
index 0000000..bd86a04
--- /dev/null
+++ b/src/lib/dns/master_lexer.h
@@ -0,0 +1,241 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef MASTER_LEXER_H
+#define MASTER_LEXER_H 1
+
+#include <exceptions/exceptions.h>
+
+#include <string>
+
+#include <stdint.h>
+
+namespace isc {
+namespace dns {
+
+class MasterLexer {
+public:
+ class Token; // we define it separately for better readability
+};
+
+/// \brief Tokens for \c MasterLexer
+///
+/// This is a simple value-class encapsulating a type of a lexer token and
+/// (if it has a value) its value. Essentially, the class provides
+/// constructors corresponding to different types of tokens, and corresponding
+/// getter methods. The type and value are fixed at the time of construction
+/// and will never be modified throughout the lifetime of the object.
+/// The getter methods are still provided to maximize the safety; an
+/// application cannot refer to a value that is invalid for the type of token.
+///
+/// This class is intentionally implemented as copyable and assignable
+/// (using the default version of copy constructor and assignment operator),
+/// but it's mainly for internal implementation convenience. Applications will
+/// simply refer to Token object as a reference via the \c MasterLexer class.
+class MasterLexer::Token {
+public:
+ /// \brief Enumeration for token types
+ ///
+ /// \note At the time of initial implementation, all numeric tokens
+ /// that would be extracted from \c MasterLexer should be represented
+ /// as an unsigned 32-bit integer. If we see the need for larger integers
+ /// or negative numbers, we can then extend the token types.
+ enum Type {
+ END_OF_LINE, ///< End of line detected (if asked for detecting it)
+ END_OF_FILE, ///< End of file detected (if asked for detecting it)
+ INITIAL_WS, ///< White spaces at the beginning of a line
+ NOVALUE_TYPE_MAX = INITIAL_WS, ///< Max integer corresponding to
+ /// no-value (type only) types.
+ /// Mainly for internal use.
+ STRING, ///< A single string
+ QSTRING, ///< A single string quoted by double-quotes (").
+ NUMBER, ///< A decimal number (unsigned 32-bit)
+ ERROR ///< Error detected in getting a token
+ };
+
+ /// \brief Enumeration for lexer error codes
+ enum ErrorCode {
+ NOT_STARTED, ///< The lexer is just initialized and has no token
+ UNBALANCED_PAREN, ///< Unbalanced parentheses detected
+ UNEXPECTED_END, ///< The lexer reaches the end of line or file
+ /// unexpectedly
+ UNBALANCED_QUOTES, ///< Unbalanced quotations detected
+ MAX_ERROR_CODE ///< Max integer corresponding to valid error codes.
+ /// (excluding this one). Mainly for internal use.
+ };
+
+ /// \brief A simple representation of a range of a string.
+ ///
+ /// This is a straightforward pair of the start pointer of a string
+ /// and its length. The \c STRING and \c QSTRING types of tokens
+ /// will be primarily represented in this form.
+ ///
+ /// Any character can be stored in the valid range of the region.
+ /// In particular, there can be a nul character (\0) in the middle of
+ /// the region. On the other hand, it is not ensured that the string
+ /// is nul-terminated. So the usual string manipulation API may not work
+ /// as expected.
+ struct StringRegion {
+ const char* beg; ///< The start address of the string
+ size_t len; ///< The length of the string in bytes
+ };
+
+ /// \brief Constructor for non-value type of token.
+ ///
+ /// \throw InvalidParameter A value type token is specified.
+ /// \param type The type of the token. It must indicate a non-value
+ /// type (not larger than \c NOVALUE_TYPE_MAX).
+ explicit Token(Type type) : type_(type) {
+ if (type > NOVALUE_TYPE_MAX) {
+ isc_throw(InvalidParameter, "Token per-type constructor "
+ "called with invalid type: " << type);
+ }
+ }
+
+ /// \brief Constructor for string and quoted-string types of token.
+ ///
+ /// The optional \c quoted parameter specifies whether it's a quoted or
+ /// non quoted string.
+ ///
+ /// The string is specified as a pair of a pointer to the start address
+ /// and its length. Any character can be contained in any position of
+ /// the valid range (see \c StringRegion).
+ ///
+ /// When it's a quoted string, the quotation marks must be excluded
+ /// from the specified range.
+ ///
+ /// \param str_beg The start address of the string
+ /// \param str_len The size of the string in bytes
+ /// \param quoted true if it's a quoted string; false otherwise.
+ Token(const char* str_beg, size_t str_len, bool quoted = false) :
+ type_(quoted ? QSTRING : STRING)
+ {
+ val_.str_region_.beg = str_beg;
+ val_.str_region_.len = str_len;
+ }
+
+ /// \brief Constructor for number type of token.
+ ///
+ /// \brief number An unsigned 32-bit integer corresponding to the token
+ /// value.
+ explicit Token(uint32_t number) : type_(NUMBER) {
+ val_.number_ = number;
+ }
+
+ /// \brief Constructor for error type of token.
+ ///
+ /// \throw InvalidParameter Invalid error code value is specified.
+ /// \brief error_code A pre-defined constant of \c ErrorCode.
+ explicit Token(ErrorCode error_code) : type_(ERROR) {
+ if (!(error_code < MAX_ERROR_CODE)) {
+ isc_throw(InvalidParameter, "Invalid master lexer error code: "
+ << error_code);
+ }
+ val_.error_code_ = error_code;
+ }
+
+ /// \brief Return the token type.
+ ///
+ /// \throw none
+ Type getType() const { return (type_); }
+
+ /// \brief Return the value of a string-variant token.
+ ///
+ /// \throw InvalidOperation Called on a non string-variant types of token.
+ /// \return A reference to \c StringRegion corresponding to the string
+ /// token value.
+ const StringRegion& getStringRegion() const {
+ if (type_ != STRING && type_ != QSTRING) {
+ isc_throw(InvalidOperation,
+ "Token::getStringRegion() for non string-variant type");
+ }
+ return (val_.str_region_);
+ }
+
+ /// \brief Return the value of a string-variant token as a string object.
+ ///
+ /// Note that the underlying string may contain a nul (\0) character
+ /// in the middle. The returned string object will contain all characters
+ /// of the valid range of the underlying string. So some string
+ /// operations such as c_str() may not work as expected.
+ ///
+ /// \throw InvalidOperation Called on a non string-variant types of token.
+ /// \throw std::bad_alloc Resource allocation failure in constructing the
+ /// string object.
+ /// \return A std::string object corresponding to the string token value.
+ std::string getString() const {
+ if (type_ != STRING && type_ != QSTRING) {
+ isc_throw(InvalidOperation,
+ "Token::getString() for non string-variant type");
+ }
+ return (std::string(val_.str_region_.beg,
+ val_.str_region_.beg + val_.str_region_.len));
+ }
+
+ /// \brief Return the value of a string-variant token as a string object.
+ ///
+ /// \throw InvalidOperation Called on a non number type of token.
+ /// \return The integer corresponding to the number token value.
+ uint32_t getNumber() const {
+ if (type_ != NUMBER) {
+ isc_throw(InvalidOperation,
+ "Token::getNumber() for non number type");
+ }
+ return (val_.number_);
+ }
+
+ /// \brief Return the error code of a error type token.
+ ///
+ /// \throw InvalidOperation Called on a non error type of token.
+ /// \return The error code of the token.
+ ErrorCode getErrorCode() const {
+ if (type_ != ERROR) {
+ isc_throw(InvalidOperation,
+ "Token::getErrorCode() for non error type");
+ }
+ return (val_.error_code_);
+ };
+
+ /// \brief Return a textual description of the error of a error type token.
+ ///
+ /// The returned string would be useful to produce a log message when
+ /// a zone file parser encounters an error.
+ ///
+ /// \throw InvalidOperation Called on a non error type of token.
+ /// \throw std::bad_alloc Resource allocation failure in constructing the
+ /// string object.
+ /// \return A string object that describes the meaning of the error.
+ std::string getErrorText() const;
+
+private:
+ Type type_; // this is not const so the class can be assignable
+
+ // We use a union to represent different types of token values via the
+ // unified Token class. The class integrity should ensure valid operation
+ // on the union; getter methods should only refer to the member set at
+ // the construction.
+ union {
+ StringRegion str_region_;
+ uint32_t number_;
+ ErrorCode error_code_;
+ } val_;
+};
+
+} // namespace dns
+} // namespace isc
+#endif // MASTER_LEXER_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/lib/dns/masterload.h b/src/lib/dns/masterload.h
index e252285..44b3d62 100644
--- a/src/lib/dns/masterload.h
+++ b/src/lib/dns/masterload.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MASTERLOAD_H
-#define __MASTERLOAD_H 1
+#ifndef MASTERLOAD_H
+#define MASTERLOAD_H 1
#include <iosfwd>
@@ -244,7 +244,7 @@ void masterLoad(std::istream& input, const Name& origin,
//@}
}
-#endif // __MASTERLOAD_H
+#endif // MASTERLOAD_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/message.h b/src/lib/dns/message.h
index 85754ac..8aaaa48 100644
--- a/src/lib/dns/message.h
+++ b/src/lib/dns/message.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MESSAGE_H
-#define __MESSAGE_H 1
+#ifndef MESSAGE_H
+#define MESSAGE_H 1
#include <stdint.h>
@@ -687,7 +687,7 @@ typedef boost::shared_ptr<const Message> ConstMessagePtr;
std::ostream& operator<<(std::ostream& os, const Message& message);
}
}
-#endif // __MESSAGE_H
+#endif // MESSAGE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/messagerenderer.h b/src/lib/dns/messagerenderer.h
index 4816ad5..092d6de 100644
--- a/src/lib/dns/messagerenderer.h
+++ b/src/lib/dns/messagerenderer.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MESSAGERENDERER_H
-#define __MESSAGERENDERER_H 1
+#ifndef MESSAGERENDERER_H
+#define MESSAGERENDERER_H 1
#include <util/buffer.h>
@@ -397,7 +397,7 @@ private:
};
}
}
-#endif // __MESSAGERENDERER_H
+#endif // MESSAGERENDERER_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/name.cc b/src/lib/dns/name.cc
index 5ea339d..079033a 100644
--- a/src/lib/dns/name.cc
+++ b/src/lib/dns/name.cc
@@ -123,15 +123,18 @@ typedef enum {
ft_ordinary, // parsing an ordinary label
ft_initialescape, // just found '\'
ft_escape, // begin of handling a '\'-escaped sequence
- ft_escdecimal, // parsing a '\DDD' octet.
-
- // Unused at this moment. We'll revisit this when we support master file
- // parser where @ is used to mean an origin name.
- ft_at
+ ft_escdecimal // parsing a '\DDD' octet.
} ft_state;
-}
-Name::Name(const std::string &namestring, bool downcase) {
+// The parser of name from a string. It is a template, because
+// some parameters are used with two different types, while others
+// are private type aliases.
+template<class Iterator, class Offsets, class Data>
+void
+stringParse(Iterator s, Iterator send, bool downcase, Offsets& offsets,
+ Data& ndata)
+{
+ const Iterator orig_s(s);
//
// Initialize things to make the compiler happy; they're not required.
//
@@ -142,17 +145,14 @@ Name::Name(const std::string &namestring, bool downcase) {
//
// Set up the state machine.
//
- std::string::const_iterator s = namestring.begin();
- std::string::const_iterator send = namestring.end();
bool done = false;
bool is_root = false;
+ const bool empty = s == send;
ft_state state = ft_init;
- NameOffsets offsets;
+ // Prepare the output buffers.
offsets.reserve(Name::MAX_LABELS);
offsets.push_back(0);
-
- NameString ndata;
ndata.reserve(Name::MAX_WIRE);
// should we refactor this code using, e.g, the state pattern? Probably
@@ -171,7 +171,8 @@ Name::Name(const std::string &namestring, bool downcase) {
if (c == '.') {
if (s != send) {
isc_throw(EmptyLabel,
- "non terminating empty label in " << namestring);
+ "non terminating empty label in " <<
+ string(orig_s, send));
}
is_root = true;
} else if (c == '@' && s == send) {
@@ -200,7 +201,7 @@ Name::Name(const std::string &namestring, bool downcase) {
if (c == '.') {
if (count == 0) {
isc_throw(EmptyLabel,
- "duplicate period in " << namestring);
+ "duplicate period in " << string(orig_s, send));
}
ndata.at(offsets.back()) = count;
offsets.push_back(ndata.size());
@@ -212,9 +213,9 @@ Name::Name(const std::string &namestring, bool downcase) {
} else if (c == '\\') {
state = ft_escape;
} else {
- if (++count > MAX_LABELLEN) {
+ if (++count > Name::MAX_LABELLEN) {
isc_throw(TooLongLabel,
- "label is too long in " << namestring);
+ "label is too long in " << string(orig_s, send));
}
ndata.push_back(downcase ? maptolower[c] : c);
}
@@ -224,15 +225,15 @@ Name::Name(const std::string &namestring, bool downcase) {
// This looks like a bitstring label, which was deprecated.
// Intentionally drop it.
isc_throw(BadLabelType,
- "invalid label type in " << namestring);
+ "invalid label type in " << string(orig_s, send));
}
state = ft_escape;
// FALLTHROUGH
case ft_escape:
if (!isdigit(c & 0xff)) {
- if (++count > MAX_LABELLEN) {
+ if (++count > Name::MAX_LABELLEN) {
isc_throw(TooLongLabel,
- "label is too long in " << namestring);
+ "label is too long in " << string(orig_s, send));
}
ndata.push_back(downcase ? maptolower[c] : c);
state = ft_ordinary;
@@ -246,7 +247,7 @@ Name::Name(const std::string &namestring, bool downcase) {
if (!isdigit(c & 0xff)) {
isc_throw(BadEscape,
"mixture of escaped digit and non-digit in "
- << namestring);
+ << string(orig_s, send));
}
value *= 10;
value += digitvalue[c];
@@ -255,11 +256,11 @@ Name::Name(const std::string &namestring, bool downcase) {
if (value > 255) {
isc_throw(BadEscape,
"escaped decimal is too large in "
- << namestring);
+ << string(orig_s, send));
}
- if (++count > MAX_LABELLEN) {
+ if (++count > Name::MAX_LABELLEN) {
isc_throw(TooLongLabel,
- "label is too long in " << namestring);
+ "label is too long in " << string(orig_s, send));
}
ndata.push_back(downcase ? maptolower[value] : value);
state = ft_ordinary;
@@ -274,13 +275,14 @@ Name::Name(const std::string &namestring, bool downcase) {
if (!done) { // no trailing '.' was found.
if (ndata.size() == Name::MAX_WIRE) {
isc_throw(TooLongName,
- "name is too long for termination in " << namestring);
+ "name is too long for termination in " <<
+ string(orig_s, send));
}
assert(s == send);
- if (state != ft_ordinary && state != ft_at) {
+ if (state != ft_ordinary) {
isc_throw(IncompleteName,
"incomplete textual name in " <<
- (namestring.empty() ? "<empty>" : namestring));
+ (empty ? "<empty>" : string(orig_s, send)));
}
if (state == ft_ordinary) {
assert(count != 0);
@@ -291,12 +293,93 @@ Name::Name(const std::string &namestring, bool downcase) {
ndata.push_back('\0');
}
}
+}
+
+}
+
+Name::Name(const std::string &namestring, bool downcase) {
+ // Prepare inputs for the parser
+ const std::string::const_iterator s = namestring.begin();
+ const std::string::const_iterator send = namestring.end();
+
+ // Prepare outputs
+ NameOffsets offsets;
+ NameString ndata;
+
+ // To the parsing
+ stringParse(s, send, downcase, offsets, ndata);
+
+ // And get the output
+ labelcount_ = offsets.size();
+ assert(labelcount_ > 0 && labelcount_ <= Name::MAX_LABELS);
+ ndata_.assign(ndata.data(), ndata.size());
+ length_ = ndata_.size();
+ offsets_.assign(offsets.begin(), offsets.end());
+}
+
+Name::Name(const char* namedata, size_t data_len, const Name* origin,
+ bool downcase)
+{
+ // Check validity of data
+ if (namedata == NULL || data_len == 0) {
+ isc_throw(isc::InvalidParameter,
+ "No data provided to Name constructor");
+ }
+ // If the last character is not a dot, it is a relative to origin.
+ // It is safe to check now, we know there's at least one character.
+ const bool absolute = (namedata[data_len - 1] == '.');
+ // If we are not absolute, we need the origin to complete the name.
+ if (!absolute && origin == NULL) {
+ isc_throw(MissingNameOrigin,
+ "No origin available and name is relative");
+ }
+ // Prepare inputs for the parser
+ const char* end = namedata + data_len;
+
+ // Prepare outputs
+ NameOffsets offsets;
+ NameString ndata;
+
+ // Do the actual parsing
+ stringParse(namedata, end, downcase, offsets, ndata);
+ // Get the output
labelcount_ = offsets.size();
assert(labelcount_ > 0 && labelcount_ <= Name::MAX_LABELS);
ndata_.assign(ndata.data(), ndata.size());
length_ = ndata_.size();
offsets_.assign(offsets.begin(), offsets.end());
+
+ if (!absolute) {
+ // Now, extend the data with the ones from origin. But eat the
+ // last label (the empty one).
+
+ // Drop the last character of the data (the \0) and append a copy of
+ // the origin's data
+ ndata_.erase(ndata_.end() - 1);
+ ndata_.append(origin->ndata_);
+
+ // Do a similar thing with offsets. However, we need to move them
+ // so they point after the prefix we parsed before.
+ size_t offset = offsets_.back();
+ offsets_.pop_back();
+ size_t offset_count = offsets_.size();
+ offsets_.insert(offsets_.end(), origin->offsets_.begin(),
+ origin->offsets_.end());
+ for (NameOffsets::iterator it(offsets_.begin() + offset_count);
+ it != offsets_.end(); ++it) {
+ *it += offset;
+ }
+
+ // Adjust sizes.
+ length_ = ndata_.size();
+ labelcount_ = offsets_.size();
+
+ // And check the sizes are OK.
+ if (labelcount_ > Name::MAX_LABELS || length_ > Name::MAX_WIRE) {
+ isc_throw(TooLongName, "Combined name is too long");
+ }
+ }
}
namespace {
diff --git a/src/lib/dns/name.h b/src/lib/dns/name.h
index 261caee..02c868f 100644
--- a/src/lib/dns/name.h
+++ b/src/lib/dns/name.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NAME_H
-#define __NAME_H 1
+#ifndef NAME_H
+#define NAME_H 1
#include <stdint.h>
@@ -105,6 +105,17 @@ public:
NameParserException(file, line, what) {}
};
+/// \brief Thrown when origin is NULL and is needed.
+///
+/// The exception is thrown when the Name constructor for master file
+/// is used, the provided data is relative and the origin parameter is
+/// set to NULL.
+class MissingNameOrigin : public NameParserException {
+public:
+ MissingNameOrigin(const char* file, size_t line, const char* what) :
+ NameParserException(file, line, what) {}
+};
+
///
/// This is a supplemental class used only as a return value of
/// Name::compare() and LabelSequence::compare().
@@ -261,6 +272,37 @@ public:
/// \param namestr A string representation of the name to be constructed.
/// \param downcase Whether to convert upper case alphabets to lower case.
explicit Name(const std::string& namestr, bool downcase = false);
+
+ /// \brief Constructor for master file parser
+ ///
+ /// This acts similar to the above. But the data is passed as raw C-string
+ /// instead of wrapped-up C++ std::string.
+ ///
+ /// Also, when the origin is non-NULL and the name_data is not ending with
+ /// a dot, it is considered relative and the origin is appended to it.
+ ///
+ /// If the name_data is equal to "@", the content of origin is copied.
+ ///
+ /// \param name_data The raw data of the name.
+ /// \param data_len How many bytes in name_data is valid and considered
+ /// part of the name.
+ /// \param origin If non-NULL, it is taken as the origin to complete
+ /// relative names.
+ /// \param downcase Whether to convert upper case letters to lower case.
+ /// \throw NameParserException or any of its descendants in case the
+ /// input data is invalid.
+ /// \throw isc::InvalidParameter In case name_data is NULL or data_len is
+ /// 0.
+ /// \throw std::bad_alloc In case allocation fails.
+ /// \note This constructor is specially designed for the use of master
+ /// file parser. It mimics the behaviour of names in the master file
+ /// and accepts raw data. It is not recommended to be used by anything
+ /// else.
+ /// \todo Should we make it private and the parser a friend, to hide the
+ /// constructor?
+ Name(const char* name_data, size_t data_len, const Name* origin,
+ bool downcase = false);
+
/// Constructor from wire-format %data.
///
/// The \c buffer parameter normally stores a complete DNS message
@@ -724,7 +766,7 @@ operator<<(std::ostream& os, const Name& name);
}
}
-#endif // __NAME_H
+#endif // NAME_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/name_internal.h b/src/lib/dns/name_internal.h
index 8595df1..d60ee7a 100644
--- a/src/lib/dns/name_internal.h
+++ b/src/lib/dns/name_internal.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NAME_INTERNAL_H
-#define __NAME_INTERNAL_H 1
+#ifndef NAME_INTERNAL_H
+#define NAME_INTERNAL_H 1
// This is effectively a "private" namespace for the Name class implementation,
// but exposed publicly so the definitions in it can be shared with other
@@ -36,7 +36,7 @@ extern const uint8_t maptolower[];
} // end of name
} // end of dns
} // end of isc
-#endif // __NAME_INTERNAL_H
+#endif // NAME_INTERNAL_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/nsec3hash.h b/src/lib/dns/nsec3hash.h
index e082ee8..f1ca1a3 100644
--- a/src/lib/dns/nsec3hash.h
+++ b/src/lib/dns/nsec3hash.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NSEC3HASH_H
-#define __NSEC3HASH_H 1
+#ifndef NSEC3HASH_H
+#define NSEC3HASH_H 1
#include <string>
#include <vector>
@@ -276,7 +276,7 @@ void setNSEC3HashCreator(const NSEC3HashCreator* new_creator);
}
}
-#endif // __NSEC3HASH_H
+#endif // NSEC3HASH_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/opcode.h b/src/lib/dns/opcode.h
index dd88062..8e93877 100644
--- a/src/lib/dns/opcode.h
+++ b/src/lib/dns/opcode.h
@@ -18,8 +18,8 @@
#include <ostream>
-#ifndef __OPCODE_H
-#define __OPCODE_H 1
+#ifndef OPCODE_H
+#define OPCODE_H 1
namespace isc {
namespace dns {
diff --git a/src/lib/dns/python/edns_python.h b/src/lib/dns/python/edns_python.h
index 30d92ab..2106b22 100644
--- a/src/lib/dns/python/edns_python.h
+++ b/src/lib/dns/python/edns_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_EDNS_H
-#define __PYTHON_EDNS_H 1
+#ifndef PYTHON_EDNS_H
+#define PYTHON_EDNS_H 1
#include <Python.h>
@@ -57,7 +57,7 @@ const EDNS& PyEDNS_ToEDNS(const PyObject* edns_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_EDNS_H
+#endif // PYTHON_EDNS_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/message_python.h b/src/lib/dns/python/message_python.h
index be23890..f3c1488 100644
--- a/src/lib/dns/python/message_python.h
+++ b/src/lib/dns/python/message_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_MESSAGE_H
-#define __PYTHON_MESSAGE_H 1
+#ifndef PYTHON_MESSAGE_H
+#define PYTHON_MESSAGE_H 1
#include <Python.h>
@@ -33,7 +33,7 @@ extern PyTypeObject message_type;
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_MESSAGE_H
+#endif // PYTHON_MESSAGE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/messagerenderer_python.h b/src/lib/dns/python/messagerenderer_python.h
index ea9a940..f6ea922 100644
--- a/src/lib/dns/python/messagerenderer_python.h
+++ b/src/lib/dns/python/messagerenderer_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_MESSAGERENDERER_H
-#define __PYTHON_MESSAGERENDERER_H 1
+#ifndef PYTHON_MESSAGERENDERER_H
+#define PYTHON_MESSAGERENDERER_H 1
#include <Python.h>
@@ -50,7 +50,7 @@ MessageRenderer& PyMessageRenderer_ToMessageRenderer(PyObject* messagerenderer_o
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_MESSAGERENDERER_H
+#endif // PYTHON_MESSAGERENDERER_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/name_python.h b/src/lib/dns/python/name_python.h
index 86d7fd0..d18c0d9 100644
--- a/src/lib/dns/python/name_python.h
+++ b/src/lib/dns/python/name_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_NAME_H
-#define __PYTHON_NAME_H 1
+#ifndef PYTHON_NAME_H
+#define PYTHON_NAME_H 1
#include <Python.h>
@@ -74,7 +74,7 @@ const Name& PyName_ToName(const PyObject* name_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_NAME_H
+#endif // PYTHON_NAME_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/nsec3hash_python.h b/src/lib/dns/python/nsec3hash_python.h
index fa9b9b6..51a5fde 100644
--- a/src/lib/dns/python/nsec3hash_python.h
+++ b/src/lib/dns/python/nsec3hash_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_NSEC3HASH_H
-#define __PYTHON_NSEC3HASH_H 1
+#ifndef PYTHON_NSEC3HASH_H
+#define PYTHON_NSEC3HASH_H 1
#include <Python.h>
@@ -40,7 +40,7 @@ bool initModulePart_NSEC3Hash(PyObject* mod);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_NSEC3HASH_H
+#endif // PYTHON_NSEC3HASH_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/opcode_python.h b/src/lib/dns/python/opcode_python.h
index d0aec15..6e9967e 100644
--- a/src/lib/dns/python/opcode_python.h
+++ b/src/lib/dns/python/opcode_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_OPCODE_H
-#define __PYTHON_OPCODE_H 1
+#ifndef PYTHON_OPCODE_H
+#define PYTHON_OPCODE_H 1
#include <Python.h>
@@ -57,7 +57,7 @@ const Opcode& PyOpcode_ToOpcode(const PyObject* opcode_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_OPCODE_H
+#endif // PYTHON_OPCODE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/pydnspp_common.h b/src/lib/dns/python/pydnspp_common.h
index 3cc69c4..5ca1cd8 100644
--- a/src/lib/dns/python/pydnspp_common.h
+++ b/src/lib/dns/python/pydnspp_common.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LIBDNS_PYTHON_COMMON_H
-#define __LIBDNS_PYTHON_COMMON_H 1
+#ifndef LIBDNS_PYTHON_COMMON_H
+#define LIBDNS_PYTHON_COMMON_H 1
#include <Python.h>
@@ -106,7 +106,7 @@ convertToPyHash(HashvalType val) {
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __LIBDNS_PYTHON_COMMON_H
+#endif // LIBDNS_PYTHON_COMMON_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/pydnspp_towire.h b/src/lib/dns/python/pydnspp_towire.h
index e987a29..7ad70cd 100644
--- a/src/lib/dns/python/pydnspp_towire.h
+++ b/src/lib/dns/python/pydnspp_towire.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LIBDNS_PYTHON_TOWIRE_H
-#define __LIBDNS_PYTHON_TOWIRE_H 1
+#ifndef LIBDNS_PYTHON_TOWIRE_H
+#define LIBDNS_PYTHON_TOWIRE_H 1
#include <Python.h>
@@ -120,7 +120,7 @@ toWireWrapper(const PYSTRUCT* const self, PyObject* args) {
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __LIBDNS_PYTHON_TOWIRE_H
+#endif // LIBDNS_PYTHON_TOWIRE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/question_python.h b/src/lib/dns/python/question_python.h
index f5d78b1..99b37c7 100644
--- a/src/lib/dns/python/question_python.h
+++ b/src/lib/dns/python/question_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_QUESTION_H
-#define __PYTHON_QUESTION_H 1
+#ifndef PYTHON_QUESTION_H
+#define PYTHON_QUESTION_H 1
#include <Python.h>
@@ -59,7 +59,7 @@ const Question& PyQuestion_ToQuestion(const PyObject* question_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_QUESTION_H
+#endif // PYTHON_QUESTION_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/rcode_python.h b/src/lib/dns/python/rcode_python.h
index a149406..704821a 100644
--- a/src/lib/dns/python/rcode_python.h
+++ b/src/lib/dns/python/rcode_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_RCODE_H
-#define __PYTHON_RCODE_H 1
+#ifndef PYTHON_RCODE_H
+#define PYTHON_RCODE_H 1
#include <Python.h>
@@ -57,7 +57,7 @@ const Rcode& PyRcode_ToRcode(const PyObject* rcode_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_RCODE_H
+#endif // PYTHON_RCODE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/rdata_python.h b/src/lib/dns/python/rdata_python.h
index c7ddd57..6fa6631 100644
--- a/src/lib/dns/python/rdata_python.h
+++ b/src/lib/dns/python/rdata_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_RDATA_H
-#define __PYTHON_RDATA_H 1
+#ifndef PYTHON_RDATA_H
+#define PYTHON_RDATA_H 1
#include <Python.h>
@@ -61,7 +61,7 @@ const isc::dns::rdata::Rdata& PyRdata_ToRdata(const PyObject* rdata_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_RDATA_H
+#endif // PYTHON_RDATA_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/rrclass_python.h b/src/lib/dns/python/rrclass_python.h
index f58bba6..df5ca70 100644
--- a/src/lib/dns/python/rrclass_python.h
+++ b/src/lib/dns/python/rrclass_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_RRCLASS_H
-#define __PYTHON_RRCLASS_H 1
+#ifndef PYTHON_RRCLASS_H
+#define PYTHON_RRCLASS_H 1
#include <Python.h>
@@ -61,7 +61,7 @@ const RRClass& PyRRClass_ToRRClass(const PyObject* rrclass_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_RRCLASS_H
+#endif // PYTHON_RRCLASS_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/rrset_python.h b/src/lib/dns/python/rrset_python.h
index 2435397..9faac95 100644
--- a/src/lib/dns/python/rrset_python.h
+++ b/src/lib/dns/python/rrset_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_RRSET_H
-#define __PYTHON_RRSET_H 1
+#ifndef PYTHON_RRSET_H
+#define PYTHON_RRSET_H 1
#include <Python.h>
@@ -71,7 +71,7 @@ RRsetPtr PyRRset_ToRRsetPtr(PyObject* rrset_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_RRSET_H
+#endif // PYTHON_RRSET_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/rrttl_python.h b/src/lib/dns/python/rrttl_python.h
index 9dbc982..9ad904f 100644
--- a/src/lib/dns/python/rrttl_python.h
+++ b/src/lib/dns/python/rrttl_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_RRTTL_H
-#define __PYTHON_RRTTL_H 1
+#ifndef PYTHON_RRTTL_H
+#define PYTHON_RRTTL_H 1
#include <Python.h>
@@ -60,7 +60,7 @@ const RRTTL& PyRRTTL_ToRRTTL(const PyObject* rrttl_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_RRTTL_H
+#endif // PYTHON_RRTTL_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/rrtype_python.h b/src/lib/dns/python/rrtype_python.h
index 596598e..3595952 100644
--- a/src/lib/dns/python/rrtype_python.h
+++ b/src/lib/dns/python/rrtype_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_RRTYPE_H
-#define __PYTHON_RRTYPE_H 1
+#ifndef PYTHON_RRTYPE_H
+#define PYTHON_RRTYPE_H 1
#include <Python.h>
@@ -61,7 +61,7 @@ const RRType& PyRRType_ToRRType(const PyObject* rrtype_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_RRTYPE_H
+#endif // PYTHON_RRTYPE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/serial_python.h b/src/lib/dns/python/serial_python.h
index 48b5199..9a495be 100644
--- a/src/lib/dns/python/serial_python.h
+++ b/src/lib/dns/python/serial_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_SERIAL_H
-#define __PYTHON_SERIAL_H 1
+#ifndef PYTHON_SERIAL_H
+#define PYTHON_SERIAL_H 1
#include <Python.h>
@@ -57,7 +57,7 @@ const Serial& PySerial_ToSerial(const PyObject* Serial_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_SERIAL_H
+#endif // PYTHON_SERIAL_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/tsig_python.h b/src/lib/dns/python/tsig_python.h
index e4e9fff..0bd57d7 100644
--- a/src/lib/dns/python/tsig_python.h
+++ b/src/lib/dns/python/tsig_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_TSIGCONTEXT_H
-#define __PYTHON_TSIGCONTEXT_H 1
+#ifndef PYTHON_TSIGCONTEXT_H
+#define PYTHON_TSIGCONTEXT_H 1
#include <Python.h>
@@ -52,7 +52,7 @@ TSIGContext& PyTSIGContext_ToTSIGContext(PyObject* tsigcontext_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_TSIGCONTEXT_H
+#endif // PYTHON_TSIGCONTEXT_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/tsig_rdata_python.h b/src/lib/dns/python/tsig_rdata_python.h
index a84d9e8..85dd366 100644
--- a/src/lib/dns/python/tsig_rdata_python.h
+++ b/src/lib/dns/python/tsig_rdata_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_TSIG_H
-#define __PYTHON_TSIG_H 1
+#ifndef PYTHON_TSIG_H
+#define PYTHON_TSIG_H 1
#include <Python.h>
@@ -61,7 +61,7 @@ const rdata::any::TSIG& PyTSIG_ToTSIG(const PyObject* tsig_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_TSIG_H
+#endif // PYTHON_TSIG_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/tsigerror_python.h b/src/lib/dns/python/tsigerror_python.h
index 0b5b630..6258ab3 100644
--- a/src/lib/dns/python/tsigerror_python.h
+++ b/src/lib/dns/python/tsigerror_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_TSIGERROR_H
-#define __PYTHON_TSIGERROR_H 1
+#ifndef PYTHON_TSIGERROR_H
+#define PYTHON_TSIGERROR_H 1
#include <Python.h>
@@ -37,7 +37,7 @@ PyObject* createTSIGErrorObject(const TSIGError& source);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_TSIGERROR_H
+#endif // PYTHON_TSIGERROR_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/tsigkey_python.h b/src/lib/dns/python/tsigkey_python.h
index 6c3d2e3..ec09e2c 100644
--- a/src/lib/dns/python/tsigkey_python.h
+++ b/src/lib/dns/python/tsigkey_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_TSIGKEY_H
-#define __PYTHON_TSIGKEY_H 1
+#ifndef PYTHON_TSIGKEY_H
+#define PYTHON_TSIGKEY_H 1
#include <Python.h>
@@ -68,7 +68,7 @@ const TSIGKeyRing& PyTSIGKeyRing_ToTSIGKeyRing(const PyObject* tsigkeyring_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_TSIGKEY_H
+#endif // PYTHON_TSIGKEY_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/python/tsigrecord_python.h b/src/lib/dns/python/tsigrecord_python.h
index d6252e1..ec505f7 100644
--- a/src/lib/dns/python/tsigrecord_python.h
+++ b/src/lib/dns/python/tsigrecord_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_TSIGRECORD_H
-#define __PYTHON_TSIGRECORD_H 1
+#ifndef PYTHON_TSIGRECORD_H
+#define PYTHON_TSIGRECORD_H 1
#include <Python.h>
@@ -58,7 +58,7 @@ const TSIGRecord& PyTSIGRecord_ToTSIGRecord(PyObject* tsigrecord_obj);
} // namespace python
} // namespace dns
} // namespace isc
-#endif // __PYTHON_TSIGRECORD_H
+#endif // PYTHON_TSIGRECORD_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/question.h b/src/lib/dns/question.h
index 5d2783b..4b5b233 100644
--- a/src/lib/dns/question.h
+++ b/src/lib/dns/question.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __QUESTION_H
-#define __QUESTION_H 1
+#ifndef QUESTION_H
+#define QUESTION_H 1
#include <iostream>
#include <string>
@@ -288,7 +288,7 @@ private:
std::ostream& operator<<(std::ostream& os, const Question& question);
} // end of namespace dns
} // end of namespace isc
-#endif // __QUESTION_H
+#endif // QUESTION_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/rcode.h b/src/lib/dns/rcode.h
index 0c63285..f294615 100644
--- a/src/lib/dns/rcode.h
+++ b/src/lib/dns/rcode.h
@@ -18,8 +18,8 @@
#include <ostream>
-#ifndef __RCODE_H
-#define __RCODE_H 1
+#ifndef RCODE_H
+#define RCODE_H 1
namespace isc {
namespace dns {
diff --git a/src/lib/dns/rdata.h b/src/lib/dns/rdata.h
index afcf4b3..f77ea6e 100644
--- a/src/lib/dns/rdata.h
+++ b/src/lib/dns/rdata.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RDATA_H
-#define __RDATA_H 1
+#ifndef RDATA_H
+#define RDATA_H 1
#include <stdint.h>
@@ -509,7 +509,7 @@ int compareNames(const Name& n1, const Name& n2);
} // end of namespace "rdata"
}
}
-#endif // __RDATA_H
+#endif // RDATA_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/rdata/generic/detail/ds_like.h b/src/lib/dns/rdata/generic/detail/ds_like.h
index b5a35cd..333de4c 100644
--- a/src/lib/dns/rdata/generic/detail/ds_like.h
+++ b/src/lib/dns/rdata/generic/detail/ds_like.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __DS_LIKE_H
-#define __DS_LIKE_H 1
+#ifndef DS_LIKE_H
+#define DS_LIKE_H 1
#include <stdint.h>
@@ -218,7 +218,7 @@ private:
}
}
}
-#endif // __DS_LIKE_H
+#endif // DS_LIKE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/rdata/generic/detail/nsec3param_common.h b/src/lib/dns/rdata/generic/detail/nsec3param_common.h
index 515777b..1891fae 100644
--- a/src/lib/dns/rdata/generic/detail/nsec3param_common.h
+++ b/src/lib/dns/rdata/generic/detail/nsec3param_common.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NSEC3PARAM_COMMON_H
-#define __NSEC3PARAM_COMMON_H 1
+#ifndef NSEC3PARAM_COMMON_H
+#define NSEC3PARAM_COMMON_H 1
#include <util/buffer.h>
@@ -127,7 +127,7 @@ ParseNSEC3ParamResult parseNSEC3ParamWire(const char* const rrtype_name,
}
}
-#endif // __NSEC3PARAM_COMMON_H
+#endif // NSEC3PARAM_COMMON_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/rdata/generic/detail/nsec_bitmap.h b/src/lib/dns/rdata/generic/detail/nsec_bitmap.h
index 85cae2e..0b2102f 100644
--- a/src/lib/dns/rdata/generic/detail/nsec_bitmap.h
+++ b/src/lib/dns/rdata/generic/detail/nsec_bitmap.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NSECBITMAP_H
-#define __NSECBITMAP_H 1
+#ifndef NSECBITMAP_H
+#define NSECBITMAP_H 1
#include <stdint.h>
@@ -100,7 +100,7 @@ void bitmapsToText(const std::vector<uint8_t>& typebits,
}
}
-#endif // __NSECBITMAP_H
+#endif // NSECBITMAP_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/rdata/generic/detail/txt_like.h b/src/lib/dns/rdata/generic/detail/txt_like.h
index a0ab7ac..fdab6bf 100644
--- a/src/lib/dns/rdata/generic/detail/txt_like.h
+++ b/src/lib/dns/rdata/generic/detail/txt_like.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TXT_LIKE_H
-#define __TXT_LIKE_H 1
+#ifndef TXT_LIKE_H
+#define TXT_LIKE_H 1
#include <stdint.h>
@@ -217,7 +217,7 @@ private:
// END_RDATA_NAMESPACE
// END_ISC_NAMESPACE
-#endif // __TXT_LIKE_H
+#endif // TXT_LIKE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/rdatafields.h b/src/lib/dns/rdatafields.h
index 16880f0..efdc453 100644
--- a/src/lib/dns/rdatafields.h
+++ b/src/lib/dns/rdatafields.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RDATAFIELDS_H
-#define __RDATAFIELDS_H 1
+#ifndef RDATAFIELDS_H
+#define RDATAFIELDS_H 1
#include <stdint.h>
@@ -420,7 +420,7 @@ private:
}
}
}
-#endif // __RDATAFIELDS_H
+#endif // RDATAFIELDS_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/rrclass-placeholder.h b/src/lib/dns/rrclass-placeholder.h
index 80035d8..70d6b78 100644
--- a/src/lib/dns/rrclass-placeholder.h
+++ b/src/lib/dns/rrclass-placeholder.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RRCLASS_H
-#define __RRCLASS_H 1
+#ifndef RRCLASS_H
+#define RRCLASS_H 1
#include <stdint.h>
@@ -283,7 +283,7 @@ std::ostream&
operator<<(std::ostream& os, const RRClass& rrclass);
}
}
-#endif // __RRCLASS_H
+#endif // RRCLASS_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/rrparamregistry.h b/src/lib/dns/rrparamregistry.h
index ae41b5f..b1ca225 100644
--- a/src/lib/dns/rrparamregistry.h
+++ b/src/lib/dns/rrparamregistry.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RRPARAMREGISTRY_H
-#define __RRPARAMREGISTRY_H 1
+#ifndef RRPARAMREGISTRY_H
+#define RRPARAMREGISTRY_H 1
#include <string>
@@ -506,7 +506,7 @@ private:
}
}
-#endif // __RRPARAMREGISTRY_H
+#endif // RRPARAMREGISTRY_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/rrset.cc b/src/lib/dns/rrset.cc
index 17a02cd..7ea01d0 100644
--- a/src/lib/dns/rrset.cc
+++ b/src/lib/dns/rrset.cc
@@ -64,8 +64,12 @@ AbstractRRset::toText() const {
it->next();
} while (!it->isLast());
+ if (getRRsig()) {
+ s += getRRsig()->toText();
+ }
+
return (s);
-}
+}
namespace {
template <typename T>
diff --git a/src/lib/dns/rrset.h b/src/lib/dns/rrset.h
index 7019f93..9c1715b 100644
--- a/src/lib/dns/rrset.h
+++ b/src/lib/dns/rrset.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RRSET_H
-#define __RRSET_H 1
+#ifndef RRSET_H
+#define RRSET_H 1
#include <iostream>
#include <string>
@@ -267,6 +267,9 @@ public:
/// the resulting string with a trailing newline character.
/// (following the BIND9 convention)
///
+ /// If any RRSIGs are associated with the RRset, they are also
+ /// appended to the returned string.
+ ///
/// If the class is not ANY or NONE, the RRset must contain some RDATA;
/// otherwise, an exception of class \c EmptyRRset will be thrown.
/// If resource allocation fails, a corresponding standard exception
@@ -293,6 +296,8 @@ public:
/// RRset would cause truncation, and handles the case appropriately
/// (this is a TODO item, and not implemented in this version).
///
+ /// If any RRSIGs are associated with the RRset, they are also rendered.
+ ///
/// Note: perhaps we may want to add more arguments to convey optional
/// information such as an "rrset-order" policy or how to handle truncation
/// case. This is a TODO item.
@@ -929,7 +934,7 @@ private:
std::ostream& operator<<(std::ostream& os, const AbstractRRset& rrset);
} // end of namespace dns
} // end of namespace isc
-#endif // __RRSET_H
+#endif // RRSET_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/rrttl.h b/src/lib/dns/rrttl.h
index bf23295..62bf886 100644
--- a/src/lib/dns/rrttl.h
+++ b/src/lib/dns/rrttl.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RRTTL_H
-#define __RRTTL_H 1
+#ifndef RRTTL_H
+#define RRTTL_H 1
#include <stdint.h>
@@ -255,7 +255,7 @@ std::ostream&
operator<<(std::ostream& os, const RRTTL& rrttl);
}
}
-#endif // __RRTTL_H
+#endif // RRTTL_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/rrtype-placeholder.h b/src/lib/dns/rrtype-placeholder.h
index dad1b2b..273a486 100644
--- a/src/lib/dns/rrtype-placeholder.h
+++ b/src/lib/dns/rrtype-placeholder.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RRTYPE_H
-#define __RRTYPE_H 1
+#ifndef RRTYPE_H
+#define RRTYPE_H 1
#include <stdint.h>
@@ -235,11 +235,11 @@ public:
///
/// \param other the \c RRType object to compare against.
/// \return true if the two RRTypes are not equal; otherwise false.
- bool nequals(const RRType& other) const
+ bool nequals(const RRType& other) const
{ return (typecode_ != other.typecode_); }
/// \brief Same as \c nequals().
bool operator!=(const RRType& other) const { return (nequals(other)); }
-
+
/// \brief Less-than comparison for RRType against \c other
///
/// We define the less-than relationship based on their type codes;
@@ -317,8 +317,8 @@ std::ostream&
operator<<(std::ostream& os, const RRType& rrtype);
}
}
-#endif // __RRTYPE_H
+#endif // RRTYPE_H
-// Local Variables:
+// Local Variables:
// mode: c++
-// End:
+// End:
diff --git a/src/lib/dns/serial.h b/src/lib/dns/serial.h
index 3549860..678fb22 100644
--- a/src/lib/dns/serial.h
+++ b/src/lib/dns/serial.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __SERIAL_H
-#define __SERIAL_H 1
+#ifndef SERIAL_H
+#define SERIAL_H 1
#include <stdint.h>
#include <iostream>
@@ -152,4 +152,4 @@ std::ostream& operator<<(std::ostream& os, const Serial& serial);
} // end namespace dns
} // end namespace isc
-#endif // __SERIAL_H
+#endif // SERIAL_H
diff --git a/src/lib/dns/tests/Makefile.am b/src/lib/dns/tests/Makefile.am
index e8cbe10..6df0e62 100644
--- a/src/lib/dns/tests/Makefile.am
+++ b/src/lib/dns/tests/Makefile.am
@@ -24,6 +24,7 @@ run_unittests_SOURCES = unittest_util.h unittest_util.cc
run_unittests_SOURCES += edns_unittest.cc
run_unittests_SOURCES += labelsequence_unittest.cc
run_unittests_SOURCES += messagerenderer_unittest.cc
+run_unittests_SOURCES += master_lexer_token_unittest.cc
run_unittests_SOURCES += name_unittest.cc
run_unittests_SOURCES += nsec3hash_unittest.cc
run_unittests_SOURCES += rrclass_unittest.cc rrtype_unittest.cc
diff --git a/src/lib/dns/tests/master_lexer_token_unittest.cc b/src/lib/dns/tests/master_lexer_token_unittest.cc
new file mode 100644
index 0000000..a63b9ca
--- /dev/null
+++ b/src/lib/dns/tests/master_lexer_token_unittest.cc
@@ -0,0 +1,156 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <exceptions/exceptions.h>
+
+#include <dns/master_lexer.h>
+
+#include <gtest/gtest.h>
+
+#include <string>
+
+using namespace isc::dns;
+
+namespace {
+
+const char TEST_STRING[] = "string token";
+// This excludes the ending \0 character
+const size_t TEST_STRING_LEN = sizeof(TEST_STRING) - 1;
+
+class MasterLexerTokenTest : public ::testing::Test {
+protected:
+ MasterLexerTokenTest() :
+ token_eof(MasterLexer::Token::END_OF_FILE),
+ token_str(TEST_STRING, TEST_STRING_LEN),
+ token_num(42),
+ token_err(MasterLexer::Token::UNEXPECTED_END)
+ {}
+
+ const MasterLexer::Token token_eof; // an example of non-value type token
+ const MasterLexer::Token token_str;
+ const MasterLexer::Token token_num;
+ const MasterLexer::Token token_err;
+};
+
+
+TEST_F(MasterLexerTokenTest, strings) {
+ // basic construction and getter checks
+ EXPECT_EQ(MasterLexer::Token::STRING, token_str.getType());
+ EXPECT_EQ(std::string("string token"), token_str.getString());
+ const MasterLexer::Token::StringRegion str_region =
+ token_str.getStringRegion();
+ EXPECT_EQ(TEST_STRING, str_region.beg);
+ EXPECT_EQ(TEST_STRING_LEN, str_region.len);
+
+ // Even if the stored string contains a nul character (in this case,
+ // it happens to be at the end of the string, but could be in the middle),
+ // getString() should return a string object containing the nul.
+ std::string expected_str("string token");
+ expected_str.push_back('\0');
+ EXPECT_EQ(expected_str,
+ MasterLexer::Token(TEST_STRING, TEST_STRING_LEN + 1).getString());
+
+ // Construct type of qstring
+ EXPECT_EQ(MasterLexer::Token::QSTRING,
+ MasterLexer::Token(TEST_STRING, sizeof(TEST_STRING), true).
+ getType());
+ // if we explicitly set 'quoted' to false, it should be normal string
+ EXPECT_EQ(MasterLexer::Token::STRING,
+ MasterLexer::Token(TEST_STRING, sizeof(TEST_STRING), false).
+ getType());
+
+ // getString/StringRegion() aren't allowed for non string(-variant) types
+ EXPECT_THROW(token_eof.getString(), isc::InvalidOperation);
+ EXPECT_THROW(token_num.getString(), isc::InvalidOperation);
+ EXPECT_THROW(token_eof.getStringRegion(), isc::InvalidOperation);
+ EXPECT_THROW(token_num.getStringRegion(), isc::InvalidOperation);
+}
+
+TEST_F(MasterLexerTokenTest, numbers) {
+ EXPECT_EQ(42, token_num.getNumber());
+ EXPECT_EQ(MasterLexer::Token::NUMBER, token_num.getType());
+
+ // It's copyable and assignable.
+ MasterLexer::Token token(token_num);
+ EXPECT_EQ(42, token.getNumber());
+ EXPECT_EQ(MasterLexer::Token::NUMBER, token.getType());
+
+ token = token_num;
+ EXPECT_EQ(42, token.getNumber());
+ EXPECT_EQ(MasterLexer::Token::NUMBER, token.getType());
+
+ // it's okay to replace it with a different type of token
+ token = token_eof;
+ EXPECT_EQ(MasterLexer::Token::END_OF_FILE, token.getType());
+
+ // Possible max value
+ token = MasterLexer::Token(0xffffffff);
+ EXPECT_EQ(4294967295u, token.getNumber());
+
+ // getNumber() isn't allowed for non number types
+ EXPECT_THROW(token_eof.getNumber(), isc::InvalidOperation);
+ EXPECT_THROW(token_str.getNumber(), isc::InvalidOperation);
+}
+
+TEST_F(MasterLexerTokenTest, novalues) {
+ // Just checking we can construct them and getType() returns correct value.
+ EXPECT_EQ(MasterLexer::Token::END_OF_FILE, token_eof.getType());
+ EXPECT_EQ(MasterLexer::Token::END_OF_LINE,
+ MasterLexer::Token(MasterLexer::Token::END_OF_LINE).getType());
+ EXPECT_EQ(MasterLexer::Token::INITIAL_WS,
+ MasterLexer::Token(MasterLexer::Token::INITIAL_WS).getType());
+
+ // Special types of tokens cannot have value-based types
+ EXPECT_THROW(MasterLexer::Token t(MasterLexer::Token::STRING),
+ isc::InvalidParameter);
+ EXPECT_THROW(MasterLexer::Token t(MasterLexer::Token::QSTRING),
+ isc::InvalidParameter);
+ EXPECT_THROW(MasterLexer::Token t(MasterLexer::Token::NUMBER),
+ isc::InvalidParameter);
+ EXPECT_THROW(MasterLexer::Token t(MasterLexer::Token::ERROR),
+ isc::InvalidParameter);
+}
+
+TEST_F(MasterLexerTokenTest, errors) {
+ EXPECT_EQ(MasterLexer::Token::ERROR, token_err.getType());
+ EXPECT_EQ(MasterLexer::Token::UNEXPECTED_END, token_err.getErrorCode());
+ EXPECT_EQ("unexpected end of input", token_err.getErrorText());
+ EXPECT_EQ("lexer not started",
+ MasterLexer::Token(MasterLexer::Token::NOT_STARTED).
+ getErrorText());
+ EXPECT_EQ("unbalanced parentheses",
+ MasterLexer::Token(MasterLexer::Token::UNBALANCED_PAREN).
+ getErrorText());
+ EXPECT_EQ("unbalanced quotes",
+ MasterLexer::Token(MasterLexer::Token::UNBALANCED_QUOTES).
+ getErrorText());
+
+ // getErrorCode/Text() isn't allowed for non number types
+ EXPECT_THROW(token_num.getErrorCode(), isc::InvalidOperation);
+ EXPECT_THROW(token_num.getErrorText(), isc::InvalidOperation);
+
+ // Only the pre-defined error code is accepted. Hardcoding '4' (max code
+ // + 1) is intentional; it'd be actually better if we notice it when we
+ // update the enum list (which shouldn't happen too often).
+ EXPECT_THROW(MasterLexer::Token(MasterLexer::Token::ErrorCode(4)),
+ isc::InvalidParameter);
+
+ // Check the coexistence of "from number" and "from error-code"
+ // constructors won't cause confusion.
+ EXPECT_EQ(MasterLexer::Token::NUMBER,
+ MasterLexer::Token(static_cast<uint32_t>(
+ MasterLexer::Token::NOT_STARTED)).
+ getType());
+}
+}
diff --git a/src/lib/dns/tests/name_unittest.cc b/src/lib/dns/tests/name_unittest.cc
index c327bdc..10d1e55 100644
--- a/src/lib/dns/tests/name_unittest.cc
+++ b/src/lib/dns/tests/name_unittest.cc
@@ -40,6 +40,22 @@ using namespace isc::util;
const size_t Name::MAX_WIRE;
const size_t Name::MAX_LABELS;
+// This is a name of maximum allowed number of labels
+const char* max_labels_str = "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 40
+ "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 80
+ "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 120
+ "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 160
+ "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 200
+ "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 240
+ "0.1.2.3.4.5.6";
+// This is a name of maximum allowed length
+const char* max_len_str = "123456789.123456789.123456789.123456789.123456789."
+ "123456789.123456789.123456789.123456789.123456789."
+ "123456789.123456789.123456789.123456789.123456789."
+ "123456789.123456789.123456789.123456789.123456789."
+ "123456789.123456789.123456789.123456789.123456789."
+ "123";
+
namespace {
class NameTest : public ::testing::Test {
protected:
@@ -47,6 +63,8 @@ protected:
example_name_upper("WWW.EXAMPLE.COM"),
small_name("aaa.example.com"),
large_name("zzz.example.com"),
+ origin_name("example.com."),
+ origin_name_upper("EXAMPLE.COM"),
buffer_actual(0), buffer_expected(0)
{}
@@ -54,6 +72,8 @@ protected:
Name example_name_upper; // this will be modified and cannot be const
const Name small_name;
const Name large_name;
+ const Name origin_name;
+ const Name origin_name_upper;
OutputBuffer buffer_actual, buffer_expected;
//
@@ -137,6 +157,11 @@ checkBadTextName(const string& txt) {
// NameParserException.
EXPECT_THROW(Name(txt, false), ExceptionType);
EXPECT_THROW(Name(txt, false), NameParserException);
+ // The same is thrown when constructing by the master-file constructor
+ EXPECT_THROW(Name(txt.c_str(), txt.length(), &Name::ROOT_NAME()),
+ ExceptionType);
+ EXPECT_THROW(Name(txt.c_str(), txt.length(), &Name::ROOT_NAME()),
+ NameParserException);
}
TEST_F(NameTest, fromText) {
@@ -201,27 +226,99 @@ TEST_F(NameTest, fromText) {
"123456789.123456789.123456789.123456789."
"123456789.1234");
// This is a possible longest name and should be accepted
- EXPECT_NO_THROW(Name("123456789.123456789.123456789.123456789.123456789."
- "123456789.123456789.123456789.123456789.123456789."
- "123456789.123456789.123456789.123456789.123456789."
- "123456789.123456789.123456789.123456789.123456789."
- "123456789.123456789.123456789.123456789.123456789."
- "123"));
+ EXPECT_NO_THROW(Name(string(max_len_str)));
// \DDD must consist of 3 digits.
checkBadTextName<IncompleteName>("\\12");
// a name with the max number of labels. should be constructed without
// an error, and its length should be the max value.
- Name maxlabels = Name("0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 40
- "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 80
- "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 120
- "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 160
- "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 200
- "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 240
- "0.1.2.3.4.5.6.");
+ Name maxlabels = Name(string(max_labels_str));
EXPECT_EQ(Name::MAX_LABELS, maxlabels.getLabelCount());
}
+// on the rest while we prepare it.
+// Check the @ syntax is accepted and it just copies the origin.
+TEST_F(NameTest, copyOrigin) {
+ EXPECT_EQ(origin_name, Name("@", 1, &origin_name));
+ // The downcase works on the origin too. But only when we provide it.
+ EXPECT_EQ(origin_name, Name("@", 1, &origin_name_upper, true));
+ EXPECT_EQ(origin_name_upper, Name("@", 1, &origin_name_upper, true));
+ // If we don't provide the origin, it throws
+ EXPECT_THROW(Name("@", 1, NULL), MissingNameOrigin);
+}
+
+// Test the master-file constructor does not append the origin when the
+// provided name is absolute
+TEST_F(NameTest, dontAppendOrigin) {
+ EXPECT_EQ(example_name, Name("www.example.com.", 16, &origin_name));
+ // The downcase works (only if provided, though)
+ EXPECT_EQ(example_name, Name("WWW.EXAMPLE.COM.", 16, &origin_name, true));
+ EXPECT_EQ(example_name_upper, Name("WWW.EXAMPLE.COM.", 16, &origin_name));
+ // And it does not require the origin to be provided
+ EXPECT_NO_THROW(Name("www.example.com.", 16, NULL));
+}
+
+// Test the master-file constructor properly appends the origin when
+// the provided name is relative.
+TEST_F(NameTest, appendOrigin) {
+ EXPECT_EQ(example_name, Name("www", 3, &origin_name));
+ // Check the downcase works (if provided)
+ EXPECT_EQ(example_name, Name("WWW", 3, &origin_name, true));
+ EXPECT_EQ(example_name, Name("WWW", 3, &origin_name_upper, true));
+ EXPECT_EQ(example_name_upper, Name("WWW", 3, &origin_name_upper));
+ // Check we can prepend more than one label
+ EXPECT_EQ(Name("a.b.c.d.example.com."), Name("a.b.c.d", 7, &origin_name));
+ // When the name is relative, we throw.
+ EXPECT_THROW(Name("www", 3, NULL), MissingNameOrigin);
+}
+
+// When we don't provide the data, it throws
+TEST_F(NameTest, noDataProvided) {
+ EXPECT_THROW(Name(NULL, 10, NULL), isc::InvalidParameter);
+ EXPECT_THROW(Name(NULL, 10, &origin_name), isc::InvalidParameter);
+ EXPECT_THROW(Name("www", 0, NULL), isc::InvalidParameter);
+ EXPECT_THROW(Name("www", 0, &origin_name), isc::InvalidParameter);
+}
+
+// When we combine the first part and the origin together, the resulting name
+// is too long. It should throw. Other test checks this is valid when alone
+// (without the origin appended).
+TEST_F(NameTest, combinedTooLong) {
+ EXPECT_THROW(Name(max_len_str, strlen(max_len_str), &origin_name),
+ TooLongName);
+ EXPECT_THROW(Name(max_labels_str, strlen(max_labels_str), &origin_name),
+ TooLongName);
+ // Appending the root should be OK
+ EXPECT_NO_THROW(Name(max_len_str, strlen(max_len_str),
+ &Name::ROOT_NAME()));
+ EXPECT_NO_THROW(Name(max_labels_str, strlen(max_labels_str),
+ &Name::ROOT_NAME()));
+}
+
+// Test the handling of @ in the name. If it is alone, it is the origin (when
+// it exists) or the root. If it is somewhere else, it has no special meaning.
+TEST_F(NameTest, atSign) {
+ // If it is alone, it is the origin
+ EXPECT_EQ(origin_name, Name("@", 1, &origin_name));
+ EXPECT_THROW(Name("@", 1, NULL), MissingNameOrigin);
+ EXPECT_EQ(Name::ROOT_NAME(), Name("@"));
+
+ // It is not alone. It is taken verbatim. We check the name converted
+ // back to the textual form, since checking it agains other name object
+ // may be wrong -- if we create it wrong the same way as the tested
+ // object.
+ EXPECT_EQ("\\@.", Name("@.").toText());
+ EXPECT_EQ("\\@.", Name("@.", 2, NULL).toText());
+ EXPECT_EQ("\\@something.", Name("@something").toText());
+ EXPECT_EQ("something\\@.", Name("something@").toText());
+ EXPECT_EQ("\\@x.example.com.", Name("@x", 2, &origin_name).toText());
+ EXPECT_EQ("x\\@.example.com.", Name("x@", 2, &origin_name).toText());
+
+ // An escaped at-sign isn't active
+ EXPECT_EQ("\\@.", Name("\\@").toText());
+ EXPECT_EQ("\\@.example.com.", Name("\\@", 2, &origin_name).toText());
+}
+
TEST_F(NameTest, fromWire) {
//
// test cases derived from BIND9 tests.
@@ -520,7 +617,6 @@ TEST_F(NameTest, downcase) {
// confirm the calling object is actually modified
example_name_upper.downcase();
compareInWireFormat(example_name_upper, example_name);
-
}
TEST_F(NameTest, at) {
diff --git a/src/lib/dns/tests/rdata_unittest.h b/src/lib/dns/tests/rdata_unittest.h
index 1bc0fa4..f593609 100644
--- a/src/lib/dns/tests/rdata_unittest.h
+++ b/src/lib/dns/tests/rdata_unittest.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RDATA_UNITTEST_H
-#define __RDATA_UNITTEST_H 1
+#ifndef RDATA_UNITTEST_H
+#define RDATA_UNITTEST_H 1
#include <util/buffer.h>
#include <dns/messagerenderer.h>
@@ -44,7 +44,7 @@ protected:
}
}
}
-#endif // __RDATA_UNITTEST_H
+#endif // RDATA_UNITTEST_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/tests/rrset_unittest.cc b/src/lib/dns/tests/rrset_unittest.cc
index 5596bcb..725eea7 100644
--- a/src/lib/dns/tests/rrset_unittest.cc
+++ b/src/lib/dns/tests/rrset_unittest.cc
@@ -359,4 +359,12 @@ TEST_F(RRsetRRSIGTest, getRRsigDataCount) {
rrset_a->removeRRsig();
EXPECT_EQ(0, rrset_a->getRRsigDataCount());
}
+
+TEST_F(RRsetRRSIGTest, toText) {
+ // toText() should also return the associated RRSIG.
+ EXPECT_EQ("test.example.com. 3600 IN AAAA 2001:db8::1234\n"
+ "test.example.com. 3600 IN RRSIG AAAA 5 3 7200 "
+ "20100322084538 20100220084538 1 example.com. FAKEFAKEFAKEFAKE\n",
+ rrset_aaaa->toText());
+}
}
diff --git a/src/lib/dns/tests/unittest_util.h b/src/lib/dns/tests/unittest_util.h
index ebb514d..f50df14 100644
--- a/src/lib/dns/tests/unittest_util.h
+++ b/src/lib/dns/tests/unittest_util.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __UNITTEST_UTIL_H
-#define __UNITTEST_UTIL_H 1
+#ifndef UNITTEST_UTIL_H
+#define UNITTEST_UTIL_H 1
#include <vector>
#include <string>
@@ -111,7 +111,7 @@ public:
};
}
-#endif // __UNITTEST_UTIL_H
+#endif // UNITTEST_UTIL_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/tsig.h b/src/lib/dns/tsig.h
index 9ccc580..a7ec011 100644
--- a/src/lib/dns/tsig.h
+++ b/src/lib/dns/tsig.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TSIG_H
-#define __TSIG_H 1
+#ifndef TSIG_H
+#define TSIG_H 1
#include <boost/noncopyable.hpp>
@@ -433,7 +433,7 @@ private:
}
}
-#endif // __TSIG_H
+#endif // TSIG_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/tsigerror.h b/src/lib/dns/tsigerror.h
index 8efd3ae..5b8056d 100644
--- a/src/lib/dns/tsigerror.h
+++ b/src/lib/dns/tsigerror.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TSIGERROR_H
-#define __TSIGERROR_H 1
+#ifndef TSIGERROR_H
+#define TSIGERROR_H 1
#include <ostream>
#include <string>
@@ -331,7 +331,7 @@ std::ostream& operator<<(std::ostream& os, const TSIGError& tsig_error);
}
}
-#endif // __TSIGERROR_H
+#endif // TSIGERROR_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/tsigkey.h b/src/lib/dns/tsigkey.h
index 6081dd3..1bbd3fe 100644
--- a/src/lib/dns/tsigkey.h
+++ b/src/lib/dns/tsigkey.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TSIGKEY_H
-#define __TSIGKEY_H 1
+#ifndef TSIGKEY_H
+#define TSIGKEY_H 1
#include <cryptolink/cryptolink.h>
@@ -353,7 +353,7 @@ private:
}
}
-#endif // __TSIGKEY_H
+#endif // TSIGKEY_H
// Local Variables:
// mode: c++
diff --git a/src/lib/dns/tsigrecord.h b/src/lib/dns/tsigrecord.h
index 03de746..b5e8de3 100644
--- a/src/lib/dns/tsigrecord.h
+++ b/src/lib/dns/tsigrecord.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TSIGRECORD_H
-#define __TSIGRECORD_H 1
+#ifndef TSIGRECORD_H
+#define TSIGRECORD_H 1
#include <ostream>
#include <string>
@@ -301,7 +301,7 @@ std::ostream& operator<<(std::ostream& os, const TSIGRecord& record);
}
}
-#endif // __TSIGRECORD_H
+#endif // TSIGRECORD_H
// Local Variables:
// mode: c++
diff --git a/src/lib/exceptions/exceptions.h b/src/lib/exceptions/exceptions.h
index 010fd39..d7e270d 100644
--- a/src/lib/exceptions/exceptions.h
+++ b/src/lib/exceptions/exceptions.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __EXCEPTIONS_H
-#define __EXCEPTIONS_H 1
+#ifndef EXCEPTIONS_H
+#define EXCEPTIONS_H 1
#include <stdexcept>
#include <string>
@@ -230,7 +230,7 @@ public:
} while (1)
}
-#endif // __EXCEPTIONS_H
+#endif // EXCEPTIONS_H
// Local Variables:
// mode: c++
diff --git a/src/lib/log/compiler/message.cc b/src/lib/log/compiler/message.cc
index ef62b2f..7bff8bd 100644
--- a/src/lib/log/compiler/message.cc
+++ b/src/lib/log/compiler/message.cc
@@ -122,7 +122,7 @@ currentTime() {
/// \brief Create Header Sentinel
///
/// Given the name of a file, create an \#ifdef sentinel name. The name is
-/// __<name>_<ext>, where <name> is the name of the file, and <ext>
+/// <name>_<ext>, where <name> is the name of the file, and <ext>
/// is the extension less the leading period. The sentinel will be upper-case.
///
/// \param file Filename object representing the file.
@@ -134,7 +134,7 @@ sentinel(Filename& file) {
string name = file.name();
string ext = file.extension();
- string sentinel_text = "__" + name + "_" + ext.substr(1);
+ string sentinel_text = name + "_" + ext.substr(1);
isc::util::str::uppercase(sentinel_text);
return (sentinel_text);
}
diff --git a/src/lib/log/dummylog.h b/src/lib/log/dummylog.h
index ef5af13..6f6ae97 100644
--- a/src/lib/log/dummylog.h
+++ b/src/lib/log/dummylog.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef _ISC_DUMMYLOG_H
-#define _ISC_DUMMYLOG_H 1
+#ifndef ISC_DUMMYLOG_H
+#define ISC_DUMMYLOG_H 1
#include <string>
@@ -58,4 +58,4 @@ void dlog(const std::string& message, bool error_flag=false);
}
}
-#endif // _ISC_DUMMYLOG_H
+#endif // ISC_DUMMYLOG_H
diff --git a/src/lib/log/log_dbglevels.h b/src/lib/log/log_dbglevels.h
index d713714..a459bed 100644
--- a/src/lib/log/log_dbglevels.h
+++ b/src/lib/log/log_dbglevels.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOG_DBGLVLS_H
-#define __LOG_DBGLVLS_H
+#ifndef LOG_DBGLVLS_H
+#define LOG_DBGLVLS_H
/// \file
///
@@ -90,4 +90,4 @@ const int DBGLVL_TRACE_DETAIL_DATA = 55;
} // Anonymous namespace
-#endif // __LOG_DBGLVLS_H
+#endif // LOG_DBGLVLS_H
diff --git a/src/lib/log/log_formatter.h b/src/lib/log/log_formatter.h
index eebdb1a..8cb34c7 100644
--- a/src/lib/log/log_formatter.h
+++ b/src/lib/log/log_formatter.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOG_FORMATTER_H
-#define __LOG_FORMMATER_H
+#ifndef LOG_FORMATTER_H
+#define LOG_FORMATTER_H
#include <cstddef>
#include <string>
diff --git a/src/lib/log/log_messages.h b/src/lib/log/log_messages.h
index 10e1501..2b70553 100644
--- a/src/lib/log/log_messages.h
+++ b/src/lib/log/log_messages.h
@@ -1,7 +1,7 @@
// File created from log_messages.mes on Thu Jul 7 15:32:06 2011
-#ifndef __LOG_MESSAGES_H
-#define __LOG_MESSAGES_H
+#ifndef LOG_MESSAGES_H
+#define LOG_MESSAGES_H
#include <log/message_types.h>
@@ -32,4 +32,4 @@ extern const isc::log::MessageID LOG_WRITE_ERROR;
} // namespace log
} // namespace isc
-#endif // __LOG_MESSAGES_H
+#endif // LOG_MESSAGES_H
diff --git a/src/lib/log/logger.h b/src/lib/log/logger.h
index 4291eae..e3ba163 100644
--- a/src/lib/log/logger.h
+++ b/src/lib/log/logger.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOGGER_H
-#define __LOGGER_H
+#ifndef LOGGER_H
+#define LOGGER_H
#include <cassert>
#include <cstdlib>
@@ -320,4 +320,4 @@ private:
} // namespace isc
-#endif // __LOGGER_H
+#endif // LOGGER_H
diff --git a/src/lib/log/logger_impl.h b/src/lib/log/logger_impl.h
index 10d3db4..7280d5c 100644
--- a/src/lib/log/logger_impl.h
+++ b/src/lib/log/logger_impl.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOGGER_IMPL_H
-#define __LOGGER_IMPL_H
+#ifndef LOGGER_IMPL_H
+#define LOGGER_IMPL_H
#include <stdarg.h>
#include <time.h>
@@ -200,4 +200,4 @@ private:
} // namespace isc
-#endif // __LOGGER_IMPL_H
+#endif // LOGGER_IMPL_H
diff --git a/src/lib/log/logger_level.h b/src/lib/log/logger_level.h
index ea60c3c..ac4a61a 100644
--- a/src/lib/log/logger_level.h
+++ b/src/lib/log/logger_level.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOGGER_LEVEL_H
-#define __LOGGER_LEVEL_H
+#ifndef LOGGER_LEVEL_H
+#define LOGGER_LEVEL_H
#include <string>
@@ -73,4 +73,4 @@ isc::log::Severity getSeverity(const std::string& sev_str);
} // namespace log
} // namespace isc
-#endif // __LOGGER_LEVEL_H
+#endif // LOGGER_LEVEL_H
diff --git a/src/lib/log/logger_level_impl.h b/src/lib/log/logger_level_impl.h
index 17b866d..4e18e46 100644
--- a/src/lib/log/logger_level_impl.h
+++ b/src/lib/log/logger_level_impl.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOGGER_LEVEL_IMPL_H
-#define __LOGGER_LEVEL_IMPL_H
+#ifndef LOGGER_LEVEL_IMPL_H
+#define LOGGER_LEVEL_IMPL_H
#include <log4cplus/logger.h>
#include <log4cplus/version.h>
@@ -131,4 +131,4 @@ public:
} // namespace log
} // namespace isc
-#endif // __LOGGER_LEVEL_IMPL_H
+#endif // LOGGER_LEVEL_IMPL_H
diff --git a/src/lib/log/logger_manager.h b/src/lib/log/logger_manager.h
index dece0c9..63699c9 100644
--- a/src/lib/log/logger_manager.h
+++ b/src/lib/log/logger_manager.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOGGER_MANAGER_H
-#define __LOGGER_MANAGER_H
+#ifndef LOGGER_MANAGER_H
+#define LOGGER_MANAGER_H
#include "exceptions/exceptions.h"
#include <log/logger_specification.h>
@@ -138,4 +138,4 @@ private:
} // namespace isc
-#endif // __LOGGER_MANAGER_H
+#endif // LOGGER_MANAGER_H
diff --git a/src/lib/log/logger_manager_impl.h b/src/lib/log/logger_manager_impl.h
index 42a98f1..2bce655 100644
--- a/src/lib/log/logger_manager_impl.h
+++ b/src/lib/log/logger_manager_impl.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOGGER_MANAGER_IMPL_H
-#define __LOGGER_MANAGER_IMPL_H
+#ifndef LOGGER_MANAGER_IMPL_H
+#define LOGGER_MANAGER_IMPL_H
#include <string>
@@ -166,4 +166,4 @@ private:
} // namespace log
} // namespace isc
-#endif // __LOGGER_MANAGER_IMPL_H
+#endif // LOGGER_MANAGER_IMPL_H
diff --git a/src/lib/log/logger_name.h b/src/lib/log/logger_name.h
index 82ea2ad..b9ebd1b 100644
--- a/src/lib/log/logger_name.h
+++ b/src/lib/log/logger_name.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOGGER_NAME_H
-#define __LOGGER_NAME_H
+#ifndef LOGGER_NAME_H
+#define LOGGER_NAME_H
#include <string>
@@ -54,4 +54,4 @@ std::string expandLoggerName(const std::string& name);
}
}
-#endif // __LOGGER_NAME_H
+#endif // LOGGER_NAME_H
diff --git a/src/lib/log/logger_specification.h b/src/lib/log/logger_specification.h
index 78df054..663b0df 100644
--- a/src/lib/log/logger_specification.h
+++ b/src/lib/log/logger_specification.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOGGER_SPECIFICATION_H
-#define __LOGGER_SPECIFICATION_H
+#ifndef LOGGER_SPECIFICATION_H
+#define LOGGER_SPECIFICATION_H
#include <stdint.h>
#include <stdlib.h>
@@ -146,11 +146,11 @@ private:
std::string name_; ///< Logger name
isc::log::Severity severity_; ///< Severity for this logger
int dbglevel_; ///< Debug level
- bool additive_; ///< Chaining output
+ bool additive_; ///< Chaining output
std::vector<OutputOption> options_; ///< Logger options
};
} // namespace log
} // namespace isc
-#endif // __LOGGER_SPEC_IFICATIONH
+#endif // LOGGER_SPECIFICATION_H
diff --git a/src/lib/log/logger_support.h b/src/lib/log/logger_support.h
index 4ce3ced..f59be60 100644
--- a/src/lib/log/logger_support.h
+++ b/src/lib/log/logger_support.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOGGER_SUPPORT_H
-#define __LOGGER_SUPPORT_H
+#ifndef LOGGER_SUPPORT_H
+#define LOGGER_SUPPORT_H
#include <unistd.h>
@@ -68,4 +68,4 @@ void initLogger(const std::string& root,
} // namespace log
} // namespace isc
-#endif // __LOGGER_SUPPORT_H
+#endif // LOGGER_SUPPORT_H
diff --git a/src/lib/log/logger_unittest_support.h b/src/lib/log/logger_unittest_support.h
index ce9121b..70f34e8 100644
--- a/src/lib/log/logger_unittest_support.h
+++ b/src/lib/log/logger_unittest_support.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOGGER_UNITTEST_SUPPORT_H
-#define __LOGGER_UNITTEST_SUPPORT_H
+#ifndef LOGGER_UNITTEST_SUPPORT_H
+#define LOGGER_UNITTEST_SUPPORT_H
#include <string>
#include <log/logger.h>
@@ -123,4 +123,4 @@ resetUnitTestRootLogger();
-#endif // __LOGGER_UNITTEST_SUPPORT_H
+#endif // LOGGER_UNITTEST_SUPPORT_H
diff --git a/src/lib/log/logimpl_messages.h b/src/lib/log/logimpl_messages.h
index 1b94838..71a50d6 100644
--- a/src/lib/log/logimpl_messages.h
+++ b/src/lib/log/logimpl_messages.h
@@ -1,7 +1,7 @@
// File created from logimpl_messages.mes on Wed Jun 22 10:57:02 2011
-#ifndef __LOGIMPL_MESSAGES_H
-#define __LOGIMPL_MESSAGES_H
+#ifndef LOGIMPL_MESSAGES_H
+#define LOGIMPL_MESSAGES_H
#include <log/message_types.h>
@@ -15,4 +15,4 @@ extern const isc::log::MessageID LOGIMPL_BELOW_MIN_DEBUG;
} // namespace log
} // namespace isc
-#endif // __LOGIMPL_MESSAGES_H
+#endif // LOGIMPL_MESSAGES_H
diff --git a/src/lib/log/macros.h b/src/lib/log/macros.h
index 42fb42e..f602555 100644
--- a/src/lib/log/macros.h
+++ b/src/lib/log/macros.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOG_MACROS_H
-#define __LOG_MACROS_H
+#ifndef LOG_MACROS_H
+#define LOG_MACROS_H
#include <log/logger.h>
#include <log/log_dbglevels.h>
diff --git a/src/lib/log/message_dictionary.h b/src/lib/log/message_dictionary.h
index 519986d..3d622cd 100644
--- a/src/lib/log/message_dictionary.h
+++ b/src/lib/log/message_dictionary.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MESSAGE_DICTIONARY_H
-#define __MESSAGE_DICTIONARY_H
+#ifndef MESSAGE_DICTIONARY_H
+#define MESSAGE_DICTIONARY_H
#include <cstddef>
#include <string>
@@ -187,4 +187,4 @@ private:
} // namespace log
} // namespace isc
-#endif // __MESSAGE_DICTIONARY_H
+#endif // MESSAGE_DICTIONARY_H
diff --git a/src/lib/log/message_exception.h b/src/lib/log/message_exception.h
index 8b9d58a..5f1ad12 100644
--- a/src/lib/log/message_exception.h
+++ b/src/lib/log/message_exception.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MESSAGE_EXCEPTION_H
-#define __MESSAGE_EXCEPTION_H
+#ifndef MESSAGE_EXCEPTION_H
+#define MESSAGE_EXCEPTION_H
#include <exceptions/exceptions.h>
#include <log/message_types.h>
@@ -117,4 +117,4 @@ private:
} // namespace log
} // namespace isc
-#endif // __MESSAGE_EXCEPTION_H
+#endif // MESSAGE_EXCEPTION_H
diff --git a/src/lib/log/message_initializer.h b/src/lib/log/message_initializer.h
index 28b0e61..3be973d 100644
--- a/src/lib/log/message_initializer.h
+++ b/src/lib/log/message_initializer.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MESSAGEINITIALIZER_H
-#define __MESSAGEINITIALIZER_H
+#ifndef MESSAGEINITIALIZER_H
+#define MESSAGEINITIALIZER_H
#include <cstdlib>
#include <string>
@@ -108,4 +108,4 @@ public:
} // namespace log
} // namespace isc
-#endif // __MESSAGEINITIALIZER_H
+#endif // MESSAGEINITIALIZER_H
diff --git a/src/lib/log/message_reader.h b/src/lib/log/message_reader.h
index a468d43..62d50b9 100644
--- a/src/lib/log/message_reader.h
+++ b/src/lib/log/message_reader.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MESSAGE_READER_H
-#define __MESSAGE_READER_H
+#ifndef MESSAGE_READER_H
+#define MESSAGE_READER_H
#include <map>
#include <string>
@@ -212,4 +212,4 @@ private:
} // namespace log
} // namespace isc
-#endif // __MESSAGE_READER_H
+#endif // MESSAGE_READER_H
diff --git a/src/lib/log/message_types.h b/src/lib/log/message_types.h
index 9f625a9..7966f98 100644
--- a/src/lib/log/message_types.h
+++ b/src/lib/log/message_types.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MESSAGE_TYPES_H
-#define __MESSAGE_TYPES_H
+#ifndef MESSAGE_TYPES_H
+#define MESSAGE_TYPES_H
#include <string.h>
@@ -34,4 +34,4 @@ bool equalMessageID(const MessageID& m1, const MessageID& m2);
-#endif // __MESSAGE_TYPES_H
+#endif // MESSAGE_TYPES_H
diff --git a/src/lib/log/output_option.h b/src/lib/log/output_option.h
index 8dfdd70..8dcb28d 100644
--- a/src/lib/log/output_option.h
+++ b/src/lib/log/output_option.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __OUTPUT_OPTION_H
-#define __OUTPUT_OPTION_H
+#ifndef OUTPUT_OPTION_H
+#define OUTPUT_OPTION_H
#include <stdint.h>
#include <stdlib.h>
@@ -82,4 +82,4 @@ OutputOption::Stream getStream(const std::string& stream_str);
} // namespace log
} // namespace isc
-#endif // __OUTPUT_OPTION_H
+#endif // OUTPUT_OPTION_H
diff --git a/src/lib/log/tests/tempdir.h.in b/src/lib/log/tests/tempdir.h.in
index 366fea3..96ce8d4 100644
--- a/src/lib/log/tests/tempdir.h.in
+++ b/src/lib/log/tests/tempdir.h.in
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TEMPDIR_H
-#define __TEMPDIR_H
+#ifndef TEMPDIR_H
+#define TEMPDIR_H
/// \brief Define temporary directory
///
@@ -26,4 +26,4 @@ namespace {
std::string TEMP_DIR("@builddir@");
}
-#endif // __TEMPDIR_H
+#endif // TEMPDIR_H
diff --git a/src/lib/nsas/address_entry.h b/src/lib/nsas/address_entry.h
index 8698017..0c165ea 100644
--- a/src/lib/nsas/address_entry.h
+++ b/src/lib/nsas/address_entry.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ADDRESS_ENTRY_H
-#define __ADDRESS_ENTRY_H
+#ifndef ADDRESS_ENTRY_H
+#define ADDRESS_ENTRY_H
/// \brief Address Entry
///
@@ -99,4 +99,4 @@ private:
} // namespace isc
-#endif // __ADDRESS_ENTRY_H
+#endif // ADDRESS_ENTRY_H
diff --git a/src/lib/nsas/address_request_callback.h b/src/lib/nsas/address_request_callback.h
index ad0630e..457c587 100644
--- a/src/lib/nsas/address_request_callback.h
+++ b/src/lib/nsas/address_request_callback.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ADDRESS_REQUEST_CALLBACK_H
-#define __ADDRESS_REQUEST_CALLBACK_H
+#ifndef ADDRESS_REQUEST_CALLBACK_H
+#define ADDRESS_REQUEST_CALLBACK_H
#include "asiolink.h"
#include "nameserver_address.h"
@@ -69,4 +69,4 @@ public:
} // namespace nsas
} // namespace isc
-#endif // __ADDRESS_REQUEST_CALLBACK_H
+#endif // ADDRESS_REQUEST_CALLBACK_H
diff --git a/src/lib/nsas/asiolink.h b/src/lib/nsas/asiolink.h
index d95868f..b236a0e 100644
--- a/src/lib/nsas/asiolink.h
+++ b/src/lib/nsas/asiolink.h
@@ -12,10 +12,10 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ASIOLINK_H
-#define __ASIOLINK_H
+#ifndef ASIOLINK_H
+#define ASIOLINK_H
#include <string>
#include <sys/socket.h>
-#endif // __ASIOLINK_H
+#endif // ASIOLINK_H
diff --git a/src/lib/nsas/fetchable.h b/src/lib/nsas/fetchable.h
index 461cfca..7e8ce5c 100644
--- a/src/lib/nsas/fetchable.h
+++ b/src/lib/nsas/fetchable.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __FETCHABLE_H
-#define __FETCHABLE_H
+#ifndef FETCHABLE_H
+#define FETCHABLE_H
/**
* \file fetchable.h
@@ -63,4 +63,4 @@ class Fetchable {
} // namespace nsas
} // namespace isc
-#endif // __FETCHABLE_H
+#endif // FETCHABLE_H
diff --git a/src/lib/nsas/glue_hints.h b/src/lib/nsas/glue_hints.h
index 8e6ecf1..ccac382 100644
--- a/src/lib/nsas/glue_hints.h
+++ b/src/lib/nsas/glue_hints.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __GLUE_HINTS_H
-#define __GLUE_HINTS_H
+#ifndef GLUE_HINTS_H
+#define GLUE_HINTS_H
#include <vector>
@@ -68,4 +68,4 @@ private:
}
-#endif // __GLUE_HINTS_H
+#endif // GLUE_HINTS_H
diff --git a/src/lib/nsas/hash.h b/src/lib/nsas/hash.h
index 85b82c3..cc03b3f 100644
--- a/src/lib/nsas/hash.h
+++ b/src/lib/nsas/hash.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __HASH_H
-#define __HASH_H
+#ifndef HASH_H
+#define HASH_H
#include <stdint.h>
#include <vector>
@@ -122,4 +122,4 @@ private:
} // namspace nsas
} // namespace isc
-#endif // __HASH_H
+#endif // HASH_H
diff --git a/src/lib/nsas/hash_deleter.h b/src/lib/nsas/hash_deleter.h
index 27f066e..6fcd3da 100644
--- a/src/lib/nsas/hash_deleter.h
+++ b/src/lib/nsas/hash_deleter.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __HASH_DELETER_H
-#define __HASH_DELETER_H
+#ifndef HASH_DELETER_H
+#define HASH_DELETER_H
#include <boost/shared_ptr.hpp>
#include <util/lru_list.h>
@@ -72,4 +72,4 @@ void HashDeleter<T>::operator()(T* element) const {
} // namespace nsas
} // namespace isc
-#endif // __HASH_DELETER_H
+#endif // HASH_DELETER_H
diff --git a/src/lib/nsas/hash_key.h b/src/lib/nsas/hash_key.h
index c89b327..5f60735 100644
--- a/src/lib/nsas/hash_key.h
+++ b/src/lib/nsas/hash_key.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __HASH_KEY_H
-#define __HASH_KEY_H
+#ifndef HASH_KEY_H
+#define HASH_KEY_H
#include <dns/rrclass.h>
@@ -93,4 +93,4 @@ struct HashKey {
} // namespace nsas
} // namespace isc
-#endif // __HASH_KEY_H
+#endif // HASH_KEY_H
diff --git a/src/lib/nsas/hash_table.h b/src/lib/nsas/hash_table.h
index 6028473..13cafc7 100644
--- a/src/lib/nsas/hash_table.h
+++ b/src/lib/nsas/hash_table.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __HASH_TABLE_H
-#define __HASH_TABLE_H
+#ifndef HASH_TABLE_H
+#define HASH_TABLE_H
#include <list>
@@ -334,4 +334,4 @@ bool HashTable<T>::addInternal(boost::shared_ptr<T>& object,
} // namespace nsas
} // namespace isc
-#endif // __HASH_TABLE_H
+#endif // HASH_TABLE_H
diff --git a/src/lib/nsas/nameserver_address.h b/src/lib/nsas/nameserver_address.h
index 07b6d4a..5f5c7c9 100644
--- a/src/lib/nsas/nameserver_address.h
+++ b/src/lib/nsas/nameserver_address.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NAMESERVER_ADDRESS_H
-#define __NAMESERVER_ADDRESS_H
+#ifndef NAMESERVER_ADDRESS_H
+#define NAMESERVER_ADDRESS_H
#include <boost/shared_ptr.hpp>
@@ -114,4 +114,4 @@ private:
} // namespace nsas
} // namespace isc
-#endif//__NAMESERVER_ADDRESS_H
+#endif//NAMESERVER_ADDRESS_H
diff --git a/src/lib/nsas/nameserver_address_store.h b/src/lib/nsas/nameserver_address_store.h
index 1af535a..b107b3b 100644
--- a/src/lib/nsas/nameserver_address_store.h
+++ b/src/lib/nsas/nameserver_address_store.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NAMESERVER_ADDRESS_STORE_H
-#define __NAMESERVER_ADDRESS_STORE_H
+#ifndef NAMESERVER_ADDRESS_STORE_H
+#define NAMESERVER_ADDRESS_STORE_H
#include <string>
#include <vector>
@@ -129,4 +129,4 @@ private:
} // namespace isc
-#endif // __NAMESERVER_ADDRESS_STORE_H
+#endif // NAMESERVER_ADDRESS_STORE_H
diff --git a/src/lib/nsas/nameserver_entry.h b/src/lib/nsas/nameserver_entry.h
index 0f214c6..77a640d 100644
--- a/src/lib/nsas/nameserver_entry.h
+++ b/src/lib/nsas/nameserver_entry.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NAMESERVER_ENTRY_H
-#define __NAMESERVER_ENTRY_H
+#ifndef NAMESERVER_ENTRY_H
+#define NAMESERVER_ENTRY_H
#include <string>
#include <vector>
@@ -281,4 +281,4 @@ private:
} // namespace dns
} // namespace isc
-#endif // __NAMESERVER_ENTRY_H
+#endif // NAMESERVER_ENTRY_H
diff --git a/src/lib/nsas/nsas_entry.h b/src/lib/nsas/nsas_entry.h
index 9cbed11..e797fd8 100644
--- a/src/lib/nsas/nsas_entry.h
+++ b/src/lib/nsas/nsas_entry.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NSAS_ENTRY_H
-#define __NSAS_ENTRY_H
+#ifndef NSAS_ENTRY_H
+#define NSAS_ENTRY_H
#include <boost/enable_shared_from_this.hpp>
#include <iostream>
@@ -135,4 +135,4 @@ private:
} // namespace isc
-#endif // __NSAS_ENTRY_H
+#endif // NSAS_ENTRY_H
diff --git a/src/lib/nsas/nsas_entry_compare.h b/src/lib/nsas/nsas_entry_compare.h
index 9e9ba7d..6291456 100644
--- a/src/lib/nsas/nsas_entry_compare.h
+++ b/src/lib/nsas/nsas_entry_compare.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NSAS_ENTRY_COMPARE_H
-#define __NSAS_ENTRY_COMPARE_H
+#ifndef NSAS_ENTRY_COMPARE_H
+#define NSAS_ENTRY_COMPARE_H
#include "hash_key.h"
#include "hash_table.h"
@@ -50,4 +50,4 @@ public:
} // namespace nsas
} // namespace isc
-#endif // __NSAS_ENTRY_COMPARE_H
+#endif // NSAS_ENTRY_COMPARE_H
diff --git a/src/lib/nsas/nsas_log.h b/src/lib/nsas/nsas_log.h
index 031f46d..d4fed3c 100644
--- a/src/lib/nsas/nsas_log.h
+++ b/src/lib/nsas/nsas_log.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NSAS_LOG__H
-#define __NSAS_LOG__H
+#ifndef NSAS_LOG_H
+#define NSAS_LOG_H
#include <log/macros.h>
#include "nsas_messages.h"
@@ -50,4 +50,4 @@ extern isc::log::Logger nsas_logger; // isc::nsas::logger is the NSAS logger
} // namespace nsas
} // namespace isc
-#endif // __NSAS_LOG__H
+#endif // NSAS_LOG_H
diff --git a/src/lib/nsas/nsas_types.h b/src/lib/nsas/nsas_types.h
index 940cc3e..07190a4 100644
--- a/src/lib/nsas/nsas_types.h
+++ b/src/lib/nsas/nsas_types.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NSAS_TYPES_H
-#define __NSAS_TYPES_H
+#ifndef NSAS_TYPES_H
+#define NSAS_TYPES_H
/// \file nsas_types.h
/// \brief Nameserver Address Store Types
@@ -44,4 +44,4 @@ enum AddressFamily {
}
}
-#endif // __NSAS_TYPES_H
+#endif // NSAS_TYPES_H
diff --git a/src/lib/nsas/tests/nsas_test.h b/src/lib/nsas/tests/nsas_test.h
index 2dd95ef..d6b4d92 100644
--- a/src/lib/nsas/tests/nsas_test.h
+++ b/src/lib/nsas/tests/nsas_test.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NSAS_TEST_H
-#define __NSAS_TEST_H
+#ifndef NSAS_TEST_H
+#define NSAS_TEST_H
/// \file nsas_test.h
///
@@ -293,4 +293,4 @@ protected:
} // namespace nsas
} // namespace isc
-#endif // __NSAS_TEST_H
+#endif // NSAS_TEST_H
diff --git a/src/lib/nsas/zone_entry.h b/src/lib/nsas/zone_entry.h
index 482b89f..7e5ab5b 100644
--- a/src/lib/nsas/zone_entry.h
+++ b/src/lib/nsas/zone_entry.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ZONE_ENTRY_H
-#define __ZONE_ENTRY_H
+#ifndef ZONE_ENTRY_H
+#define ZONE_ENTRY_H
#include <string>
#include <vector>
@@ -189,4 +189,4 @@ private:
} // namespace nsas
} // namespace isc
-#endif // __ZONE_ENTRY_H
+#endif // ZONE_ENTRY_H
diff --git a/src/lib/python/bind10_config.py.in b/src/lib/python/bind10_config.py.in
index b8975cf..6db64e2 100644
--- a/src/lib/python/bind10_config.py.in
+++ b/src/lib/python/bind10_config.py.in
@@ -51,7 +51,7 @@ def reload():
# tree the programs in the tree (not installed ones) will be used.
#
# B10_FROM_SOURCE_LOCALSTATEDIR is specifically intended to be used for
- # tests where we want to use variuos types of configuration within the test
+ # tests where we want to use various types of configuration within the test
# environment. (We may want to make it even more generic so that the path
# is passed from the boss process)
if "B10_FROM_SOURCE" in os.environ:
@@ -60,6 +60,8 @@ def reload():
else:
DATA_PATH = os.environ["B10_FROM_SOURCE"]
PLUGIN_PATHS = [os.environ["B10_FROM_SOURCE"] +
+ '/src/bin/cfgmgr/local_plugins',
+ os.environ["B10_FROM_SOURCE"] +
'/src/bin/cfgmgr/plugins']
programdirs = ['auth', 'cfgmgr', 'cmdctl', 'ddns', 'dhcp6', 'msgq',
'resolver', 'sockcreator', 'stats', 'xfrin', 'xfrout',
diff --git a/src/lib/python/isc/acl/dns.h b/src/lib/python/isc/acl/dns.h
index 76849c5..424a7f8 100644
--- a/src/lib/python/isc/acl/dns.h
+++ b/src/lib/python/isc/acl/dns.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_ACL_DNS_H
-#define __PYTHON_ACL_DNS_H 1
+#ifndef PYTHON_ACL_DNS_H
+#define PYTHON_ACL_DNS_H 1
#include <Python.h>
@@ -45,7 +45,7 @@ extern PyObject* getACLException(const char* ex_name);
} // namespace acl
} // namespace isc
-#endif // __PYTHON_ACL_DNS_H
+#endif // PYTHON_ACL_DNS_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/acl/dns_requestacl_python.h b/src/lib/python/isc/acl/dns_requestacl_python.h
index 8f7ad8a..ea1cb5e 100644
--- a/src/lib/python/isc/acl/dns_requestacl_python.h
+++ b/src/lib/python/isc/acl/dns_requestacl_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_REQUESTACL_H
-#define __PYTHON_REQUESTACL_H 1
+#ifndef PYTHON_REQUESTACL_H
+#define PYTHON_REQUESTACL_H 1
#include <Python.h>
@@ -46,7 +46,7 @@ bool initModulePart_RequestACL(PyObject* mod);
} // namespace dns
} // namespace acl
} // namespace isc
-#endif // __PYTHON_REQUESTACL_H
+#endif // PYTHON_REQUESTACL_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/acl/dns_requestcontext_python.h b/src/lib/python/isc/acl/dns_requestcontext_python.h
index 766133b..567e86f 100644
--- a/src/lib/python/isc/acl/dns_requestcontext_python.h
+++ b/src/lib/python/isc/acl/dns_requestcontext_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_REQUESTCONTEXT_H
-#define __PYTHON_REQUESTCONTEXT_H 1
+#ifndef PYTHON_REQUESTCONTEXT_H
+#define PYTHON_REQUESTCONTEXT_H 1
#include <Python.h>
@@ -47,7 +47,7 @@ bool initModulePart_RequestContext(PyObject* mod);
} // namespace dns
} // namespace acl
} // namespace isc
-#endif // __PYTHON_REQUESTCONTEXT_H
+#endif // PYTHON_REQUESTCONTEXT_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/acl/dns_requestloader_python.h b/src/lib/python/isc/acl/dns_requestloader_python.h
index 9d0b63e..80cb6be 100644
--- a/src/lib/python/isc/acl/dns_requestloader_python.h
+++ b/src/lib/python/isc/acl/dns_requestloader_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_REQUESTLOADER_H
-#define __PYTHON_REQUESTLOADER_H 1
+#ifndef PYTHON_REQUESTLOADER_H
+#define PYTHON_REQUESTLOADER_H 1
#include <Python.h>
@@ -39,7 +39,7 @@ bool initModulePart_RequestLoader(PyObject* mod);
} // namespace dns
} // namespace acl
} // namespace isc
-#endif // __PYTHON_REQUESTLOADER_H
+#endif // PYTHON_REQUESTLOADER_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/datasrc/client_python.h b/src/lib/python/isc/datasrc/client_python.h
index 98a256e..71aee8b 100644
--- a/src/lib/python/isc/datasrc/client_python.h
+++ b/src/lib/python/isc/datasrc/client_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_DATASRC_CLIENT_H
-#define __PYTHON_DATASRC_CLIENT_H 1
+#ifndef PYTHON_DATASRC_CLIENT_H
+#define PYTHON_DATASRC_CLIENT_H 1
#include <datasrc/client_list.h>
@@ -47,7 +47,7 @@ wrapDataSourceClient(DataSourceClient* client,
} // namespace python
} // namespace datasrc
} // namespace isc
-#endif // __PYTHON_DATASRC_CLIENT_H
+#endif // PYTHON_DATASRC_CLIENT_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/datasrc/configurableclientlist_python.h b/src/lib/python/isc/datasrc/configurableclientlist_python.h
index 155d262..bcd76fe 100644
--- a/src/lib/python/isc/datasrc/configurableclientlist_python.h
+++ b/src/lib/python/isc/datasrc/configurableclientlist_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_CONFIGURABLECLIENTLIST_H
-#define __PYTHON_CONFIGURABLECLIENTLIST_H 1
+#ifndef PYTHON_CONFIGURABLECLIENTLIST_H
+#define PYTHON_CONFIGURABLECLIENTLIST_H 1
#include <Python.h>
@@ -37,7 +37,7 @@ bool initModulePart_ConfigurableClientList(PyObject* mod);
} // namespace python
} // namespace datasrc
} // namespace isc
-#endif // __PYTHON_CONFIGURABLECLIENTLIST_H
+#endif // PYTHON_CONFIGURABLECLIENTLIST_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/datasrc/datasrc.h b/src/lib/python/isc/datasrc/datasrc.h
index d82881b..5a7a8f0 100644
--- a/src/lib/python/isc/datasrc/datasrc.h
+++ b/src/lib/python/isc/datasrc/datasrc.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_DATASRC_H
-#define __PYTHON_DATASRC_H 1
+#ifndef PYTHON_DATASRC_H
+#define PYTHON_DATASRC_H 1
#include <Python.h>
@@ -43,7 +43,7 @@ extern PyObject* getDataSourceException(const char* ex_name);
} // namespace datasrc
} // namespace isc
-#endif // __PYTHON_ACL_DNS_H
+#endif // PYTHON_DATASRC_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/datasrc/finder_python.h b/src/lib/python/isc/datasrc/finder_python.h
index 23bc457..8d4c9b6 100644
--- a/src/lib/python/isc/datasrc/finder_python.h
+++ b/src/lib/python/isc/datasrc/finder_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_DATASRC_FINDER_H
-#define __PYTHON_DATASRC_FINDER_H 1
+#ifndef PYTHON_DATASRC_FINDER_H
+#define PYTHON_DATASRC_FINDER_H 1
#include <Python.h>
@@ -37,7 +37,7 @@ PyObject* createZoneFinderObject(isc::datasrc::ZoneFinderPtr source,
} // namespace python
} // namespace datasrc
} // namespace isc
-#endif // __PYTHON_DATASRC_FINDER_H
+#endif // PYTHON_DATASRC_FINDER_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/datasrc/iterator_python.h b/src/lib/python/isc/datasrc/iterator_python.h
index 7c1b0eb..c64dea3 100644
--- a/src/lib/python/isc/datasrc/iterator_python.h
+++ b/src/lib/python/isc/datasrc/iterator_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_DATASRC_ITERATOR_H
-#define __PYTHON_DATASRC_ITERATOR_H 1
+#ifndef PYTHON_DATASRC_ITERATOR_H
+#define PYTHON_DATASRC_ITERATOR_H 1
#include <Python.h>
@@ -39,7 +39,7 @@ PyObject* createZoneIteratorObject(isc::datasrc::ZoneIteratorPtr source,
} // namespace python
} // namespace datasrc
} // namespace isc
-#endif // __PYTHON_DATASRC_ITERATOR_H
+#endif // PYTHON_DATASRC_ITERATOR_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/datasrc/journal_reader_python.h b/src/lib/python/isc/datasrc/journal_reader_python.h
index 56344df..6708c36 100644
--- a/src/lib/python/isc/datasrc/journal_reader_python.h
+++ b/src/lib/python/isc/datasrc/journal_reader_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_DATASRC_JOURNAL_READER_H
-#define __PYTHON_DATASRC_JOURNAL_READER_H 1
+#ifndef PYTHON_DATASRC_JOURNAL_READER_H
+#define PYTHON_DATASRC_JOURNAL_READER_H 1
#include <Python.h>
@@ -40,7 +40,7 @@ PyObject* createZoneJournalReaderObject(
} // namespace python
} // namespace datasrc
} // namespace isc
-#endif // __PYTHON_DATASRC_JOURNAL_READER_H
+#endif // PYTHON_DATASRC_JOURNAL_READER_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/datasrc/updater_python.h b/src/lib/python/isc/datasrc/updater_python.h
index 8228578..b09c524 100644
--- a/src/lib/python/isc/datasrc/updater_python.h
+++ b/src/lib/python/isc/datasrc/updater_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_DATASRC_UPDATER_H
-#define __PYTHON_DATASRC_UPDATER_H 1
+#ifndef PYTHON_DATASRC_UPDATER_H
+#define PYTHON_DATASRC_UPDATER_H 1
#include <Python.h>
@@ -40,7 +40,7 @@ PyObject* createZoneUpdaterObject(isc::datasrc::ZoneUpdaterPtr source,
} // namespace python
} // namespace datasrc
} // namespace isc
-#endif // __PYTHON_DATASRC_UPDATER_H
+#endif // PYTHON_DATASRC_UPDATER_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/sysinfo/sysinfo.py b/src/lib/python/isc/sysinfo/sysinfo.py
index 97b9e59..8e4610c 100644
--- a/src/lib/python/isc/sysinfo/sysinfo.py
+++ b/src/lib/python/isc/sysinfo/sysinfo.py
@@ -22,6 +22,7 @@ import subprocess
import os.path
import platform
import time
+from datetime import timedelta
class SysInfo:
def __init__(self):
@@ -93,6 +94,18 @@ class SysInfo:
"""Returns the uptime in seconds."""
return self._uptime
+ def get_uptime_desc(self):
+ """Returns the uptime in human readable form.
+
+ The format is the result of str() method of the standard library
+ datetime.timedelta class. It returns None if _uptime is None.
+
+ """
+ if self._uptime is None:
+ return None
+
+ return str(timedelta(seconds=self._uptime))
+
def get_loadavg(self):
"""Returns the load average as 3 floating point values in an array."""
return self._loadavg
@@ -333,11 +346,11 @@ class SysInfoOpenBSD(SysInfoBSD):
pass
try:
+ # We use the size of free-list from the vmstat result.
s = subprocess.check_output(['vmstat'])
lines = s.decode('utf-8').split('\n')
v = re.split('\s+', lines[2])
- used = int(v[4]) * 1024
- self._mem_free = self._mem_total - used
+ self._mem_free = int(v[5]) * 1024
except (subprocess.CalledProcessError, OSError):
pass
@@ -389,17 +402,27 @@ class SysInfoFreeBSD(SysInfoFreeBSDOSX):
super().__init__()
try:
- s = subprocess.check_output(['sysctl', '-n', 'kern.smp.active'])
- self._platform_is_smp = int(s.decode('utf-8').strip()) > 0
- except (subprocess.CalledProcessError, OSError):
+ # There doesn't seem to be an easy way to reliably detect whether
+ # the kernel was built with SMP support on FreeBSD. We use
+ # a sysctl variable that is only defined in SMP kernels.
+ # This assumption seems to hold for several recent versions of
+ # FreeBSD, but it may not always be so for future versions.
+ s = subprocess.check_output(['sysctl', '-n',
+ 'kern.smp.forward_signal_enabled'])
+ self._platform_is_smp = True # the value doesn't matter
+ except subprocess.CalledProcessError:
+ # if this variable isn't defined we should see this exception.
+ # intepret it as an indication of non-SMP kernel.
+ self._platform_is_smp = False
+ except OSError:
pass
try:
+ # We use the size of free-list from the vmstat result.
s = subprocess.check_output(['vmstat', '-H'])
lines = s.decode('utf-8').split('\n')
v = re.split('\s+', lines[2])
- used = int(v[4]) * 1024
- self._mem_free = self._mem_total - used
+ self._mem_free = int(v[5]) * 1024
except (subprocess.CalledProcessError, OSError):
pass
diff --git a/src/lib/python/isc/sysinfo/tests/sysinfo_test.py b/src/lib/python/isc/sysinfo/tests/sysinfo_test.py
index 0add036..8f11df0 100644
--- a/src/lib/python/isc/sysinfo/tests/sysinfo_test.py
+++ b/src/lib/python/isc/sysinfo/tests/sysinfo_test.py
@@ -49,7 +49,7 @@ class MyLinuxFile:
elif self._filename == '/proc/version':
return 'An SMP version string'
elif self._filename == '/proc/uptime':
- return '86400.75 139993.71'
+ return '172800.75 139993.71'
elif self._filename == '/proc/loadavg':
return '0.1 0.2 0.3 0.4'
else:
@@ -171,26 +171,33 @@ def _my_freebsd_os_sysconf(key):
def _my_freebsd_platform_uname():
return ('FreeBSD', 'freebsd', '8.2-RELEASE', '', 'i386')
-def _my_freebsd_osx_subprocess_check_output(command):
+def _my_freebsd_osx_subprocess_check_output(command, faked_output={}):
'''subprocess output shared for freebsd and osx'''
assert type(command) == list, 'command argument is not a list'
if command == ['sysctl', '-n', 'kern.boottime']:
- return bytes('{ sec = ' + str(int(time.time() - 76632)) + ', usec = 0 }\n', 'utf-8')
+ if 'boottime-sysctl' in faked_output:
+ return faked_output['boottime-sysctl']
+ return bytes('{ sec = ' + str(int(time.time() - 76632)) +
+ ', usec = 0 }\n', 'utf-8')
elif command == ['sysctl', '-n', 'vm.loadavg']:
return b'{ 0.2 0.4 0.6 }\n'
else:
return _my_bsd_subprocess_check_output(command)
-def _my_freebsd_subprocess_check_output(command):
+def _my_freebsd_subprocess_check_output(command, faked_output):
assert type(command) == list, 'command argument is not a list'
- if command == ['sysctl', '-n', 'kern.smp.active']:
- return b'1\n'
+ if command == ['sysctl', '-n', 'kern.smp.forward_signal_enabled']:
+ output = faked_output['smp-sysctl']
+ if isinstance(output, Exception):
+ raise output
+ return output
elif command == ['vmstat', '-H']:
return b' procs memory page disks traps cpu\n r b w avm fre flt re pi po fr sr wd0 cd0 int sys cs us sy id\n 0 0 0 343434 123456 47 0 0 0 0 0 2 0 2 80 14 0 1 99\n'
elif command == ['swapctl', '-s', '-k']:
return b'Total: 1013216 0\n'
else:
- freebsd_osx_output = _my_freebsd_osx_subprocess_check_output(command)
+ freebsd_osx_output = \
+ _my_freebsd_osx_subprocess_check_output(command, faked_output)
if freebsd_osx_output is not None:
return freebsd_osx_output
else:
@@ -252,6 +259,7 @@ class SysInfoTest(unittest.TestCase):
self.assertEqual('Unknown', s.get_platform_machine())
self.assertFalse(s.get_platform_is_smp())
self.assertEqual(None, s.get_uptime())
+ self.assertEqual(None, s.get_uptime_desc())
self.assertEqual(None, s.get_loadavg())
self.assertEqual(None, s.get_mem_total())
self.assertEqual(None, s.get_mem_free())
@@ -267,7 +275,11 @@ class SysInfoTest(unittest.TestCase):
def test_sysinfo_factory(self):
"""Test that SysInfoFromFactory returns a valid system-specific
- SysInfo implementation."""
+ SysInfo implementation.
+
+ See sysinfo.SysInfoTestcase() for some of the parameters.
+
+ """
old_platform_system = platform.system
platform.system = _my_testcase_platform_system
@@ -281,6 +293,8 @@ class SysInfoTest(unittest.TestCase):
self.assertEqual('Unknown', s.get_platform_machine())
self.assertFalse(s.get_platform_is_smp())
self.assertEqual(131072, s.get_uptime())
+ # We check that we do NOT add 's' to 'day' (because it's singular):
+ self.assertEqual('1 day, 12:24:32', s.get_uptime_desc())
self.assertEqual(None, s.get_loadavg())
self.assertEqual(None, s.get_mem_total())
self.assertEqual(None, s.get_mem_free())
@@ -312,7 +326,10 @@ class SysInfoTest(unittest.TestCase):
self.assertEqual(NPROCESSORS_LINUX, s.get_num_processors())
self.assertEqual('myhostname', s.get_platform_hostname())
self.assertTrue(s.get_platform_is_smp())
- self.assertEqual(86401, s.get_uptime())
+ self.assertEqual(172801, s.get_uptime())
+ # We check that we add 's' to 'day', and that the mm part has an
+ # additional 0, i.e., not '0:0' but '0:00':
+ self.assertEqual('2 days, 0:00:01', s.get_uptime_desc())
self.assertEqual((0.1, 0.2, 0.3), s.get_loadavg())
self.assertEqual(3157884928, s.get_mem_total())
self.assertEqual(891383808, s.get_mem_free())
@@ -366,7 +383,7 @@ class SysInfoTest(unittest.TestCase):
self.assertEqual((0.7, 0.9, 0.8), s.get_loadavg())
self.assertFalse(s.get_platform_is_smp())
self.assertEqual(543214321, s.get_mem_total())
- self.assertEqual(543214321 - (121212 * 1024), s.get_mem_free())
+ self.assertEqual(123456 * 1024, s.get_mem_free())
self.assertEqual(566791168, s.get_mem_swap_total())
self.assertEqual(566789120, s.get_mem_swap_free())
@@ -379,18 +396,42 @@ class SysInfoTest(unittest.TestCase):
# with mock ones for testing.
platform.system = _my_freebsd_platform_system
os.sysconf = _my_freebsd_os_sysconf
- subprocess.check_output = _my_freebsd_subprocess_check_output
+
+ # We use a lambda object so we can tweak the subprocess output during
+ # the tests later.
+ faked_process_output = { 'smp-sysctl': b'1\n' }
+ subprocess.check_output = lambda command : \
+ _my_freebsd_subprocess_check_output(command, faked_process_output)
+
os.uname = _my_freebsd_platform_uname
s = SysInfoFromFactory()
self.assertEqual(NPROCESSORS_FREEBSD, s.get_num_processors())
self.assertTrue(s.get_platform_is_smp())
+ # We check the kernel SMP support by the availability of a sysctl
+ # variable. The value (especially a 0 value) shouldn't matter.
+ faked_process_output['smp-sysctl'] = b'0\n'
+ s = SysInfoFromFactory()
+ self.assertTrue(s.get_platform_is_smp())
+
+ # if the sysctl raises CalledProcessError, we treat it as non-SMP
+ # kernel.
+ faked_process_output['smp-sysctl'] = \
+ subprocess.CalledProcessError(1, 'sysctl')
+ s = SysInfoFromFactory()
+ self.assertFalse(s.get_platform_is_smp())
+
+ # if it results in OSError, no SMP information will be provided.
+ faked_process_output['smp-sysctl'] = OSError()
+ s = SysInfoFromFactory()
+ self.assertIsNone(s.get_platform_is_smp())
+
self.check_bsd_values(s)
self.assertEqual((0.2, 0.4, 0.6), s.get_loadavg())
self.assertEqual(543214321, s.get_mem_total())
- self.assertEqual(543214321 - (343434 * 1024), s.get_mem_free())
+ self.assertEqual(123456 * 1024, s.get_mem_free())
self.assertEqual(1037533184, s.get_mem_swap_total())
self.assertEqual(1037533184, s.get_mem_swap_free())
diff --git a/src/lib/python/isc/util/cio/socketsession_python.h b/src/lib/python/isc/util/cio/socketsession_python.h
index b0703ac..da83047 100644
--- a/src/lib/python/isc/util/cio/socketsession_python.h
+++ b/src/lib/python/isc/util/cio/socketsession_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_SOCKETSESSION_H
-#define __PYTHON_SOCKETSESSION_H 1
+#ifndef PYTHON_SOCKETSESSION_H
+#define PYTHON_SOCKETSESSION_H 1
#include <Python.h>
@@ -28,7 +28,7 @@ extern PyObject* po_SocketSessionError;
} // namespace io
} // namespace util
} // namespace isc
-#endif // __PYTHON_SOCKETSESSION_H
+#endif // PYTHON_SOCKETSESSION_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/util/cio/socketsessionforwarder_python.h b/src/lib/python/isc/util/cio/socketsessionforwarder_python.h
index 2ce220a..968ce7f 100644
--- a/src/lib/python/isc/util/cio/socketsessionforwarder_python.h
+++ b/src/lib/python/isc/util/cio/socketsessionforwarder_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_SOCKETSESSIONFORWARDER_H
-#define __PYTHON_SOCKETSESSIONFORWARDER_H 1
+#ifndef PYTHON_SOCKETSESSIONFORWARDER_H
+#define PYTHON_SOCKETSESSIONFORWARDER_H 1
#include <Python.h>
@@ -38,7 +38,7 @@ bool initModulePart_SocketSessionForwarder(PyObject* mod);
} // namespace io
} // namespace util
} // namespace isc
-#endif // __PYTHON_SOCKETSESSIONFORWARDER_H
+#endif // PYTHON_SOCKETSESSIONFORWARDER_H
// Local Variables:
// mode: c++
diff --git a/src/lib/python/isc/util/cio/socketsessionreceiver_python.h b/src/lib/python/isc/util/cio/socketsessionreceiver_python.h
index 14e8a1b..eb9a884 100644
--- a/src/lib/python/isc/util/cio/socketsessionreceiver_python.h
+++ b/src/lib/python/isc/util/cio/socketsessionreceiver_python.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_SOCKETSESSIONRECEIVER_H
-#define __PYTHON_SOCKETSESSIONRECEIVER_H 1
+#ifndef PYTHON_SOCKETSESSIONRECEIVER_H
+#define PYTHON_SOCKETSESSIONRECEIVER_H 1
#include <Python.h>
@@ -39,7 +39,7 @@ bool initModulePart_SocketSessionReceiver(PyObject* mod);
} // namespace python
} // namespace util
} // namespace isc
-#endif // __PYTHON_SOCKETSESSIONRECEIVER_H
+#endif // PYTHON_SOCKETSESSIONRECEIVER_H
// Local Variables:
// mode: c++
diff --git a/src/lib/resolve/recursive_query.h b/src/lib/resolve/recursive_query.h
index 7cda837..2875441 100644
--- a/src/lib/resolve/recursive_query.h
+++ b/src/lib/resolve/recursive_query.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RECURSIVE_QUERY_H
-#define __RECURSIVE_QUERY_H 1
+#ifndef RECURSIVE_QUERY_H
+#define RECURSIVE_QUERY_H 1
#include <util/buffer.h>
#include <asiodns/dns_service.h>
@@ -226,4 +226,4 @@ private:
} // namespace asiodns
} // namespace isc
-#endif // __RECURSIVE_QUERY_H
+#endif // RECURSIVE_QUERY_H
diff --git a/src/lib/resolve/resolve.h b/src/lib/resolve/resolve.h
index 0a588e2..c7ff195 100644
--- a/src/lib/resolve/resolve.h
+++ b/src/lib/resolve/resolve.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef _ISC_RESOLVE_H
-#define _ISC_RESOLVE_H 1
+#ifndef ISC_RESOLVE_H
+#define ISC_RESOLVE_H 1
/// This file includes all other libresolve headers, and provides
/// several helper functions used in resolving.
diff --git a/src/lib/resolve/resolve_log.h b/src/lib/resolve/resolve_log.h
index 828b9d3..15a7a72 100644
--- a/src/lib/resolve/resolve_log.h
+++ b/src/lib/resolve/resolve_log.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RESOLVE_LOG__H
-#define __RESOLVE_LOG__H
+#ifndef RESOLVE_LOG_H
+#define RESOLVE_LOG_H
#include <log/macros.h>
#include "resolve_messages.h"
@@ -50,4 +50,4 @@ extern isc::log::Logger logger;
} // namespace resolve
} // namespace isc
-#endif // __RESOLVE_LOG__H
+#endif // RESOLVE_LOG_H
diff --git a/src/lib/resolve/resolver_callback.h b/src/lib/resolve/resolver_callback.h
index 79138e8..9a24501 100644
--- a/src/lib/resolve/resolver_callback.h
+++ b/src/lib/resolve/resolver_callback.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef _ISC_RESOLVER_CALLBACK_H
-#define _ISC_RESOLVER_CALLBACK_H 1
+#ifndef ISC_RESOLVER_CALLBACK_H
+#define ISC_RESOLVER_CALLBACK_H 1
#include <asiodns/dns_server.h>
#include <dns/message.h>
diff --git a/src/lib/resolve/resolver_interface.h b/src/lib/resolve/resolver_interface.h
index 1d01e90..5002c80 100644
--- a/src/lib/resolve/resolver_interface.h
+++ b/src/lib/resolve/resolver_interface.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RESOLVER_INTERFACE_H
-#define __RESOLVER_INTERFACE_H
+#ifndef RESOLVER_INTERFACE_H
+#define RESOLVER_INTERFACE_H
#include <dns/message.h>
@@ -95,4 +95,4 @@ class ResolverInterface {
} // namespace nsas
} // namespace isc
-#endif //__RESOLVER_INTERFACE_H
+#endif //RESOLVER_INTERFACE_H
diff --git a/src/lib/resolve/response_classifier.h b/src/lib/resolve/response_classifier.h
index a027bd0..ce99bf0 100644
--- a/src/lib/resolve/response_classifier.h
+++ b/src/lib/resolve/response_classifier.h
@@ -14,8 +14,8 @@
// $Id$
-#ifndef __RESPONSE_CLASSIFIER_H
-#define __RESPONSE_CLASSIFIER_H
+#ifndef RESPONSE_CLASSIFIER_H
+#define RESPONSE_CLASSIFIER_H
#include <cstddef>
@@ -154,4 +154,4 @@ private:
} // namespace resolve
} // namespace isc
-#endif // __RESPONSE_CLASSIFIER_H
+#endif // RESPONSE_CLASSIFIER_H
diff --git a/src/lib/server_common/client.h b/src/lib/server_common/client.h
index 8cafb1e..912e7a6 100644
--- a/src/lib/server_common/client.h
+++ b/src/lib/server_common/client.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __CLIENT_H
-#define __CLIENT_H 1
+#ifndef CLIENT_H
+#define CLIENT_H 1
#include <string>
#include <ostream>
@@ -147,7 +147,7 @@ std::ostream& operator<<(std::ostream& os, const Client& client);
}
}
-#endif // __CLIENT_H
+#endif // CLIENT_H
// Local Variables:
// mode: c++
diff --git a/src/lib/server_common/logger.h b/src/lib/server_common/logger.h
index 80bc81d..5d565bf 100644
--- a/src/lib/server_common/logger.h
+++ b/src/lib/server_common/logger.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __SERVER_COMMON_LOGGER_H
-#define __SERVER_COMMON_LOGGER_H
+#ifndef SERVER_COMMON_LOGGER_H
+#define SERVER_COMMON_LOGGER_H
#include <log/macros.h>
#include <server_common/server_common_messages.h>
diff --git a/src/lib/server_common/socket_request.h b/src/lib/server_common/socket_request.h
index aac95d1..b532153 100644
--- a/src/lib/server_common/socket_request.h
+++ b/src/lib/server_common/socket_request.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __SOCKET_REQUEST_H
-#define __SOCKET_REQUEST_H 1
+#ifndef SOCKET_REQUEST_H
+#define SOCKET_REQUEST_H 1
#include <exceptions/exceptions.h>
@@ -275,4 +275,4 @@ void cleanupSocketRequestor();
}
}
-#endif // __SOCKET_REQUEST_H
+#endif // SOCKET_REQUEST_H
diff --git a/src/lib/statistics/Makefile.am b/src/lib/statistics/Makefile.am
index 206b527..a395bf5 100644
--- a/src/lib/statistics/Makefile.am
+++ b/src/lib/statistics/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = . tests
+SUBDIRS = tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG)
@@ -17,8 +17,9 @@ if USE_CLANGPP
AM_CXXFLAGS += -Wno-unused-parameter
endif
-lib_LTLIBRARIES = libb10-statistics.la
-libb10_statistics_la_SOURCES = counter.h counter.cc
-libb10_statistics_la_SOURCES += counter_dict.h counter_dict.cc
-
CLEANFILES = *.gcno *.gcda
+
+# These are header-only shared classes and required to build BIND 10.
+# Include them in the distributed tarball with EXTRA_DIST (like as
+# external sources in ext/).
+EXTRA_DIST = counter.h counter_dict.h
diff --git a/src/lib/statistics/counter.cc b/src/lib/statistics/counter.cc
deleted file mode 100644
index 53dc58e..0000000
--- a/src/lib/statistics/counter.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <vector>
-
-#include <boost/noncopyable.hpp>
-
-#include <statistics/counter.h>
-
-namespace {
-const unsigned int InitialValue = 0;
-} // namespace
-
-namespace isc {
-namespace statistics {
-
-class CounterImpl : boost::noncopyable {
- private:
- std::vector<Counter::Value> counters_;
- public:
- CounterImpl(const size_t nelements);
- ~CounterImpl();
- void inc(const Counter::Type&);
- const Counter::Value& get(const Counter::Type&) const;
-};
-
-CounterImpl::CounterImpl(const size_t items) :
- counters_(items, InitialValue)
-{
- if (items == 0) {
- isc_throw(isc::InvalidParameter, "Items must not be 0");
- }
-}
-
-CounterImpl::~CounterImpl() {}
-
-void
-CounterImpl::inc(const Counter::Type& type) {
- if(type >= counters_.size()) {
- isc_throw(isc::OutOfRange, "Counter type is out of range");
- }
- ++counters_.at(type);
- return;
-}
-
-const Counter::Value&
-CounterImpl::get(const Counter::Type& type) const {
- if(type >= counters_.size()) {
- isc_throw(isc::OutOfRange, "Counter type is out of range");
- }
- return (counters_.at(type));
-}
-
-Counter::Counter(const size_t items) : impl_(new CounterImpl(items))
-{}
-
-Counter::~Counter() {}
-
-void
-Counter::inc(const Type& type) {
- impl_->inc(type);
- return;
-}
-
-const Counter::Value&
-Counter::get(const Type& type) const {
- return (impl_->get(type));
-}
-
-} // namespace statistics
-} // namespace isc
diff --git a/src/lib/statistics/counter.h b/src/lib/statistics/counter.h
index 9e467ce..af52da4 100644
--- a/src/lib/statistics/counter.h
+++ b/src/lib/statistics/counter.h
@@ -12,27 +12,32 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __COUNTER_H
-#define __COUNTER_H 1
+#ifndef COUNTER_H
+#define COUNTER_H 1
+
+#include <exceptions/exceptions.h>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
-#include <exceptions/exceptions.h>
+#include <vector>
+
+namespace {
+const unsigned int InitialValue = 0;
+} // anonymous namespace
namespace isc {
namespace statistics {
-// forward declaration for pImpl idiom
-class CounterImpl;
-
class Counter : boost::noncopyable {
-private:
- boost::scoped_ptr<CounterImpl> impl_;
public:
typedef unsigned int Type;
typedef unsigned int Value;
+private:
+ std::vector<Counter::Value> counters_;
+
+public:
/// The constructor.
///
/// This constructor is mostly exception free. But it may still throw
@@ -41,29 +46,46 @@ public:
/// \param items A number of counter items to hold (greater than 0)
///
/// \throw isc::InvalidParameter \a items is 0
- Counter(const size_t items);
+ explicit Counter(const size_t items) :
+ counters_(items, InitialValue)
+ {
+ if (items == 0) {
+ isc_throw(isc::InvalidParameter, "Items must not be 0");
+ }
+ };
/// The destructor.
///
/// This method never throws an exception.
- ~Counter();
+ ~Counter() {};
/// \brief Increment a counter item specified with \a type.
///
/// \param type %Counter item to increment
///
/// \throw isc::OutOfRange \a type is invalid
- void inc(const Type& type);
+ void inc(const Counter::Type type) {
+ if (type >= counters_.size()) {
+ isc_throw(isc::OutOfRange, "Counter type is out of range");
+ }
+ ++counters_.at(type);
+ return;
+ };
/// \brief Get the value of a counter item specified with \a type.
///
/// \param type %Counter item to get the value of
///
/// \throw isc::OutOfRange \a type is invalid
- const Value& get(const Type& type) const;
+ const Counter::Value& get(const Counter::Type type) const {
+ if (type >= counters_.size()) {
+ isc_throw(isc::OutOfRange, "Counter type is out of range");
+ }
+ return (counters_.at(type));
+ };
};
} // namespace statistics
} // namespace isc
-#endif
+#endif // __COUNTER_H
diff --git a/src/lib/statistics/counter_dict.cc b/src/lib/statistics/counter_dict.cc
deleted file mode 100644
index 55353b2..0000000
--- a/src/lib/statistics/counter_dict.cc
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <cassert>
-#include <stdexcept>
-#include <iterator>
-#include <map>
-#include <boost/noncopyable.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <statistics/counter_dict.h>
-
-namespace {
-typedef boost::shared_ptr<isc::statistics::Counter> CounterPtr;
-typedef std::map<std::string, CounterPtr> DictionaryMap;
-}
-
-namespace isc {
-namespace statistics {
-
-// Implementation detail class for CounterDictionary::ConstIterator
-class CounterDictionaryConstIteratorImpl;
-
-class CounterDictionaryImpl : boost::noncopyable {
-private:
- DictionaryMap dictionary_;
- std::vector<std::string> elements_;
- const size_t items_;
- // Default constructor is forbidden; number of counter items must be
- // specified at the construction of this class.
- CounterDictionaryImpl();
-public:
- CounterDictionaryImpl(const size_t items);
- ~CounterDictionaryImpl();
- void addElement(const std::string& name);
- void deleteElement(const std::string& name);
- Counter& getElement(const std::string& name);
-public:
- CounterDictionaryConstIteratorImpl begin() const;
- CounterDictionaryConstIteratorImpl end() const;
-};
-
-// Constructor with number of items
-CounterDictionaryImpl::CounterDictionaryImpl(const size_t items) :
- items_(items)
-{
- // The number of items must not be 0
- if (items == 0) {
- isc_throw(isc::InvalidParameter, "Items must not be 0");
- }
-}
-
-// Destructor
-CounterDictionaryImpl::~CounterDictionaryImpl() {}
-
-void
-CounterDictionaryImpl::addElement(const std::string& name) {
- // throw if the element already exists
- if (dictionary_.count(name) != 0) {
- isc_throw(isc::InvalidParameter,
- "Element " << name << " already exists");
- }
- assert(items_ != 0);
- // Create a new Counter and add to the map
- dictionary_.insert(
- DictionaryMap::value_type(name, CounterPtr(new Counter(items_))));
-}
-
-void
-CounterDictionaryImpl::deleteElement(const std::string& name) {
- size_t result = dictionary_.erase(name);
- if (result != 1) {
- // If an element with specified name does not exist, throw
- // isc::OutOfRange.
- isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
- }
-}
-
-Counter&
-CounterDictionaryImpl::getElement(const std::string& name) {
- DictionaryMap::const_iterator i = dictionary_.find(name);
- if (i != dictionary_.end()) {
- // the key was found. return the element.
- return (*(i->second));
- } else {
- // If an element with specified name does not exist, throw
- // isc::OutOfRange.
- isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
- }
-}
-
-// Constructor
-// Initialize impl_
-CounterDictionary::CounterDictionary(const size_t items) :
- impl_(new CounterDictionaryImpl(items))
-{}
-
-// Destructor
-// impl_ will be freed automatically with scoped_ptr
-CounterDictionary::~CounterDictionary() {}
-
-void
-CounterDictionary::addElement(const std::string& name) {
- impl_->addElement(name);
-}
-
-void
-CounterDictionary::deleteElement(const std::string& name) {
- impl_->deleteElement(name);
-}
-
-Counter&
-CounterDictionary::getElement(const std::string& name) const {
- return (impl_->getElement(name));
-}
-
-Counter&
-CounterDictionary::operator[](const std::string& name) const {
- return (impl_->getElement(name));
-}
-
-// Implementation detail class for CounterDictionary::ConstIterator
-class CounterDictionaryConstIteratorImpl {
- public:
- CounterDictionaryConstIteratorImpl();
- ~CounterDictionaryConstIteratorImpl();
- CounterDictionaryConstIteratorImpl(
- const CounterDictionaryConstIteratorImpl &other);
- CounterDictionaryConstIteratorImpl &operator=(
- const CounterDictionaryConstIteratorImpl &source);
- CounterDictionaryConstIteratorImpl(
- DictionaryMap::const_iterator iterator);
- public:
- void increment();
- const CounterDictionary::ConstIterator::value_type&
- dereference() const;
- bool equal(const CounterDictionaryConstIteratorImpl& other) const;
- private:
- DictionaryMap::const_iterator iterator_;
-};
-
-CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl() {}
-
-CounterDictionaryConstIteratorImpl::~CounterDictionaryConstIteratorImpl() {}
-
-// Copy constructor: deep copy of iterator_
-CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl(
- const CounterDictionaryConstIteratorImpl &other) :
- iterator_(other.iterator_)
-{}
-
-// Assignment operator: deep copy of iterator_
-CounterDictionaryConstIteratorImpl &
-CounterDictionaryConstIteratorImpl::operator=(
- const CounterDictionaryConstIteratorImpl &source)
-{
- iterator_ = source.iterator_;
- return (*this);
-}
-
-// Constructor from implementation detail DictionaryMap::const_iterator
-CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl(
- DictionaryMap::const_iterator iterator) :
- iterator_(iterator)
-{}
-
-CounterDictionaryConstIteratorImpl
-CounterDictionaryImpl::begin() const {
- return (CounterDictionaryConstIteratorImpl(dictionary_.begin()));
-}
-
-CounterDictionaryConstIteratorImpl
-CounterDictionaryImpl::end() const {
- return (CounterDictionaryConstIteratorImpl(dictionary_.end()));
-}
-
-void
-CounterDictionaryConstIteratorImpl::increment() {
- ++iterator_;
- return;
-}
-
-const CounterDictionary::ConstIterator::value_type&
-CounterDictionaryConstIteratorImpl::dereference() const {
- return (iterator_->first);
-}
-
-bool
-CounterDictionaryConstIteratorImpl::equal(
- const CounterDictionaryConstIteratorImpl& other) const
-{
- return (iterator_ == other.iterator_);
-}
-
-CounterDictionary::ConstIterator
-CounterDictionary::begin() const {
- return (CounterDictionary::ConstIterator(
- CounterDictionaryConstIteratorImpl(impl_->begin())));
-}
-
-CounterDictionary::ConstIterator
-CounterDictionary::end() const {
- return (CounterDictionary::ConstIterator(
- CounterDictionaryConstIteratorImpl(impl_->end())));
-}
-
-CounterDictionary::ConstIterator::ConstIterator() :
- impl_(new CounterDictionaryConstIteratorImpl())
-{}
-
-CounterDictionary::ConstIterator::~ConstIterator() {}
-
-// Copy constructor: deep copy of impl_
-CounterDictionary::ConstIterator::ConstIterator(
- const CounterDictionary::ConstIterator& source) :
- impl_(new CounterDictionaryConstIteratorImpl(*(source.impl_)))
-{}
-
-// Assignment operator: deep copy of impl_
-CounterDictionary::ConstIterator &
-CounterDictionary::ConstIterator::operator=(
- const CounterDictionary::ConstIterator &source)
-{
- *impl_ = *source.impl_;
- return (*this);
-}
-
-// The constructor from implementation detail
-CounterDictionary::ConstIterator::ConstIterator(
- const CounterDictionaryConstIteratorImpl& source) :
- impl_(new CounterDictionaryConstIteratorImpl(source))
-{}
-
-const CounterDictionary::ConstIterator::value_type&
-CounterDictionary::ConstIterator::dereference() const
-{
- return (impl_->dereference());
-}
-
-bool
-CounterDictionary::ConstIterator::equal(
- CounterDictionary::ConstIterator const& other) const
-{
- return (impl_->equal(*(other.impl_)));
-}
-
-void
-CounterDictionary::ConstIterator::increment() {
- impl_->increment();
- return;
-}
-
-} // namespace statistics
-} // namespace isc
diff --git a/src/lib/statistics/counter_dict.h b/src/lib/statistics/counter_dict.h
index e322119..e288dfe 100644
--- a/src/lib/statistics/counter_dict.h
+++ b/src/lib/statistics/counter_dict.h
@@ -12,70 +12,86 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __COUNTER_DICT_H
-#define __COUNTER_DICT_H 1
+#ifndef COUNTER_DICT_H
+#define COUNTER_DICT_H 1
+
+#include <statistics/counter.h>
+#include <exceptions/exceptions.h>
-#include <string>
-#include <vector>
-#include <utility>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
#include <boost/iterator/iterator_facade.hpp>
-#include <exceptions/exceptions.h>
-#include <statistics/counter.h>
+#include <cassert>
+#include <stdexcept>
+#include <string>
+#include <vector>
+#include <map>
+#include <iterator>
+#include <utility>
+
+namespace {
+typedef boost::shared_ptr<isc::statistics::Counter> CounterPtr;
+typedef std::map<std::string, CounterPtr> DictionaryMap;
+}
namespace isc {
namespace statistics {
-class CounterDictionaryImpl;
-class CounterDictionaryConstIteratorImpl;
-
class CounterDictionary : boost::noncopyable {
private:
- boost::scoped_ptr<CounterDictionaryImpl> impl_;
+ DictionaryMap dictionary_;
+ std::vector<std::string> elements_;
+ const size_t items_;
// Default constructor is forbidden; number of counter items must be
// specified at the construction of this class.
CounterDictionary();
public:
- /// The constructor.
- /// This constructor is mostly exception free. But it may still throw
- /// a standard exception if memory allocation fails inside the method.
- ///
- /// \param items A number of counter items to hold (greater than 0)
- ///
- /// \throw isc::InvalidParameter \a items is 0
- CounterDictionary(const size_t items);
-
- /// The destructor.
- ///
- /// This method never throws an exception.
- ~CounterDictionary();
-
- /// \brief Add an element
- ///
- /// \throw isc::InvalidParameter \a element already exists.
- ///
- /// \param name A name of the element to append
- void addElement(const std::string& name);
-
- /// \brief Delete
- ///
- /// \throw isc::OutOfRange \a element does not exist.
- ///
- /// \param name A name of the element to delete
- void deleteElement(const std::string& name);
-
- /// \brief Lookup
- ///
- /// \throw isc::OutOfRange \a element does not exist.
- ///
- /// \param name A name of the element to get the counters
- Counter& getElement(const std::string &name) const;
-
- /// Same as getElement()
- Counter& operator[](const std::string &name) const;
-
+ explicit CounterDictionary(const size_t items) :
+ items_(items)
+ {
+ // The number of items must not be 0
+ if (items == 0) {
+ isc_throw(isc::InvalidParameter, "Items must not be 0");
+ }
+ };
+ ~CounterDictionary() {};
+ void addElement(const std::string& name) {
+ // throw if the element already exists
+ if (dictionary_.count(name) != 0) {
+ isc_throw(isc::InvalidParameter,
+ "Element " << name << " already exists");
+ }
+ assert(items_ != 0);
+ // Create a new Counter and add to the map
+ dictionary_.insert(
+ DictionaryMap::value_type(name, CounterPtr(new Counter(items_))));
+ };
+ void deleteElement(const std::string& name) {
+ size_t result = dictionary_.erase(name);
+ if (result != 1) {
+ // If an element with specified name does not exist, throw
+ // isc::OutOfRange.
+ isc_throw(isc::OutOfRange,
+ "Element " << name << " does not exist");
+ }
+ };
+ Counter& getElement(const std::string& name) {
+ DictionaryMap::const_iterator i = dictionary_.find(name);
+ if (i != dictionary_.end()) {
+ // the key was found. return the element.
+ return (*(i->second));
+ } else {
+ // If an element with specified name does not exist, throw
+ // isc::OutOfRange.
+ isc_throw(isc::OutOfRange,
+ "Element " << name << " does not exist");
+ }
+ };
+ Counter& operator[](const std::string& name) {
+ return (getElement(name));
+ };
/// \brief \c ConstIterator is a constant iterator that provides an
/// interface for enumerating name of zones stored in CounterDictionary.
///
@@ -90,67 +106,53 @@ public:
const std::string,
boost::forward_traversal_tag>
{
- private:
- boost::scoped_ptr<CounterDictionaryConstIteratorImpl> impl_;
public:
/// The constructor.
///
/// This constructor is mostly exception free. But it may still
/// throw a standard exception if memory allocation fails
/// inside the method.
- ConstIterator();
+ ConstIterator() {}
/// The destructor.
///
/// This method never throws an exception.
- ~ConstIterator();
- /// The assignment operator.
- ///
- /// This method is mostly exception free. But it may still
- /// throw a standard exception if memory allocation fails
- /// inside the method.
- ConstIterator& operator=(const ConstIterator &source);
- /// The copy constructor.
- ///
- /// This constructor is mostly exception free. But it may still
- /// throw a standard exception if memory allocation fails
- /// inside the method.
- ConstIterator(const ConstIterator& source);
- /// The constructor from implementation detail.
- ///
- /// This method is used to create an instance of ConstIterator
- /// by CounterDict::begin() and CounterDict::end().
- ///
- /// This constructor is mostly exception free. But it may still
- /// throw a standard exception if memory allocation fails
- /// inside the method.
+ ~ConstIterator() {}
+ /// Constructor from implementation detail DictionaryMap::const_iterator
ConstIterator(
- const CounterDictionaryConstIteratorImpl& source);
+ DictionaryMap::const_iterator iterator) :
+ iterator_(iterator)
+ {}
+
private:
/// \brief An internal method to increment this iterator.
- void increment();
+ void increment() {
+ ++iterator_;
+ return;
+ }
+
/// \brief An internal method to check equality.
- bool equal(const ConstIterator& other) const;
+ bool equal(const ConstIterator& other) const {
+ return (iterator_ == other.iterator_);
+ }
+
/// \brief An internal method to dereference this iterator.
- const value_type& dereference() const;
+ const value_type& dereference() const {
+ return (iterator_->first);
+ }
+
private:
friend class boost::iterator_core_access;
+ DictionaryMap::const_iterator iterator_;
};
- typedef ConstIterator const_iterator;
-
- /// \brief Return an iterator corresponding to the beginning of the
- /// elements stored in CounterDictionary.
- ///
- /// This method is mostly exception free. But it may still throw a
- /// standard exception if memory allocation fails inside the method.
- const_iterator begin() const;
+ ConstIterator begin() const {
+ return (CounterDictionary::ConstIterator(dictionary_.begin()));
+ };
+ ConstIterator end() const {
+ return (CounterDictionary::ConstIterator(dictionary_.end()));
+ };
- /// \brief Return an iterator corresponding to the end of the elements
- /// stored in CounterDictionary.
- ///
- /// This method is mostly exception free. But it may still throw a
- /// standard exception if memory allocation fails inside the method.
- const_iterator end() const;
+ typedef ConstIterator const_iterator;
};
} // namespace statistics
diff --git a/src/lib/statistics/tests/Makefile.am b/src/lib/statistics/tests/Makefile.am
index 007c8b0..25a3db2 100644
--- a/src/lib/statistics/tests/Makefile.am
+++ b/src/lib/statistics/tests/Makefile.am
@@ -28,7 +28,6 @@ run_unittests_SOURCES += counter_dict_unittest.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDADD = $(GTEST_LDADD)
-run_unittests_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
run_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
diff --git a/src/lib/testutils/dnsmessage_test.h b/src/lib/testutils/dnsmessage_test.h
index 02550eb..262d177 100644
--- a/src/lib/testutils/dnsmessage_test.h
+++ b/src/lib/testutils/dnsmessage_test.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ISC_TESTUTILS_DNSMESSAGETEST_H
-#define __ISC_TESTUTILS_DNSMESSAGETEST_H 1
+#ifndef ISC_TESTUTILS_DNSMESSAGETEST_H
+#define ISC_TESTUTILS_DNSMESSAGETEST_H 1
#include <algorithm>
#include <functional>
@@ -391,7 +391,7 @@ rrsetsCheck(const std::string& expected,
} // end of namespace testutils
} // end of namespace isc
-#endif // __ISC_TESTUTILS_DNSMESSAGETEST_H
+#endif // ISC_TESTUTILS_DNSMESSAGETEST_H
// Local Variables:
// mode: c++
diff --git a/src/lib/testutils/mockups.h b/src/lib/testutils/mockups.h
index 3028d7f..fc8a2e0 100644
--- a/src/lib/testutils/mockups.h
+++ b/src/lib/testutils/mockups.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ISC_TESTUTILS_MOCKUPS_H
-#define __ISC_TESTUTILS_MOCKUPS_H 1
+#ifndef ISC_TESTUTILS_MOCKUPS_H
+#define ISC_TESTUTILS_MOCKUPS_H 1
#include <config.h>
@@ -210,7 +210,7 @@ private:
} // end of testutils
} // end of isc
-#endif // __ISC_TESTUTILS_MOCKUPS_H
+#endif // ISC_TESTUTILS_MOCKUPS_H
// Local Variables:
// mode: c++
diff --git a/src/lib/testutils/portconfig.h b/src/lib/testutils/portconfig.h
index ce1bb39..8e8cab1 100644
--- a/src/lib/testutils/portconfig.h
+++ b/src/lib/testutils/portconfig.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ISC_TESTUTILS_PORTCONFIG_H
-#define __ISC_TESTUTILS_PORTCONFIG_H
+#ifndef ISC_TESTUTILS_PORTCONFIG_H
+#define ISC_TESTUTILS_PORTCONFIG_H
#include <gtest/gtest.h>
#include <cc/data.h>
@@ -186,4 +186,4 @@ invalidListenAddressConfig(Server& server) {
}
}
-#endif // __ISC_TESTUTILS_PORTCONFIG_H
+#endif // ISC_TESTUTILS_PORTCONFIG_H
diff --git a/src/lib/testutils/socket_request.h b/src/lib/testutils/socket_request.h
index 0ae15f3..d511401 100644
--- a/src/lib/testutils/socket_request.h
+++ b/src/lib/testutils/socket_request.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ISC_TESTUTILS_SOCKETREQUEST_H
-#define __ISC_TESTUTILS_SOCKETREQUEST_H 1
+#ifndef ISC_TESTUTILS_SOCKETREQUEST_H
+#define ISC_TESTUTILS_SOCKETREQUEST_H 1
#include <server_common/socket_request.h>
#include <server_common/portconfig.h>
@@ -216,4 +216,4 @@ private:
}
}
-#endif // __ISC_TESTUTILS_SOCKETREQUEST_H
+#endif // ISC_TESTUTILS_SOCKETREQUEST_H
diff --git a/src/lib/testutils/srv_test.h b/src/lib/testutils/srv_test.h
index a5c516e..e867595 100644
--- a/src/lib/testutils/srv_test.h
+++ b/src/lib/testutils/srv_test.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __ISC_TESTUTILS_SRVTEST_H
-#define __ISC_TESTUTILS_SRVTEST_H 1
+#ifndef ISC_TESTUTILS_SRVTEST_H
+#define ISC_TESTUTILS_SRVTEST_H 1
#include <util/buffer.h>
#include <dns/name.h>
@@ -112,7 +112,7 @@ protected:
};
} // end of namespace testutils
} // end of namespace isc
-#endif // __ISC_TESTUTILS_SRVTEST_H
+#endif // ISC_TESTUTILS_SRVTEST_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/buffer.h b/src/lib/util/buffer.h
index 7e88108..4800e99 100644
--- a/src/lib/util/buffer.h
+++ b/src/lib/util/buffer.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __BUFFER_H
-#define __BUFFER_H 1
+#ifndef BUFFER_H
+#define BUFFER_H 1
#include <stdlib.h>
#include <cstring>
@@ -535,7 +535,7 @@ typedef boost::shared_ptr<OutputBuffer> OutputBufferPtr;
} // namespace util
} // namespace isc
-#endif // __BUFFER_H
+#endif // BUFFER_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/encode/base32hex.h b/src/lib/util/encode/base32hex.h
index d7129d7..83fd0d3 100644
--- a/src/lib/util/encode/base32hex.h
+++ b/src/lib/util/encode/base32hex.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __BASE32HEX_H
-#define __BASE32HEX_H 1
+#ifndef BASE32HEX_H
+#define BASE32HEX_H 1
#include <stdint.h>
#include <string>
@@ -57,7 +57,7 @@ void decodeBase32Hex(const std::string& input, std::vector<uint8_t>& result);
} // namespace util
} // namespace isc
-#endif // __BASE32HEX_H
+#endif // BASE32HEX_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/encode/base64.h b/src/lib/util/encode/base64.h
index 6b1b346..1c7c74d 100644
--- a/src/lib/util/encode/base64.h
+++ b/src/lib/util/encode/base64.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __BASE64_H
-#define __BASE64_H 1
+#ifndef BASE64_H
+#define BASE64_H 1
#include <stdint.h>
#include <string>
@@ -72,7 +72,7 @@ void decodeBase64(const std::string& input, std::vector<uint8_t>& result);
} // namespace util
} // namespace isc
-#endif // __BASE64_H
+#endif // BASE64_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/encode/hex.h b/src/lib/util/encode/hex.h
index 5c806fc..32b5071 100644
--- a/src/lib/util/encode/hex.h
+++ b/src/lib/util/encode/hex.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __HEX_H
-#define __HEX_H 1
+#ifndef HEX_H
+#define HEX_H 1
#include <stdint.h>
#include <string>
@@ -58,7 +58,7 @@ void decodeHex(const std::string& input, std::vector<uint8_t>& result);
} // namespace util
} // namespace isc
-#endif // __HEX_H
+#endif // HEX_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/filename.h b/src/lib/util/filename.h
index f625938..a4ba47c 100644
--- a/src/lib/util/filename.h
+++ b/src/lib/util/filename.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __FILENAME_H
-#define __FILENAME_H
+#ifndef FILENAME_H
+#define FILENAME_H
#include <string>
@@ -170,4 +170,4 @@ private:
} // namespace util
} // namespace isc
-#endif // __FILENAME_H
+#endif // FILENAME_H
diff --git a/src/lib/util/hash/sha1.h b/src/lib/util/hash/sha1.h
index 6089ca8..165d93f 100644
--- a/src/lib/util/hash/sha1.h
+++ b/src/lib/util/hash/sha1.h
@@ -30,8 +30,8 @@
* without express or implied warranty of any kind.
*/
-#ifndef _SHA1_H_
-#define _SHA1_H_
+#ifndef SHA1_H
+#define SHA1_H
#include <stdint.h>
diff --git a/src/lib/util/interprocess_sync.h b/src/lib/util/interprocess_sync.h
index e4fa7af..f55f0ac 100644
--- a/src/lib/util/interprocess_sync.h
+++ b/src/lib/util/interprocess_sync.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __INTERPROCESS_SYNC_H__
-#define __INTERPROCESS_SYNC_H__
+#ifndef INTERPROCESS_SYNC_H
+#define INTERPROCESS_SYNC_H
#include <string>
@@ -146,4 +146,4 @@ protected:
} // namespace util
} // namespace isc
-#endif // __INTERPROCESS_SYNC_H__
+#endif // INTERPROCESS_SYNC_H
diff --git a/src/lib/util/interprocess_sync_file.h b/src/lib/util/interprocess_sync_file.h
index fd8da1b..153b391 100644
--- a/src/lib/util/interprocess_sync_file.h
+++ b/src/lib/util/interprocess_sync_file.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __INTERPROCESS_SYNC_FILE_H__
-#define __INTERPROCESS_SYNC_FILE_H__
+#ifndef INTERPROCESS_SYNC_FILE_H
+#define INTERPROCESS_SYNC_FILE_H
#include <util/interprocess_sync.h>
#include <exceptions/exceptions.h>
@@ -88,4 +88,4 @@ private:
} // namespace util
} // namespace isc
-#endif // __INTERPROCESS_SYNC_FILE_H__
+#endif // INTERPROCESS_SYNC_FILE_H
diff --git a/src/lib/util/interprocess_sync_null.h b/src/lib/util/interprocess_sync_null.h
index 6ac0322..be77514 100644
--- a/src/lib/util/interprocess_sync_null.h
+++ b/src/lib/util/interprocess_sync_null.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __INTERPROCESS_SYNC_NULL_H__
-#define __INTERPROCESS_SYNC_NULL_H__
+#ifndef INTERPROCESS_SYNC_NULL_H
+#define INTERPROCESS_SYNC_NULL_H
#include <util/interprocess_sync.h>
@@ -61,4 +61,4 @@ protected:
} // namespace util
} // namespace isc
-#endif // __INTERPROCESS_SYNC_NULL_H__
+#endif // INTERPROCESS_SYNC_NULL_H
diff --git a/src/lib/util/io/fd.h b/src/lib/util/io/fd.h
index bdd2d41..e90e16e 100644
--- a/src/lib/util/io/fd.h
+++ b/src/lib/util/io/fd.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __UTIL_IO_FD_H
-#define __UTIL_IO_FD_H 1
+#ifndef UTIL_IO_FD_H
+#define UTIL_IO_FD_H 1
#include <unistd.h>
@@ -58,4 +58,4 @@ read_data(const int fd, void *buffer, const size_t length);
}
}
-#endif // __UTIL_IO_FD_H
+#endif // UTIL_IO_FD_H
diff --git a/src/lib/util/io/pktinfo_utilities.h b/src/lib/util/io/pktinfo_utilities.h
index 9883c30..74dc37d 100644
--- a/src/lib/util/io/pktinfo_utilities.h
+++ b/src/lib/util/io/pktinfo_utilities.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PKTINFO_UTIL_H_
-#define __PKTINFO_UTIL_H_ 1
+#ifndef PKTINFO_UTIL_H
+#define PKTINFO_UTIL_H 1
#include <sys/socket.h>
#include <netinet/in.h>
@@ -48,4 +48,4 @@ convertPktInfo6(unsigned char* pktinfo) {
}
}
-#endif // __PKTINFO_UTIL_H_
+#endif // PKTINFO_UTIL_H
diff --git a/src/lib/util/io/sockaddr_util.h b/src/lib/util/io/sockaddr_util.h
index 0cd7c7b..847a0cb 100644
--- a/src/lib/util/io/sockaddr_util.h
+++ b/src/lib/util/io/sockaddr_util.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __SOCKADDR_UTIL_H_
-#define __SOCKADDR_UTIL_H_ 1
+#ifndef SOCKADDR_UTIL_H
+#define SOCKADDR_UTIL_H 1
#include <sys/types.h>
#include <sys/socket.h>
@@ -77,7 +77,7 @@ convertSockAddr(struct sockaddr* sa) {
}
}
-#endif // __SOCKADDR_UTIL_H_
+#endif // SOCKADDR_UTIL_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/io/socketsession.h b/src/lib/util/io/socketsession.h
index 48b7f19..023ef8e 100644
--- a/src/lib/util/io/socketsession.h
+++ b/src/lib/util/io/socketsession.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __SOCKETSESSION_H_
-#define __SOCKETSESSION_H_ 1
+#ifndef SOCKETSESSION_H
+#define SOCKETSESSION_H 1
#include <boost/noncopyable.hpp>
@@ -492,7 +492,7 @@ private:
}
}
-#endif // __SOCKETSESSION_H_
+#endif // SOCKETSESSION_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/io_utilities.h b/src/lib/util/io_utilities.h
index 61d4c9c..cd35364 100644
--- a/src/lib/util/io_utilities.h
+++ b/src/lib/util/io_utilities.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __IO_UTILITIES_H
-#define __IO_UTILITIES_H
+#ifndef IO_UTILITIES_H
+#define IO_UTILITIES_H
#include <cstddef>
@@ -101,4 +101,4 @@ writeUint32(uint32_t value, uint8_t* buffer) {
} // namespace util
} // namespace isc
-#endif // __ASIOLINK_UTILITIES_H
+#endif // IO_UTILITIES_H
diff --git a/src/lib/util/locks.h b/src/lib/util/locks.h
index f33ff96..34296f2 100644
--- a/src/lib/util/locks.h
+++ b/src/lib/util/locks.h
@@ -23,8 +23,8 @@
/// to be set. we might want to enfore this at compile time with a check
/// (TODO)
-#ifndef __LOCKS_
-#define __LOCKS_
+#ifndef LOCKS
+#define LOCKS
namespace isc {
namespace util {
@@ -62,4 +62,4 @@ public:
} // namespace util
} // namespace isc
-#endif // __LOCKS_
+#endif // LOCKS
diff --git a/src/lib/util/lru_list.h b/src/lib/util/lru_list.h
index 797c3c9..e5db869 100644
--- a/src/lib/util/lru_list.h
+++ b/src/lib/util/lru_list.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LRU_LIST_H
-#define __LRU_LIST_H
+#ifndef LRU_LIST_H
+#define LRU_LIST_H
#include <list>
#include <string>
@@ -257,4 +257,4 @@ void LruList<T>::clear() {
} // namespace util
} // namespace isc
-#endif // __LRU_LIST_H
+#endif // LRU_LIST_H
diff --git a/src/lib/util/memory_segment.h b/src/lib/util/memory_segment.h
index 97d2e02..664bd3c 100644
--- a/src/lib/util/memory_segment.h
+++ b/src/lib/util/memory_segment.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MEMORY_SEGMENT_H__
-#define __MEMORY_SEGMENT_H__
+#ifndef MEMORY_SEGMENT_H
+#define MEMORY_SEGMENT_H
#include <stdlib.h>
@@ -66,4 +66,4 @@ public:
} // namespace util
} // namespace isc
-#endif // __MEMORY_SEGMENT_H__
+#endif // MEMORY_SEGMENT_H
diff --git a/src/lib/util/memory_segment_local.h b/src/lib/util/memory_segment_local.h
index 5e43e53..de35b87 100644
--- a/src/lib/util/memory_segment_local.h
+++ b/src/lib/util/memory_segment_local.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __MEMORY_SEGMENT_LOCAL_H__
-#define __MEMORY_SEGMENT_LOCAL_H__
+#ifndef MEMORY_SEGMENT_LOCAL_H
+#define MEMORY_SEGMENT_LOCAL_H
#include <util/memory_segment.h>
@@ -73,4 +73,4 @@ private:
} // namespace util
} // namespace isc
-#endif // __MEMORY_SEGMENT_LOCAL_H__
+#endif // MEMORY_SEGMENT_LOCAL_H
diff --git a/src/lib/util/python/pycppwrapper_util.h b/src/lib/util/python/pycppwrapper_util.h
index 462e715..31041ba 100644
--- a/src/lib/util/python/pycppwrapper_util.h
+++ b/src/lib/util/python/pycppwrapper_util.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYCPPWRAPPER_UTIL_H
-#define __PYCPPWRAPPER_UTIL_H 1
+#ifndef PYCPPWRAPPER_UTIL_H
+#define PYCPPWRAPPER_UTIL_H 1
#include <Python.h>
@@ -328,7 +328,7 @@ installClassVariable(PyTypeObject& pyclass, const char* name, PyObject* obj) {
} // namespace python
} // namespace util
} // namespace isc
-#endif // __PYCPPWRAPPER_UTIL_H
+#endif // PYCPPWRAPPER_UTIL_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/python/wrapper_template.h b/src/lib/util/python/wrapper_template.h
index be701e1..787a296 100644
--- a/src/lib/util/python/wrapper_template.h
+++ b/src/lib/util/python/wrapper_template.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PYTHON_ at CPPCLASS@_H
-#define __PYTHON_ at CPPCLASS@_H 1
+#ifndef PYTHON_ at CPPCLASS@_H
+#define PYTHON_ at CPPCLASS@_H 1
#include <Python.h>
@@ -52,7 +52,7 @@ PyObject* create at CPPCLASS@Object(const @CPPCLASS@& source);
} // namespace python
} // namespace @MODULE@
} // namespace isc
-#endif // __PYTHON_ at CPPCLASS@_H
+#endif // PYTHON_ at CPPCLASS@_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/random/qid_gen.h b/src/lib/util/random/qid_gen.h
index 1af43c1..80f532f 100644
--- a/src/lib/util/random/qid_gen.h
+++ b/src/lib/util/random/qid_gen.h
@@ -18,8 +18,8 @@
// (and other parts where we need randomness, perhaps another thing
// for a general libutil?)
-#ifndef __QID_GEN_H
-#define __QID_GEN_H
+#ifndef QID_GEN_H
+#define QID_GEN_H
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
@@ -84,4 +84,4 @@ private:
} // namespace util
} // namespace isc
-#endif // __QID_GEN_H
+#endif // QID_GEN_H
diff --git a/src/lib/util/random/random_number_generator.h b/src/lib/util/random/random_number_generator.h
index 485ea7a..f0c0fb3 100644
--- a/src/lib/util/random/random_number_generator.h
+++ b/src/lib/util/random/random_number_generator.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __NSAS_RANDOM_NUMBER_GENERATOR_H
-#define __NSAS_RANDOM_NUMBER_GENERATOR_H
+#ifndef NSAS_RANDOM_NUMBER_GENERATOR_H
+#define NSAS_RANDOM_NUMBER_GENERATOR_H
#include <algorithm>
#include <cmath>
@@ -205,4 +205,4 @@ private:
} // namespace util
} // namespace isc
-#endif//__NSAS_RANDOM_NUMBER_GENERATOR_H
+#endif//NSAS_RANDOM_NUMBER_GENERATOR_H
diff --git a/src/lib/util/range_utilities.h b/src/lib/util/range_utilities.h
index 3f8b971..4d5b0bb 100644
--- a/src/lib/util/range_utilities.h
+++ b/src/lib/util/range_utilities.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __RANGE_UTIL_H_
-#define __RANGE_UTIL_H_ 1
+#ifndef RANGE_UTIL_H
+#define RANGE_UTIL_H 1
#include <stdlib.h>
#include <algorithm>
@@ -41,16 +41,17 @@ isRangeZero(Iterator begin, Iterator end) {
/// @brief Fill in specified range with a random data.
///
-/// Make sure that random number generator is initialized properly. Otherwise you
-/// will get a the same pseudo-random sequence after every start of your process.
-/// Calling srand() is enough. This method uses default rand(), which is usually
-/// a LCG pseudo-random number generator, so it is not suitable for security
-/// purposes. Please get a decent PRNG implementation, like mersene twister, if
-/// you are doing anything related with security.
+/// Make sure that random number generator is initialized
+/// properly. Otherwise you will get a the same pseudo-random sequence
+/// after every start of your process. Calling srand() is enough. This
+/// method uses default rand(), which is usually a LCG pseudo-random
+/// number generator, so it is not suitable for security
+/// purposes. Please get a decent PRNG implementation, like mersene
+/// twister, if you are doing anything related with security.
///
-/// PRNG initialization is left out of this function on purpose. It may be
-/// initialized to specific value on purpose, e.g. to repeat exactly the same
-/// sequence in a test.
+/// PRNG initialization is left out of this function on purpose. It may
+/// be initialized to specific value on purpose, e.g. to repeat exactly
+/// the same sequence in a test.
///
/// @param begin
/// @param end
@@ -65,4 +66,4 @@ fillRandom(Iterator begin, Iterator end) {
} // end of isc::util namespace
} // end of isc namespace
-#endif // __PKTINFO_UTIL_H_
+#endif // RANGE_UTIL_H
diff --git a/src/lib/util/strutil.h b/src/lib/util/strutil.h
index 0dbbe96..6b60009 100644
--- a/src/lib/util/strutil.h
+++ b/src/lib/util/strutil.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __STRUTIL_H
-#define __STRUTIL_H
+#ifndef STRUTIL_H
+#define STRUTIL_H
#include <algorithm>
#include <cctype>
@@ -206,4 +206,4 @@ tokenToNum(const std::string& num_token) {
} // namespace util
} // namespace isc
-#endif // __STRUTIL_H
+#endif // STRUTIL_H
diff --git a/src/lib/util/threads/sync.cc b/src/lib/util/threads/sync.cc
index c98a7a6..46a5646 100644
--- a/src/lib/util/threads/sync.cc
+++ b/src/lib/util/threads/sync.cc
@@ -12,6 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include "config.h"
+
#include "sync.h"
#include <exceptions/exceptions.h>
@@ -31,12 +33,16 @@ namespace thread {
class Mutex::Impl {
public:
- Impl() :
- locked_count(0)
+ Impl()
+#ifdef ENABLE_DEBUG
+ : locked_count(0)
+#endif // ENABLE_DEBUG
{}
+
pthread_mutex_t mutex;
- // Only in debug mode
+#ifdef ENABLE_DEBUG
size_t locked_count;
+#endif // ENABLE_DEBUG
};
namespace {
@@ -70,12 +76,20 @@ Mutex::Mutex() :
isc_throw(isc::InvalidOperation, std::strerror(result));
}
Deinitializer deinitializer(attributes);
- // TODO: Distinguish if debug mode is enabled in compilation.
- // If so, it should be PTHREAD_MUTEX_NORMAL or NULL
+
+ // If debug mode is enabled in compilation, use the slower
+ // error-checking mutexes that detect deadlocks. Otherwise, use fast
+ // mutexes which don't. See the pthread_mutexattr_settype() POSIX
+ // documentation which describes these type attributes.
+#ifdef ENABLE_DEBUG
result = pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_ERRORCHECK);
+#else
+ result = pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_NORMAL);
+#endif // ENABLE_DEBUG
if (result != 0) {
isc_throw(isc::InvalidOperation, std::strerror(result));
}
+
auto_ptr<Impl> impl(new Impl);
result = pthread_mutex_init(&impl->mutex, &attributes);
switch (result) {
@@ -93,12 +107,17 @@ Mutex::Mutex() :
Mutex::~Mutex() {
if (impl_ != NULL) {
const int result = pthread_mutex_destroy(&impl_->mutex);
+
+#ifdef ENABLE_DEBUG
const bool locked = impl_->locked_count != 0;
+#endif // ENABLE_DEBUG
+
delete impl_;
// We don't want to throw from the destructor. Also, if this ever
// fails, something is really screwed up a lot.
assert(result == 0);
+#ifdef ENABLE_DEBUG
// We should not try to destroy a locked mutex, bad threaded monsters
// could get loose if we ever do and it is also forbidden by pthreads.
@@ -106,29 +125,19 @@ Mutex::~Mutex() {
// pthread_mutex_destroy should check for it already. But it seems
// there are systems that don't check it.
assert(!locked);
+#endif // ENABLE_DEBUG
}
}
+#ifdef ENABLE_DEBUG
+
void
Mutex::postLockAction() {
- // This assertion would fail only in non-debugging mode, in which case
- // this method wouldn't be called either, so we simply assert the
- // condition.
assert(impl_->locked_count == 0);
++impl_->locked_count;
}
void
-Mutex::lock() {
- assert(impl_ != NULL);
- const int result = pthread_mutex_lock(&impl_->mutex);
- if (result != 0) {
- isc_throw(isc::InvalidOperation, std::strerror(result));
- }
- postLockAction(); // Only in debug mode
-}
-
-void
Mutex::preUnlockAction(bool throw_ok) {
if (impl_->locked_count == 0) {
if (throw_ok) {
@@ -141,20 +150,35 @@ Mutex::preUnlockAction(bool throw_ok) {
--impl_->locked_count;
}
+bool
+Mutex::locked() const {
+ return (impl_->locked_count != 0);
+}
+
+#endif // ENABLE_DEBUG
+
+void
+Mutex::lock() {
+ assert(impl_ != NULL);
+ const int result = pthread_mutex_lock(&impl_->mutex);
+ if (result != 0) {
+ isc_throw(isc::InvalidOperation, std::strerror(result));
+ }
+#ifdef ENABLE_DEBUG
+ postLockAction(); // Only in debug mode
+#endif // ENABLE_DEBUG
+}
+
void
Mutex::unlock() {
assert(impl_ != NULL);
+#ifdef ENABLE_DEBUG
preUnlockAction(false); // Only in debug mode. Ensure no throw.
+#endif // ENABLE_DEBUG
const int result = pthread_mutex_unlock(&impl_->mutex);
assert(result == 0); // This should never be possible
}
-// TODO: Disable in non-debug build
-bool
-Mutex::locked() const {
- return (impl_->locked_count != 0);
-}
-
class CondVar::Impl {
public:
Impl() {
@@ -187,10 +211,13 @@ CondVar::~CondVar() {
void
CondVar::wait(Mutex& mutex) {
+#ifdef ENABLE_DEBUG
mutex.preUnlockAction(true); // Only in debug mode
const int result = pthread_cond_wait(&impl_->cond_, &mutex.impl_->mutex);
mutex.postLockAction(); // Only in debug mode
-
+#else
+ const int result = pthread_cond_wait(&impl_->cond_, &mutex.impl_->mutex);
+#endif
// pthread_cond_wait should normally succeed unless mutex is completely
// broken.
if (result != 0) {
diff --git a/src/lib/util/threads/sync.h b/src/lib/util/threads/sync.h
index ff56999..87c78be 100644
--- a/src/lib/util/threads/sync.h
+++ b/src/lib/util/threads/sync.h
@@ -112,6 +112,9 @@ private:
// Commonly called after acquiring the lock, checking and updating
// internal state for debug.
+ //
+ // Note that this method is only available when the build is
+ // configured with debugging support.
void postLockAction();
// Commonly called before releasing the lock, checking and updating
@@ -121,6 +124,9 @@ private:
// fails; otherwise it aborts the process. This parameter must be set
// to false if the call to this shouldn't result in an exception (e.g.
// when called from a destructor).
+ //
+ // Note that this method is only available when the build is
+ // configured with debugging support.
void preUnlockAction(bool throw_ok);
class Impl;
diff --git a/src/lib/util/threads/tests/condvar_unittest.cc b/src/lib/util/threads/tests/condvar_unittest.cc
index 77a8980..1e04efa 100644
--- a/src/lib/util/threads/tests/condvar_unittest.cc
+++ b/src/lib/util/threads/tests/condvar_unittest.cc
@@ -12,6 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <config.h>
+
#include <exceptions/exceptions.h>
#include <util/threads/sync.h>
@@ -137,8 +139,8 @@ signalAndWait(CondVar* condvar, Mutex* mutex) {
condvar->wait(*mutex);
}
-// Temporarily disabled: Solaris seems to make this behavior "undefined"
-TEST_F(CondVarTest, DISABLED_destroyWhileWait) {
+#ifndef HAS_UNDEFINED_PTHREAD_BEHAVIOR
+TEST_F(CondVarTest, destroyWhileWait) {
// We'll destroy a CondVar object while the thread is still waiting
// on it. This will trigger an assertion failure.
EXPECT_DEATH_IF_SUPPORTED({
@@ -148,12 +150,17 @@ TEST_F(CondVarTest, DISABLED_destroyWhileWait) {
cond.wait(mutex_);
}, "");
}
+#endif // !HAS_UNDEFINED_PTHREAD_BEHAVIOR
+
+#ifdef ENABLE_DEBUG
TEST_F(CondVarTest, badWait) {
// In our implementation, wait() requires acquiring the lock beforehand.
EXPECT_THROW(condvar_.wait(mutex_), isc::InvalidOperation);
}
+#endif // ENABLE_DEBUG
+
TEST_F(CondVarTest, emptySignal) {
// It's okay to call signal when no one waits.
EXPECT_NO_THROW(condvar_.signal());
diff --git a/src/lib/util/threads/tests/lock_unittest.cc b/src/lib/util/threads/tests/lock_unittest.cc
index 9c17e6f..1abc3fa 100644
--- a/src/lib/util/threads/tests/lock_unittest.cc
+++ b/src/lib/util/threads/tests/lock_unittest.cc
@@ -12,6 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <config.h>
+
#include <gtest/gtest.h>
#include <util/threads/sync.h>
@@ -26,25 +28,31 @@ using namespace isc::util::thread;
namespace {
-// If we try to lock the debug mutex multiple times, it should throw.
+#ifdef ENABLE_DEBUG
+
+// If we try to lock the debug mutex multiple times, it should
+// throw. This test will complete properly only when pthread debugging
+// facilities are enabled by configuring the code for debug build.
TEST(MutexTest, lockMultiple) {
- // TODO: Once we support non-debug mutexes, disable the test if we compile
- // with them.
Mutex mutex;
EXPECT_FALSE(mutex.locked()); // Debug-only build
+
Mutex::Locker l1(mutex);
EXPECT_TRUE(mutex.locked()); // Debug-only build
+
EXPECT_THROW({
Mutex::Locker l2(mutex); // Attempt to lock again.
}, isc::InvalidOperation);
EXPECT_TRUE(mutex.locked()); // Debug-only build
}
+#endif // ENABLE_DEBUG
+
+#ifndef HAS_UNDEFINED_PTHREAD_BEHAVIOR
// Destroying a locked mutex is a bad idea as well
-#ifdef EXPECT_DEATH
TEST(MutexTest, destroyLocked) {
if (!isc::util::unittests::runningOnValgrind()) {
- EXPECT_DEATH({
+ EXPECT_DEATH_IF_SUPPORTED({
Mutex* mutex = new Mutex;
new Mutex::Locker(*mutex);
delete mutex;
@@ -53,7 +61,7 @@ TEST(MutexTest, destroyLocked) {
}, "");
}
}
-#endif
+#endif // !HAS_UNDEFINED_PTHREAD_BEHAVIOR
// In this test, we try to check if a mutex really locks. We could try that
// with a deadlock, but that's not practical (the test would not end).
diff --git a/src/lib/util/time_utilities.h b/src/lib/util/time_utilities.h
index a53089d..479f055 100644
--- a/src/lib/util/time_utilities.h
+++ b/src/lib/util/time_utilities.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TIME_UTILITIES_H
-#define __TIME_UTILITIES_H 1
+#ifndef TIME_UTILITIES_H
+#define TIME_UTILITIES_H 1
#include <string>
@@ -32,7 +32,7 @@ namespace isc {
namespace util {
///
-/// \brief A standard DNS (or ISC) module exception that is thrown if
+/// \brief A standard DNS (or ISC) module exception that is thrown if
/// a time conversion function encounters bad input
///
class InvalidTime : public Exception {
@@ -166,7 +166,7 @@ timeToText32(const uint32_t value);
}
}
-#endif // __DNSSECTIME_H
+#endif // TIME_UTILITIES_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/unittests/check_valgrind.h b/src/lib/util/unittests/check_valgrind.h
index c08b58b..80f1f85 100644
--- a/src/lib/util/unittests/check_valgrind.h
+++ b/src/lib/util/unittests/check_valgrind.h
@@ -27,8 +27,8 @@
// natively
//
-#ifndef __UTIL_UNITTESTS_CHECK_VALGRIND_H
-#define __UTIL_UNITTESTS_CHECK_VALGRIND_H 1
+#ifndef UTIL_UNITTESTS_CHECK_VALGRIND_H
+#define UTIL_UNITTESTS_CHECK_VALGRIND_H 1
#include <config.h>
@@ -47,4 +47,4 @@ bool runningOnValgrind();
} // end namespace util
} // end namespace isc
-#endif // __UTIL_UNITTESTS_CHECK_VALGRIND_H
+#endif // UTIL_UNITTESTS_CHECK_VALGRIND_H
diff --git a/src/lib/util/unittests/fork.h b/src/lib/util/unittests/fork.h
index 2d27a11..d5623a7 100644
--- a/src/lib/util/unittests/fork.h
+++ b/src/lib/util/unittests/fork.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __UTIL_UNITTESTS_FORK_H
-#define __UTIL_UNITTESTS_FORK_H 1
+#ifndef UTIL_UNITTESTS_FORK_H
+#define UTIL_UNITTESTS_FORK_H 1
#include <unistd.h>
@@ -49,4 +49,4 @@ check_output(int *write_pipe, const void *output, const size_t length);
}
}
-#endif // __UTIL_UNITTESTS_FORK_H
+#endif // UTIL_UNITTESTS_FORK_H
diff --git a/src/lib/util/unittests/mock_socketsession.h b/src/lib/util/unittests/mock_socketsession.h
index 8078265..01ca34f 100644
--- a/src/lib/util/unittests/mock_socketsession.h
+++ b/src/lib/util/unittests/mock_socketsession.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __UTIL_UNITTESTS_MOCKSOCKETSESSION_H
-#define __UTIL_UNITTESTS_MOCKSOCKETSESSION_H 1
+#ifndef UTIL_UNITTESTS_MOCKSOCKETSESSION_H
+#define UTIL_UNITTESTS_MOCKSOCKETSESSION_H 1
#include <exceptions/exceptions.h>
@@ -147,7 +147,7 @@ private:
} // end of unittests
} // end of util
} // end of isc
-#endif // __UTIL_UNITTESTS_MOCKSOCKETSESSION_H
+#endif // UTIL_UNITTESTS_MOCKSOCKETSESSION_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/unittests/newhook.h b/src/lib/util/unittests/newhook.h
index c90751e..d2c1385 100644
--- a/src/lib/util/unittests/newhook.h
+++ b/src/lib/util/unittests/newhook.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __UTIL_UNITTESTS_NEWHOOK_H
-#define __UTIL_UNITTESTS_NEWHOOK_H 1
+#ifndef UTIL_UNITTESTS_NEWHOOK_H
+#define UTIL_UNITTESTS_NEWHOOK_H 1
/**
* \file newhook.h
@@ -75,7 +75,7 @@ extern size_t throw_size_on_new;
}
}
-#endif // __UTIL_UNITTESTS_NEWHOOK_H
+#endif // UTIL_UNITTESTS_NEWHOOK_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/unittests/resource.h b/src/lib/util/unittests/resource.h
index 6430ab2..5a266b2 100644
--- a/src/lib/util/unittests/resource.h
+++ b/src/lib/util/unittests/resource.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __UTIL_UNITTESTS_RESOURCE_H
-#define __UTIL_UNITTESTS_RESOURCE_H 1
+#ifndef UTIL_UNITTESTS_RESOURCE_H
+#define UTIL_UNITTESTS_RESOURCE_H 1
namespace isc {
namespace util {
@@ -32,7 +32,7 @@ void dontCreateCoreDumps();
} // end of namespace util
} // end of namespace isc
-#endif /* __UTIL_UNITTESTS_RESOURCE_H */
+#endif // UTIL_UNITTESTS_RESOURCE_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/unittests/run_all.h b/src/lib/util/unittests/run_all.h
index 94c7cb0..2335df7 100644
--- a/src/lib/util/unittests/run_all.h
+++ b/src/lib/util/unittests/run_all.h
@@ -14,8 +14,8 @@
-#ifndef __RUN_ALL_H
-#define __RUN_ALL_H
+#ifndef RUN_ALL_H
+#define RUN_ALL_H
// Avoid need for user to include this header file.
@@ -49,4 +49,4 @@ int run_all();
-#endif // __RUN_ALL_H
+#endif // RUN_ALL_H
diff --git a/src/lib/util/unittests/testdata.h b/src/lib/util/unittests/testdata.h
index a452dc6..c7ee707 100644
--- a/src/lib/util/unittests/testdata.h
+++ b/src/lib/util/unittests/testdata.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __UTIL_UNITTESTS_TESTDATA_H
-#define __UTIL_UNITTESTS_TESTDATA_H 1
+#ifndef UTIL_UNITTESTS_TESTDATA_H
+#define UTIL_UNITTESTS_TESTDATA_H 1
/**
* \file testdata.h
@@ -47,7 +47,7 @@ void openTestData(const char* const datafile, std::ifstream& ifs);
}
}
-#endif // __UTIL_UNITTESTS_TESTDATA_H
+#endif // UTIL_UNITTESTS_TESTDATA_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/unittests/textdata.h b/src/lib/util/unittests/textdata.h
index 3e5fe0f..50d09ea 100644
--- a/src/lib/util/unittests/textdata.h
+++ b/src/lib/util/unittests/textdata.h
@@ -18,8 +18,8 @@
#include <gtest/gtest.h>
-#ifndef __UTIL_UNITTESTS_TEXTDATA_H
-#define __UTIL_UNITTESTS_TEXTDATA_H 1
+#ifndef UTIL_UNITTESTS_TEXTDATA_H
+#define UTIL_UNITTESTS_TEXTDATA_H 1
/**
* \file textdata.h
@@ -96,7 +96,7 @@ matchTextData(const std::string& expected_text,
}
}
-#endif // __UTIL_UNITTESTS_TEXTDATA_H
+#endif // UTIL_UNITTESTS_TEXTDATA_H
// Local Variables:
// mode: c++
diff --git a/src/lib/util/unittests/wiredata.h b/src/lib/util/unittests/wiredata.h
index a33a03a..a8c519e 100644
--- a/src/lib/util/unittests/wiredata.h
+++ b/src/lib/util/unittests/wiredata.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __UTIL_UNITTESTS_WIREDATA_H
-#define __UTIL_UNITTESTS_WIREDATA_H 1
+#ifndef UTIL_UNITTESTS_WIREDATA_H
+#define UTIL_UNITTESTS_WIREDATA_H 1
#include <cstddef>
@@ -38,7 +38,7 @@ void matchWireData(const void* expected_data, std::size_t expected_len,
}
}
-#endif // __UTIL_UNITTESTS_WIREDATA_H
+#endif // UTIL_UNITTESTS_WIREDATA_H
// Local Variables:
// mode: c++
diff --git a/src/lib/xfr/xfrout_client.h b/src/lib/xfr/xfrout_client.h
index bad963c..e691fb1 100644
--- a/src/lib/xfr/xfrout_client.h
+++ b/src/lib/xfr/xfrout_client.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef _XFROUT_CLIENT_H
-#define _XFROUT_CLIENT_H
+#ifndef XFROUT_CLIENT_H
+#define XFROUT_CLIENT_H
#include <stdint.h>
diff --git a/tests/lettuce/configurations/auth/.gitignore b/tests/lettuce/configurations/auth/.gitignore
new file mode 100644
index 0000000..07f1b7d
--- /dev/null
+++ b/tests/lettuce/configurations/auth/.gitignore
@@ -0,0 +1 @@
+/auth_basic.config
diff --git a/tests/lettuce/configurations/auth/auth_basic.config.orig b/tests/lettuce/configurations/auth/auth_basic.config.orig
new file mode 100644
index 0000000..4067fb1
--- /dev/null
+++ b/tests/lettuce/configurations/auth/auth_basic.config.orig
@@ -0,0 +1,22 @@
+{
+ "version": 2,
+ "Logging": {
+ "loggers": [ {
+ "debuglevel": 99,
+ "severity": "DEBUG",
+ "name": "*"
+ } ]
+ },
+ "Auth": {
+ "listen_on": [ {
+ "port": 47806,
+ "address": "127.0.0.1"
+ } ]
+ },
+ "Boss": {
+ "components": {
+ "b10-auth": { "kind": "needed", "special": "auth" },
+ "b10-cmdctl": { "special": "cmdctl", "kind": "needed" }
+ }
+ }
+}
diff --git a/tests/lettuce/features/auth_basic.feature b/tests/lettuce/features/auth_basic.feature
new file mode 100644
index 0000000..4667b64
--- /dev/null
+++ b/tests/lettuce/features/auth_basic.feature
@@ -0,0 +1,20 @@
+Feature: Basic Authoritative DNS server
+ This feature set is for testing the execution of the b10-auth
+ component using its default datasource configurations. This
+ will start it and perform queries against it.
+
+ Scenario: Query builtin bind zone
+ Given I have bind10 running with configuration auth/auth_basic.config
+ And wait for bind10 stderr message BIND10_STARTED_CC
+ And wait for bind10 stderr message CMDCTL_STARTED
+ And wait for bind10 stderr message AUTH_SERVER_STARTED
+
+ bind10 module Auth should be running
+ And bind10 module Resolver should not be running
+
+ A query for example.com should have rcode REFUSED
+ A query for version.bind type TXT class CH should have rcode NOERROR
+ A query for authors.bind type TXT class CH should have rcode NOERROR
+
+ # TODO: to be compatible with BIND 9
+ # A query for nonexistent.bind type TXT class CH should have rcode REFUSED
diff --git a/tests/lettuce/features/ddns_system.feature b/tests/lettuce/features/ddns_system.feature
index ee3187c..8e279a7 100644
--- a/tests/lettuce/features/ddns_system.feature
+++ b/tests/lettuce/features/ddns_system.feature
@@ -39,7 +39,7 @@ Feature: DDNS System
# Test 5
When I use DDNS to set the SOA serial to 1237
# also check if Auth server reloaded
- And wait for new bind10 stderr message AUTH_LOAD_ZONE
+ And wait for new bind10 stderr message AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE
The DDNS response should be SUCCESS
And the SOA serial for example.org should be 1237
@@ -53,11 +53,12 @@ Feature: DDNS System
# Test 8
When I use DDNS to set the SOA serial to 1238
+ And wait for new bind10 stderr message AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE
The DDNS response should be SUCCESS
And the SOA serial for example.org should be 1238
When I use DDNS to set the SOA serial to 1239
- And wait for new bind10 stderr message AUTH_LOAD_ZONE
+ And wait for new bind10 stderr message AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE
The DDNS response should be SUCCESS
And the SOA serial for example.org should be 1239
@@ -69,7 +70,7 @@ Feature: DDNS System
# Test 10
When I use DDNS to set the SOA serial to 1240
- And wait for new bind10 stderr message AUTH_LOAD_ZONE
+ And wait for new bind10 stderr message AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE
The DDNS response should be SUCCESS
And the SOA serial for example.org should be 1240
diff --git a/tests/lettuce/features/inmemory_over_sqlite3.feature b/tests/lettuce/features/inmemory_over_sqlite3.feature
index 851caca..7d8ad6d 100644
--- a/tests/lettuce/features/inmemory_over_sqlite3.feature
+++ b/tests/lettuce/features/inmemory_over_sqlite3.feature
@@ -33,7 +33,7 @@ Feature: In-memory zone using SQLite3 backend
A query for mail.example.org to [::1]:47806 should have rcode NXDOMAIN
When I send bind10 the command Xfrin retransfer example.org IN ::1 47807
Then wait for new bind10 stderr message XFRIN_TRANSFER_SUCCESS not XFRIN_XFR_PROCESS_FAILURE
- Then wait for new bind10 stderr message AUTH_LOAD_ZONE
+ Then wait for new bind10 stderr message AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE
A query for www.example.org to [::1]:47807 should have rcode NOERROR
The answer section of the last query response should be
diff --git a/tests/lettuce/features/terrain/terrain.py b/tests/lettuce/features/terrain/terrain.py
index 8720e2d..2bfe7d4 100644
--- a/tests/lettuce/features/terrain/terrain.py
+++ b/tests/lettuce/features/terrain/terrain.py
@@ -49,6 +49,8 @@ copylist = [
"configurations/example.org.config"],
["configurations/bindctl/bindctl.config.orig",
"configurations/bindctl/bindctl.config"],
+ ["configurations/auth/auth_basic.config.orig",
+ "configurations/auth/auth_basic.config"],
["configurations/resolver/resolver_basic.config.orig",
"configurations/resolver/resolver_basic.config"],
["configurations/multi_instance/multi_auth.config.orig",
diff --git a/tests/tools/badpacket/command_options.h b/tests/tools/badpacket/command_options.h
index fc819e9..c6f2825 100644
--- a/tests/tools/badpacket/command_options.h
+++ b/tests/tools/badpacket/command_options.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __COMMAND_OPTIONS_H
-#define __COMMAND_OPTIONS_H
+#ifndef COMMAND_OPTIONS_H
+#define COMMAND_OPTIONS_H
#include <cstdlib>
#include <stdint.h>
@@ -159,4 +159,4 @@ private:
} // namespace badpacket
} // namespace isc
-#endif // __COMMAND_OPTIONS_H
+#endif // COMMAND_OPTIONS_H
diff --git a/tests/tools/badpacket/header_flags.h b/tests/tools/badpacket/header_flags.h
index 5d74e75..71aa64c 100644
--- a/tests/tools/badpacket/header_flags.h
+++ b/tests/tools/badpacket/header_flags.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __HEADER_FLAGS_H
-#define __HEADER_FLAGS_H
+#ifndef HEADER_FLAGS_H
+#define HEADER_FLAGS_H
#include <exceptions/exceptions.h>
#include "option_info.h"
@@ -99,4 +99,4 @@ private:
} // namespace badpacket
} // namespace isc
-#endif // __HEADER_FLAGS_H
+#endif // HEADER_FLAGS_H
diff --git a/tests/tools/badpacket/option_info.h b/tests/tools/badpacket/option_info.h
index a340c1d..aebeb66 100644
--- a/tests/tools/badpacket/option_info.h
+++ b/tests/tools/badpacket/option_info.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __OPTION_INFO_H
-#define __OPTION_INFO_H
+#ifndef OPTION_INFO_H
+#define OPTION_INFO_H
#include <stdint.h>
#include "exceptions/exceptions.h"
@@ -171,4 +171,4 @@ public:
} // namespace badpacket
} // namespace isc
-#endif // __OPTION_INFO_H
+#endif // OPTION_INFO_H
diff --git a/tests/tools/badpacket/scan.h b/tests/tools/badpacket/scan.h
index ca56646..40b5bf6 100644
--- a/tests/tools/badpacket/scan.h
+++ b/tests/tools/badpacket/scan.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __SCAN_H
-#define __SCAN_H
+#ifndef SCAN_H
+#define SCAN_H
#include <stdint.h>
@@ -195,4 +195,4 @@ private:
} // namespace test
} // namespace isc
-#endif // __SCAN_H
+#endif // SCAN_H
diff --git a/tests/tools/badpacket/version.h b/tests/tools/badpacket/version.h
index dc59b11..9f7f280 100644
--- a/tests/tools/badpacket/version.h
+++ b/tests/tools/badpacket/version.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __VERSION_H
-#define __VERSION_H
+#ifndef VERSION_H
+#define VERSION_H
namespace isc {
namespace badpacket {
@@ -23,4 +23,4 @@ static const char* BADPACKET_VERSION = "1.0-1";
} // namespace badpacket
} // namespace isc
-#endif // __VERSION_H
+#endif // VERSION_H
diff --git a/tests/tools/perfdhcp/command_options.h b/tests/tools/perfdhcp/command_options.h
index 4668f73..cbb6236 100644
--- a/tests/tools/perfdhcp/command_options.h
+++ b/tests/tools/perfdhcp/command_options.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __COMMAND_OPTIONS_H
-#define __COMMAND_OPTIONS_H
+#ifndef COMMAND_OPTIONS_H
+#define COMMAND_OPTIONS_H
#include <string>
#include <vector>
@@ -462,4 +462,4 @@ private:
} // namespace perfdhcp
} // namespace isc
-#endif // __COMMAND_OPTIONS_H
+#endif // COMMAND_OPTIONS_H
diff --git a/tests/tools/perfdhcp/localized_option.h b/tests/tools/perfdhcp/localized_option.h
index 336e083..2aa270a 100644
--- a/tests/tools/perfdhcp/localized_option.h
+++ b/tests/tools/perfdhcp/localized_option.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __LOCALIZED_OPTION_H
-#define __LOCALIZED_OPTION_H
+#ifndef LOCALIZED_OPTION_H
+#define LOCALIZED_OPTION_H
#include <dhcp/pkt6.h>
#include <dhcp/option6_ia.h>
@@ -147,4 +147,4 @@ private:
} // namespace isc::perfdhcp
} // namespace isc
-#endif // __LOCALIZED_OPTION_H
+#endif // LOCALIZED_OPTION_H
diff --git a/tests/tools/perfdhcp/perf_pkt4.h b/tests/tools/perfdhcp/perf_pkt4.h
index 87c7bb0..6f03193 100644
--- a/tests/tools/perfdhcp/perf_pkt4.h
+++ b/tests/tools/perfdhcp/perf_pkt4.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PERF_PKT4_H
-#define __PERF_PKT4_H
+#ifndef PERF_PKT4_H
+#define PERF_PKT4_H
#include <time.h>
#include <boost/shared_ptr.hpp>
@@ -136,4 +136,4 @@ typedef boost::shared_ptr<PerfPkt4> PerfPkt4Ptr;
} // namespace perfdhcp
} // namespace isc
-#endif // __PERF_PKT4_H
+#endif // PERF_PKT4_H
diff --git a/tests/tools/perfdhcp/perf_pkt6.h b/tests/tools/perfdhcp/perf_pkt6.h
index 25fb4e5..9a8d69b 100644
--- a/tests/tools/perfdhcp/perf_pkt6.h
+++ b/tests/tools/perfdhcp/perf_pkt6.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PERF_PKT6_H
-#define __PERF_PKT6_H
+#ifndef PERF_PKT6_H
+#define PERF_PKT6_H
#include <time.h>
#include <boost/shared_ptr.hpp>
@@ -136,4 +136,4 @@ typedef boost::shared_ptr<PerfPkt6> PerfPkt6Ptr;
} // namespace perfdhcp
} // namespace isc
-#endif // __PERF_PKT6_H
+#endif // PERF_PKT6_H
diff --git a/tests/tools/perfdhcp/pkt_transform.h b/tests/tools/perfdhcp/pkt_transform.h
index 1f57105..c94e9ba 100644
--- a/tests/tools/perfdhcp/pkt_transform.h
+++ b/tests/tools/perfdhcp/pkt_transform.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __PKT_TRANSFORM_H
-#define __PKT_TRANSFORM_H
+#ifndef PKT_TRANSFORM_H
+#define PKT_TRANSFORM_H
#include <dhcp/option.h>
@@ -166,4 +166,4 @@ private:
} // namespace perfdhcp
} // namespace isc
-#endif // __PKT_TRANSFORM_H
+#endif // PKT_TRANSFORM_H
diff --git a/tests/tools/perfdhcp/stats_mgr.h b/tests/tools/perfdhcp/stats_mgr.h
index 0c2b68c..537e81d 100644
--- a/tests/tools/perfdhcp/stats_mgr.h
+++ b/tests/tools/perfdhcp/stats_mgr.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __STATS_MGR_H
-#define __STATS_MGR_H
+#ifndef STATS_MGR_H
+#define STATS_MGR_H
#include <iostream>
#include <map>
@@ -1300,4 +1300,4 @@ private:
} // namespace perfdhcp
} // namespace isc
-#endif // __STATS_MGR_H
+#endif // STATS_MGR_H
diff --git a/tests/tools/perfdhcp/test_control.h b/tests/tools/perfdhcp/test_control.h
index 2bd7871..245cf6d 100644
--- a/tests/tools/perfdhcp/test_control.h
+++ b/tests/tools/perfdhcp/test_control.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __TEST_CONTROL_H
-#define __TEST_CONTROL_H
+#ifndef TEST_CONTROL_H
+#define TEST_CONTROL_H
#include <string>
#include <vector>
@@ -97,7 +97,7 @@ static const size_t DHCPV6_IA_NA_OFFSET = 40;
/// accept 'start' and 'stop' arguments. The first time it is called, it is
/// called with the argument 'start' and the second time with the argument
/// 'stop'.
-///
+///
/// The application is executed by calling fork() to fork the current perfdhcp
/// process and then call execlp() to replace the current process image with
/// the new one.
@@ -987,4 +987,4 @@ private:
} // namespace perfdhcp
} // namespace isc
-#endif // __COMMAND_OPTIONS_H
+#endif // TEST_CONTROL_H
diff --git a/tests/tools/perfdhcp/tests/command_options_helper.h b/tests/tools/perfdhcp/tests/command_options_helper.h
index f9f6d36..7436bd7 100644
--- a/tests/tools/perfdhcp/tests/command_options_helper.h
+++ b/tests/tools/perfdhcp/tests/command_options_helper.h
@@ -12,8 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#ifndef __COMMAND_OPTIONS_HELPER_H
-#define __COMMAND_OPTIONS_HELPER_H
+#ifndef COMMAND_OPTIONS_HELPER_H
+#define COMMAND_OPTIONS_HELPER_H
#include <string>
#include <vector>
@@ -136,4 +136,4 @@ private:
} // namespace isc::perfdhcp
} // namespace isc
-#endif // __COMMAND_OPTIONS_HELPER_H
+#endif // COMMAND_OPTIONS_HELPER_H
More information about the bind10-changes
mailing list