2 * Copyright (c) 2016, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include <tr_gss_names.h>
40 #include <trp_route.h>
41 #include <trp_internal.h>
43 #include <trp_ptable.h>
45 /* Can't do the updates test because trps_select_updates_for_peer() is now static */
46 #define VERIFY_UPDATES 0
52 unsigned int linkcost;
55 static struct peer_entry peer_data[]={
56 {"peer0", "trustrouter@peer0", 10000, 0x0001},
57 {"peer1", "trustrouter@peer1", 15000, 0x0002},
58 {"peer2", "trustrouter@peer2", 20000, 0x0004},
59 {"peer3", "trustrouter@peer3", 25000, 0x0008},
60 {"peer4", "trustrouter@peer4", 30000, 0x0010}
62 static size_t n_peers=sizeof(peer_data)/sizeof(peer_data[0]);
64 static void populate_ptable(TRPS_INSTANCE *trps)
69 for (i=0; i<n_peers; i++) {
70 new_peer=trp_peer_new(NULL);
71 assert(new_peer!=NULL);
72 trp_peer_set_server(new_peer, peer_data[i].server);
73 assert(trp_peer_get_server(new_peer)!=NULL);
74 trp_peer_add_gss_name(new_peer, tr_new_name(peer_data[i].gss_name));
75 assert(trp_peer_get_gss_names(new_peer)!=NULL);
76 trp_peer_set_port(new_peer, peer_data[i].port);
77 trp_peer_set_linkcost(new_peer, peer_data[i].linkcost);
78 assert(trps_add_peer(trps, new_peer)==TRP_SUCCESS);
82 static struct peer_entry *find_peer_entry(char *server)
85 for (i=0; i<n_peers; i++) {
86 if (0==strcmp(server, peer_data[i].server)) {
93 static void verify_ptable(TRPS_INSTANCE *trps)
95 struct peer_entry *peer_entry=NULL;
100 peer=trps->ptable->head;
102 peer_entry=find_peer_entry(trp_peer_get_server(peer));
103 assert(peer_entry!=NULL);
104 assert(!strcmp(trp_peer_get_server(peer), peer_entry->server));
105 assert(trp_peer_get_port(peer)==peer_entry->port);
106 assert(trp_peer_get_linkcost(peer)==peer_entry->linkcost);
107 assert(0<asprintf(&s, "trustrouter@%s", peer_entry->server));
108 gssname=tr_new_name(s);
110 assert(gssname!=NULL);
111 assert(tr_gss_names_matches(trp_peer_get_gss_names(peer), gssname));
112 tr_free_name(gssname);
125 unsigned int interval;
126 int verified; /* for testing */
128 static struct route_data route_table[]={
129 {"apc0", "realm0", "", 0, "tr.r0.apc0", "", 1, 60, 0},
130 {"apc0", "realm1", "", 0, "tr.r1.apc0", "", 1, 60, 0},
131 {"apc0", "realm0", "trustrouter@peer0", 1, "tr.r0.apc0", "trustrouter@peer0", 0, 60, 0},
132 {"apc0", "realm1", "trustrouter@peer0", 0, "tr.r1.apc0", "trustrouter@peer0", 0, 60, 0},
133 {"apc0", "realm2", "trustrouter@peer0", 0, "tr.r2.apc0", "trustrouter@peer0", 1, 60, 0},
134 {"apc0", "realm3", "trustrouter@peer0", 1, "tr.r3.apc0", "trustrouter@peer0", 0, 60, 0},
135 {"apc0", "realm4", "trustrouter@peer0", 2, "tr.r4.apc0", "trustrouter@peer0", 0, 60, 0},
136 {"apc0", "realm0", "trustrouter@peer1", 0, "tr.r0.apc0", "trustrouter@peer1", 0, 60, 0},
137 {"apc0", "realm1", "trustrouter@peer1", 1, "tr.r1.apc0", "trustrouter@peer1", 0, 60, 0},
138 {"apc0", "realm2", "trustrouter@peer1", 1, "tr.r2.apc0", "trustrouter@peer1", 0, 60, 0},
139 {"apc0", "realm3", "trustrouter@peer1", 0, "tr.r3.apc0", "trustrouter@peer1", 1, 60, 0},
140 {"apc0", "realm4", "trustrouter@peer1", 2, "tr.r4.apc0", "trustrouter@peer1", 0, 60, 0},
141 {"apc0", "realm0", "trustrouter@peer2", 0, "tr.r0.apc0", "trustrouter@peer2", 0, 60, 0},
142 {"apc0", "realm1", "trustrouter@peer2", 2, "tr.r1.apc0", "trustrouter@peer2", 0, 60, 0},
143 {"apc0", "realm2", "trustrouter@peer2", 2, "tr.r2.apc0", "trustrouter@peer2", 0, 60, 0},
144 {"apc0", "realm3", "trustrouter@peer2", 1, "tr.r3.apc0", "trustrouter@peer2", 0, 60, 0},
145 {"apc0", "realm4", "trustrouter@peer2", 0, "tr.r4.apc0", "trustrouter@peer2", 1, 60, 0},
147 static size_t n_routes=sizeof(route_table)/sizeof(route_table[0]);
150 /* These are the correct updates to select from the above route table for each peer.
151 * The rule is: send selected route unless it is through that peer, otherwise send
152 * the best (lowest metric) alternative route.
154 * In a few cases there are multiple valid options (when a two non-selected routes
155 * exist). If these tests are failing, it may be that the trps code is selecting another
156 * valid option, so check that. Probably ought to tweak metrics to avoid that ambiguity. */
157 static struct route_data update_table[][10]={
159 {"apc0", "realm0", "", 0, "tr.r0.apc0", "", 1, 60, 0},
160 {"apc0", "realm1", "", 0, "tr.r1.apc0", "", 1, 60, 0},
161 {"apc0", "realm2", "trustrouter@peer1", 1, "tr.r2.apc0", "trustrouter@peer1", 0, 60, 0},
162 {"apc0", "realm3", "trustrouter@peer1", 0, "tr.r3.apc0", "trustrouter@peer1", 1, 60, 0},
163 {"apc0", "realm4", "trustrouter@peer2", 0, "tr.r4.apc0", "trustrouter@peer2", 1, 60, 0},
167 {"apc0", "realm0", "", 0, "tr.r0.apc0", "", 1, 60, 0},
168 {"apc0", "realm1", "", 0, "tr.r1.apc0", "", 1, 60, 0},
169 {"apc0", "realm2", "trustrouter@peer0", 0, "tr.r2.apc0", "trustrouter@peer0", 1, 60, 0},
170 {"apc0", "realm3", "trustrouter@peer2", 1, "tr.r3.apc0", "trustrouter@peer2", 0, 60, 0},
171 {"apc0", "realm4", "trustrouter@peer2", 0, "tr.r4.apc0", "trustrouter@peer2", 1, 60, 0},
175 {"apc0", "realm0", "", 0, "tr.r0.apc0", "", 1, 60, 0},
176 {"apc0", "realm1", "", 0, "tr.r1.apc0", "", 1, 60, 0},
177 {"apc0", "realm2", "trustrouter@peer0", 0, "tr.r2.apc0", "trustrouter@peer0", 1, 60, 0},
178 {"apc0", "realm3", "trustrouter@peer1", 0, "tr.r3.apc0", "trustrouter@peer1", 1, 60, 0},
179 {"apc0", "realm4", "trustrouter@peer1", 2, "tr.r4.apc0", "trustrouter@peer1", 0, 60, 0},
183 {"apc0", "realm0", "", 0, "tr.r0.apc0", "", 1, 60, 0},
184 {"apc0", "realm1", "", 0, "tr.r1.apc0", "", 1, 60, 0},
185 {"apc0", "realm2", "trustrouter@peer0", 0, "tr.r2.apc0", "trustrouter@peer0", 1, 60, 0},
186 {"apc0", "realm3", "trustrouter@peer1", 0, "tr.r3.apc0", "trustrouter@peer1", 1, 60, 0},
187 {"apc0", "realm4", "trustrouter@peer2", 0, "tr.r4.apc0", "trustrouter@peer2", 1, 60, 0},
191 {"apc0", "realm0", "", 0, "tr.r0.apc0", "", 1, 60, 0},
192 {"apc0", "realm1", "", 0, "tr.r1.apc0", "", 1, 60, 0},
193 {"apc0", "realm2", "trustrouter@peer0", 0, "tr.r2.apc0", "trustrouter@peer0", 1, 60, 0},
194 {"apc0", "realm3", "trustrouter@peer1", 0, "tr.r3.apc0", "trustrouter@peer1", 1, 60, 0},
195 {"apc0", "realm4", "trustrouter@peer2", 0, "tr.r4.apc0", "trustrouter@peer2", 1, 60, 0},
199 #endif /* VERIFY_UPDATES */
201 static void populate_rtable(TRPS_INSTANCE *trps)
206 for (i=0; i<n_routes; i++) {
207 new=trp_route_new(NULL);
209 trp_route_set_comm(new, tr_new_name(route_table[i].apc));
210 trp_route_set_realm(new, tr_new_name(route_table[i].realm));
211 trp_route_set_peer(new, tr_new_name(route_table[i].peer));
212 trp_route_set_metric(new, route_table[i].metric);
213 trp_route_set_trust_router(new, tr_new_name(route_table[i].trust_router));
214 trp_route_set_next_hop(new, tr_new_name(route_table[i].next_hop));
215 trp_route_set_selected(new, route_table[i].selected);
216 trp_route_set_interval(new, route_table[i].interval);
217 /* do not set expiry */
218 trp_rtable_add(trps->rtable, new);
224 static void verify_update(TRP_ROUTE **updates, size_t n_updates, struct route_data *expected)
229 for(jj=0; jj<n_updates; jj++) {
231 for (ii=0; expected[ii].apc!=NULL; ii++) {
232 if ((0==strcmp(expected[ii].apc, updates[jj]->comm->buf))
233 &&(0==strcmp(expected[ii].realm, updates[jj]->realm->buf))
234 &&(0==strcmp(expected[ii].peer, updates[jj]->peer->buf))
235 &&(expected[ii].metric==updates[jj]->metric)
236 &&(0==strcmp(expected[ii].trust_router, updates[jj]->trust_router->buf))
237 &&(0==strcmp(expected[ii].next_hop, updates[jj]->next_hop->buf))
238 &&(expected[ii].selected==updates[jj]->selected)
239 &&(expected[ii].interval==updates[jj]->interval)) {
240 assert(expected[ii].verified==0); /* should only encounter each entry once */
241 expected[ii].verified=1;
247 printf("missing:\n%s\n", trp_route_to_str(NULL,updates[jj], " | "));
251 for(ii=0; expected[ii].apc!=NULL; ii++)
252 assert(expected[ii].verified==1);
255 static void verify_update_selection(TRPS_INSTANCE *trps)
258 TRP_ROUTE **updates=NULL;
260 TR_NAME *gssname=NULL;
263 for (ii=0; ii<n_peers; ii++) {
264 assert(0<asprintf(&s, "trustrouter@%s", peer_data[ii].server));
265 assert(NULL!=(gssname=tr_new_name(s)));
268 updates=trps_select_updates_for_peer(NULL, trps, gssname, &n_updates);
269 tr_free_name(gssname);
270 verify_update(updates, n_updates, update_table[ii]);
271 talloc_free(updates);
274 #endif /* VERIFY_UPDATES */
278 TALLOC_CTX *main_ctx=talloc_new(NULL);
282 trps=trps_new(main_ctx);
284 printf("\nPopulating peer table...\n");
285 populate_ptable(trps);
287 printf("\nVerifying peer table...\n");
290 printf("\nPopulating route table...\n");
291 populate_rtable(trps);
292 s=trp_rtable_to_str(main_ctx, trps->rtable, " | ", NULL);
293 printf("Route Table:\n%s---\n", s);
296 printf("\nVerifying route update selection...\n");
297 verify_update_selection(trps);
298 #endif /* VERIFY_UPDATES */
300 printf("\nDone\n\n");
301 talloc_report_full(main_ctx, stderr);
302 talloc_free(main_ctx);
303 talloc_report_full(NULL, stderr);