OLD | NEW |
| (Empty) |
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 #ifdef HAVE_CONFIG_H | |
47 #include <config.h> | |
48 #endif | |
49 | |
50 #include <stdio.h> | |
51 | |
52 #include "rdb.h" | |
53 #include "ut_sim.h" | |
54 | |
55 /* | |
56 * num_trials defines the number of trials that are used in the | |
57 * validation functions below | |
58 */ | |
59 | |
60 unsigned num_trials = 1 << 16; | |
61 | |
62 err_status_t | |
63 test_rdb_db(void); | |
64 | |
65 double | |
66 rdb_check_adds_per_second(void); | |
67 | |
68 int | |
69 main (void) { | |
70 err_status_t err; | |
71 | |
72 printf("testing anti-replay database (rdb_t)...\n"); | |
73 err = test_rdb_db(); | |
74 if (err) { | |
75 printf("failed\n"); | |
76 exit(1); | |
77 } | |
78 printf("done\n"); | |
79 | |
80 printf("rdb_check/rdb_adds per second: %e\n", | |
81 rdb_check_adds_per_second()); | |
82 | |
83 return 0; | |
84 } | |
85 | |
86 | |
87 void | |
88 print_rdb(rdb_t *rdb) { | |
89 printf("rdb: {%u, %s}\n", rdb->window_start, v128_bit_string(&rdb->bitmask)); | |
90 } | |
91 | |
92 err_status_t | |
93 rdb_check_add(rdb_t *rdb, uint32_t idx) { | |
94 | |
95 if (rdb_check(rdb, idx) != err_status_ok) { | |
96 printf("rdb_check failed at index %u\n", idx); | |
97 return err_status_fail; | |
98 } | |
99 if (rdb_add_index(rdb, idx) != err_status_ok) { | |
100 printf("rdb_add_index failed at index %u\n", idx); | |
101 return err_status_fail; | |
102 } | |
103 | |
104 return err_status_ok; | |
105 } | |
106 | |
107 err_status_t | |
108 rdb_check_expect_failure(rdb_t *rdb, uint32_t idx) { | |
109 err_status_t err; | |
110 | |
111 err = rdb_check(rdb, idx); | |
112 if ((err != err_status_replay_old) && (err != err_status_replay_fail)) { | |
113 printf("rdb_check failed at index %u (false positive)\n", idx); | |
114 return err_status_fail; | |
115 } | |
116 | |
117 return err_status_ok; | |
118 } | |
119 | |
120 err_status_t | |
121 rdb_check_add_unordered(rdb_t *rdb, uint32_t idx) { | |
122 err_status_t rstat; | |
123 | |
124 /* printf("index: %u\n", idx); */ | |
125 rstat = rdb_check(rdb, idx); | |
126 if ((rstat != err_status_ok) && (rstat != err_status_replay_old)) { | |
127 printf("rdb_check_add_unordered failed at index %u\n", idx); | |
128 return rstat; | |
129 } | |
130 if (rstat == err_status_replay_old) { | |
131 return err_status_ok; | |
132 } | |
133 if (rdb_add_index(rdb, idx) != err_status_ok) { | |
134 printf("rdb_add_index failed at index %u\n", idx); | |
135 return err_status_fail; | |
136 } | |
137 | |
138 return err_status_ok; | |
139 } | |
140 | |
141 err_status_t | |
142 test_rdb_db() { | |
143 rdb_t rdb; | |
144 uint32_t idx, ircvd; | |
145 ut_connection utc; | |
146 err_status_t err; | |
147 | |
148 if (rdb_init(&rdb) != err_status_ok) { | |
149 printf("rdb_init failed\n"); | |
150 return err_status_init_fail; | |
151 } | |
152 | |
153 /* test sequential insertion */ | |
154 for (idx=0; idx < num_trials; idx++) { | |
155 err = rdb_check_add(&rdb, idx); | |
156 if (err) | |
157 return err; | |
158 } | |
159 | |
160 /* test for false positives */ | |
161 for (idx=0; idx < num_trials; idx++) { | |
162 err = rdb_check_expect_failure(&rdb, idx); | |
163 if (err) | |
164 return err; | |
165 } | |
166 | |
167 /* re-initialize */ | |
168 if (rdb_init(&rdb) != err_status_ok) { | |
169 printf("rdb_init failed\n"); | |
170 return err_status_fail; | |
171 } | |
172 | |
173 /* test non-sequential insertion */ | |
174 ut_init(&utc); | |
175 | |
176 for (idx=0; idx < num_trials; idx++) { | |
177 ircvd = ut_next_index(&utc); | |
178 err = rdb_check_add_unordered(&rdb, ircvd); | |
179 if (err) | |
180 return err; | |
181 err = rdb_check_expect_failure(&rdb, ircvd); | |
182 if (err) | |
183 return err; | |
184 } | |
185 | |
186 /* re-initialize */ | |
187 if (rdb_init(&rdb) != err_status_ok) { | |
188 printf("rdb_init failed\n"); | |
189 return err_status_fail; | |
190 } | |
191 | |
192 /* test insertion with large gaps */ | |
193 for (idx=0, ircvd=0; idx < num_trials; idx++, ircvd += (1 << (rand() % 10))) { | |
194 err = rdb_check_add(&rdb, ircvd); | |
195 if (err) | |
196 return err; | |
197 err = rdb_check_expect_failure(&rdb, ircvd); | |
198 if (err) | |
199 return err; | |
200 } | |
201 | |
202 /* re-initialize */ | |
203 if (rdb_init(&rdb) != err_status_ok) { | |
204 printf("rdb_init failed\n"); | |
205 return err_status_fail; | |
206 } | |
207 | |
208 /* test loss of first 513 packets */ | |
209 for (idx=0; idx < num_trials; idx++) { | |
210 err = rdb_check_add(&rdb, idx + 513); | |
211 if (err) | |
212 return err; | |
213 } | |
214 | |
215 /* test for false positives */ | |
216 for (idx=0; idx < num_trials + 513; idx++) { | |
217 err = rdb_check_expect_failure(&rdb, idx); | |
218 if (err) | |
219 return err; | |
220 } | |
221 | |
222 | |
223 return err_status_ok; | |
224 } | |
225 | |
226 #include <time.h> /* for clock() */ | |
227 #include <stdlib.h> /* for random() */ | |
228 | |
229 #define REPLAY_NUM_TRIALS 10000000 | |
230 | |
231 double | |
232 rdb_check_adds_per_second(void) { | |
233 uint32_t i; | |
234 rdb_t rdb; | |
235 clock_t timer; | |
236 int failures = 0; /* count number of failures */ | |
237 | |
238 if (rdb_init(&rdb) != err_status_ok) { | |
239 printf("rdb_init failed\n"); | |
240 exit(1); | |
241 } | |
242 | |
243 timer = clock(); | |
244 for(i=0; i < REPLAY_NUM_TRIALS; i+=3) { | |
245 if (rdb_check(&rdb, i+2) != err_status_ok) | |
246 ++failures; | |
247 if (rdb_add_index(&rdb, i+2) != err_status_ok) | |
248 ++failures; | |
249 if (rdb_check(&rdb, i+1) != err_status_ok) | |
250 ++failures; | |
251 if (rdb_add_index(&rdb, i+1) != err_status_ok) | |
252 ++failures; | |
253 if (rdb_check(&rdb, i) != err_status_ok) | |
254 ++failures; | |
255 if (rdb_add_index(&rdb, i) != err_status_ok) | |
256 ++failures; | |
257 } | |
258 timer = clock() - timer; | |
259 | |
260 return (double) CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer; | |
261 } | |
OLD | NEW |