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