replay_driver.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. * replay_driver.c
  3. *
  4. * A driver for the replay_database implementation
  5. *
  6. * David A. McGrew
  7. * Cisco Systems, Inc.
  8. */
  9. /*
  10. *
  11. * Copyright (c) 2001-2006, Cisco Systems, Inc.
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions
  16. * are met:
  17. *
  18. * Redistributions of source code must retain the above copyright
  19. * notice, this list of conditions and the following disclaimer.
  20. *
  21. * Redistributions in binary form must reproduce the above
  22. * copyright notice, this list of conditions and the following
  23. * disclaimer in the documentation and/or other materials provided
  24. * with the distribution.
  25. *
  26. * Neither the name of the Cisco Systems, Inc. nor the names of its
  27. * contributors may be used to endorse or promote products derived
  28. * from this software without specific prior written permission.
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  33. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  34. * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  35. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  37. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  41. * OF THE POSSIBILITY OF SUCH DAMAGE.
  42. *
  43. */
  44. #include <stdio.h>
  45. #include "rdb.h"
  46. #include "ut_sim.h"
  47. /*
  48. * num_trials defines the number of trials that are used in the
  49. * validation functions below
  50. */
  51. unsigned num_trials = 1 << 16;
  52. err_status_t
  53. test_rdb_db(void);
  54. double
  55. rdb_check_adds_per_second(void);
  56. int
  57. main (void) {
  58. err_status_t err;
  59. printf("testing anti-replay database (rdb_t)...\n");
  60. err = test_rdb_db();
  61. if (err) {
  62. printf("failed\n");
  63. exit(1);
  64. }
  65. printf("done\n");
  66. printf("rdb_check/rdb_adds per second: %e\n",
  67. rdb_check_adds_per_second());
  68. return 0;
  69. }
  70. void
  71. print_rdb(rdb_t *rdb) {
  72. printf("rdb: {%u, %s}\n", rdb->window_start, v128_bit_string(&rdb->bitmask));
  73. }
  74. err_status_t
  75. rdb_check_add(rdb_t *rdb, uint32_t idx) {
  76. if (rdb_check(rdb, idx) != err_status_ok) {
  77. printf("rdb_check failed at index %u\n", idx);
  78. return err_status_fail;
  79. }
  80. if (rdb_add_index(rdb, idx) != err_status_ok) {
  81. printf("rdb_add_index failed at index %u\n", idx);
  82. return err_status_fail;
  83. }
  84. return err_status_ok;
  85. }
  86. err_status_t
  87. rdb_check_expect_failure(rdb_t *rdb, uint32_t idx) {
  88. err_status_t err;
  89. err = rdb_check(rdb, idx);
  90. if ((err != err_status_replay_old) && (err != err_status_replay_fail)) {
  91. printf("rdb_check failed at index %u (false positive)\n", idx);
  92. return err_status_fail;
  93. }
  94. return err_status_ok;
  95. }
  96. err_status_t
  97. rdb_check_add_unordered(rdb_t *rdb, uint32_t idx) {
  98. err_status_t rstat;
  99. /* printf("index: %u\n", idx); */
  100. rstat = rdb_check(rdb, idx);
  101. if ((rstat != err_status_ok) && (rstat != err_status_replay_old)) {
  102. printf("rdb_check_add_unordered failed at index %u\n", idx);
  103. return rstat;
  104. }
  105. if (rstat == err_status_replay_old) {
  106. return err_status_ok;
  107. }
  108. if (rdb_add_index(rdb, idx) != err_status_ok) {
  109. printf("rdb_add_index failed at index %u\n", idx);
  110. return err_status_fail;
  111. }
  112. return err_status_ok;
  113. }
  114. err_status_t
  115. test_rdb_db() {
  116. rdb_t rdb;
  117. uint32_t idx, ircvd;
  118. ut_connection utc;
  119. err_status_t err;
  120. if (rdb_init(&rdb) != err_status_ok) {
  121. printf("rdb_init failed\n");
  122. return err_status_init_fail;
  123. }
  124. /* test sequential insertion */
  125. for (idx=0; idx < num_trials; idx++) {
  126. err = rdb_check_add(&rdb, idx);
  127. if (err)
  128. return err;
  129. }
  130. /* test for false positives */
  131. for (idx=0; idx < num_trials; idx++) {
  132. err = rdb_check_expect_failure(&rdb, idx);
  133. if (err)
  134. return err;
  135. }
  136. /* re-initialize */
  137. if (rdb_init(&rdb) != err_status_ok) {
  138. printf("rdb_init failed\n");
  139. return err_status_fail;
  140. }
  141. /* test non-sequential insertion */
  142. ut_init(&utc);
  143. for (idx=0; idx < num_trials; idx++) {
  144. ircvd = ut_next_index(&utc);
  145. err = rdb_check_add_unordered(&rdb, ircvd);
  146. if (err)
  147. return err;
  148. err = rdb_check_expect_failure(&rdb, ircvd);
  149. if (err)
  150. return err;
  151. }
  152. /* re-initialize */
  153. if (rdb_init(&rdb) != err_status_ok) {
  154. printf("rdb_init failed\n");
  155. return err_status_fail;
  156. }
  157. /* test insertion with large gaps */
  158. for (idx=0, ircvd=0; idx < num_trials; idx++, ircvd += (1 << (rand() % 10))) {
  159. err = rdb_check_add(&rdb, ircvd);
  160. if (err)
  161. return err;
  162. err = rdb_check_expect_failure(&rdb, ircvd);
  163. if (err)
  164. return err;
  165. }
  166. /* re-initialize */
  167. if (rdb_init(&rdb) != err_status_ok) {
  168. printf("rdb_init failed\n");
  169. return err_status_fail;
  170. }
  171. /* test loss of first 513 packets */
  172. for (idx=0; idx < num_trials; idx++) {
  173. err = rdb_check_add(&rdb, idx + 513);
  174. if (err)
  175. return err;
  176. }
  177. /* test for false positives */
  178. for (idx=0; idx < num_trials + 513; idx++) {
  179. err = rdb_check_expect_failure(&rdb, idx);
  180. if (err)
  181. return err;
  182. }
  183. return err_status_ok;
  184. }
  185. #include <time.h> /* for clock() */
  186. #include <stdlib.h> /* for random() */
  187. #define REPLAY_NUM_TRIALS 10000000
  188. double
  189. rdb_check_adds_per_second(void) {
  190. uint32_t i;
  191. rdb_t rdb;
  192. clock_t timer;
  193. int failures; /* count number of failures */
  194. if (rdb_init(&rdb) != err_status_ok) {
  195. printf("rdb_init failed\n");
  196. exit(1);
  197. }
  198. timer = clock();
  199. for(i=0; i < REPLAY_NUM_TRIALS; i+=3) {
  200. if (rdb_check(&rdb, i+2) != err_status_ok)
  201. ++failures;
  202. if (rdb_add_index(&rdb, i+2) != err_status_ok)
  203. ++failures;
  204. if (rdb_check(&rdb, i+1) != err_status_ok)
  205. ++failures;
  206. if (rdb_add_index(&rdb, i+1) != err_status_ok)
  207. ++failures;
  208. if (rdb_check(&rdb, i) != err_status_ok)
  209. ++failures;
  210. if (rdb_add_index(&rdb, i) != err_status_ok)
  211. ++failures;
  212. }
  213. timer = clock() - timer;
  214. return (double) CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer;
  215. }