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.
38 #include <trust_router/tr_name.h>
39 #include <trp_internal.h>
43 /* static prototypes */
44 static TRP_INFOREC_DATA *trp_inforec_route_new(TALLOC_CTX *mem_ctx);
45 static void trp_inforec_route_print(TRP_INFOREC_DATA *);
46 static TRP_INFOREC_DATA *trp_inforec_comm_new(TALLOC_CTX *mem_ctx);
47 static void trp_inforec_comm_print(TRP_INFOREC_DATA *);
50 struct trp_inforec_type_entry {
52 TRP_INFOREC_TYPE type;
53 TRP_INFOREC_DATA *(*allocate)(TALLOC_CTX *);
54 void (*print)(TRP_INFOREC_DATA *);
56 static struct trp_inforec_type_entry trp_inforec_type_table[] = {
57 { "route", TRP_INFOREC_TYPE_ROUTE, trp_inforec_route_new, trp_inforec_route_print },
58 { "comm", TRP_INFOREC_TYPE_COMMUNITY, trp_inforec_comm_new, trp_inforec_comm_print },
59 { NULL, TRP_INFOREC_TYPE_UNKNOWN, NULL, NULL } /* must be the last entry */
63 /* look up an entry in the trp_inforec_type_table */
64 static struct trp_inforec_type_entry *get_trp_inforec_type_entry(TRP_INFOREC_TYPE msgtype)
66 struct trp_inforec_type_entry *entry=trp_inforec_type_table;
68 while ((entry->type != TRP_INFOREC_TYPE_UNKNOWN)
69 && (entry->type != msgtype)) {
75 /* translate strings to codes */
76 TRP_INFOREC_TYPE trp_inforec_type_from_string(const char *s)
78 struct trp_inforec_type_entry *entry=trp_inforec_type_table;
80 while ((entry->type != TRP_INFOREC_TYPE_UNKNOWN)
81 && (strcmp(s, entry->name)!=0)) {
86 /* translate codes to strings (do not need to be freed)
87 * Returns NULL on an unknown code */
88 const char *trp_inforec_type_to_string(TRP_INFOREC_TYPE msgtype)
90 struct trp_inforec_type_entry *entry=get_trp_inforec_type_entry(msgtype);
94 /* called by talloc when destroying an update message body */
95 static int trp_inforec_route_destructor(void *object)
97 TRP_INFOREC_ROUTE *body=talloc_get_type_abort(object, TRP_INFOREC_ROUTE);
99 /* clean up TR_NAME data, which are not managed by talloc */
100 if (body->trust_router != NULL)
101 tr_free_name(body->trust_router);
102 if (body->next_hop != NULL)
103 tr_free_name(body->next_hop);
107 static TRP_INFOREC_DATA *trp_inforec_route_new(TALLOC_CTX *mem_ctx)
109 TRP_INFOREC_DATA *new_data=talloc(mem_ctx, TRP_INFOREC_DATA);
110 TRP_INFOREC_ROUTE *new_rec=NULL;
115 new_rec=talloc(new_data, TRP_INFOREC_ROUTE);
116 if (new_rec == NULL) {
117 talloc_free(new_data);
120 new_rec->trust_router=NULL;
121 new_rec->next_hop=NULL;
122 new_rec->next_hop_port=0;
123 new_rec->metric=TRP_METRIC_INFINITY;
125 talloc_set_destructor((void *)new_rec, trp_inforec_route_destructor);
126 new_data->route=new_rec;
133 static int trp_inforec_comm_destructor(void *obj)
135 TRP_INFOREC_COMM *rec=talloc_get_type_abort(obj, TRP_INFOREC_COMM);
136 if (rec->owner_realm!=NULL)
137 tr_free_name(rec->owner_realm);
138 if (rec->owner_contact!=NULL)
139 tr_free_name(rec->owner_contact);
143 static TRP_INFOREC_DATA *trp_inforec_comm_new(TALLOC_CTX *mem_ctx)
145 TRP_INFOREC_DATA *new_data=talloc(mem_ctx, TRP_INFOREC_DATA);
146 TRP_INFOREC_COMM *new_rec=NULL;
151 new_rec=talloc(new_data, TRP_INFOREC_COMM);
153 talloc_free(new_data);
156 new_rec->type=TR_COMM_UNKNOWN;
157 new_rec->is_service_realm=0;
158 new_rec->is_idp_realm=0;
160 new_rec->owner_realm=NULL;
161 new_rec->owner_contact=NULL;
162 talloc_set_destructor((void *)new_rec, trp_inforec_comm_destructor);
163 new_data->comm=new_rec;
169 TRP_INFOREC *trp_inforec_get_next(TRP_INFOREC *rec)
177 static TRP_INFOREC *trp_inforec_get_tail(TRP_INFOREC *rec)
179 while ((rec->next)!=NULL)
180 rec=trp_inforec_get_next(rec);
184 void trp_inforec_set_next(TRP_INFOREC *rec, TRP_INFOREC *next_rec)
190 TRP_INFOREC_TYPE trp_inforec_get_type(TRP_INFOREC *rec)
195 return TRP_INFOREC_TYPE_UNKNOWN;
198 void trp_inforec_set_type(TRP_INFOREC *rec, TRP_INFOREC_TYPE type)
204 TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec)
207 case TRP_INFOREC_TYPE_ROUTE:
208 if (rec->data->route!=NULL)
209 return rec->data->route->trust_router;
217 TR_NAME *trp_inforec_dup_trust_router(TRP_INFOREC *rec)
219 return tr_dup_name(trp_inforec_get_trust_router(rec));
222 TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router)
225 case TRP_INFOREC_TYPE_ROUTE:
226 if (rec->data->route!=NULL) {
227 rec->data->route->trust_router=trust_router;
237 /* TODO: need to return hostname/port --jlr */
238 TR_NAME *trp_inforec_get_next_hop(TRP_INFOREC *rec)
241 case TRP_INFOREC_TYPE_ROUTE:
242 if (rec->data->route!=NULL)
243 return rec->data->route->next_hop;
251 TR_NAME *trp_inforec_dup_next_hop(TRP_INFOREC *rec)
253 return tr_dup_name(trp_inforec_get_next_hop(rec));
256 TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop)
259 case TRP_INFOREC_TYPE_ROUTE:
260 if (rec->data->route!=NULL) {
261 rec->data->route->next_hop=next_hop;
271 unsigned int trp_inforec_get_metric(TRP_INFOREC *rec)
274 case TRP_INFOREC_TYPE_ROUTE:
275 if (rec->data->route!=NULL)
276 return rec->data->route->metric;
281 return TRP_METRIC_INVALID;
284 TRP_RC trp_inforec_set_metric(TRP_INFOREC *rec, unsigned int metric)
287 case TRP_INFOREC_TYPE_ROUTE:
288 if (rec->data->route!=NULL) {
289 rec->data->route->metric=metric;
299 unsigned int trp_inforec_get_interval(TRP_INFOREC *rec)
302 case TRP_INFOREC_TYPE_ROUTE:
303 if (rec->data->route!=NULL)
304 return rec->data->route->interval;
309 return TRP_INTERVAL_INVALID;
312 TRP_RC trp_inforec_set_interval(TRP_INFOREC *rec, unsigned int interval)
315 case TRP_INFOREC_TYPE_ROUTE:
316 if (rec->data->route!=NULL) {
317 rec->data->route->interval=interval;
327 /* generic record type */
328 TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type)
330 TRP_INFOREC *new_rec=talloc(mem_ctx, TRP_INFOREC);
331 TRP_INFOREC_DATA *data=NULL;
332 struct trp_inforec_type_entry *dtype=get_trp_inforec_type_entry(type);
334 if ((new_rec != NULL) && (dtype->type != TRP_INFOREC_TYPE_UNKNOWN)) {
335 trp_inforec_set_type(new_rec, type);
336 trp_inforec_set_next(new_rec, NULL);
337 if (dtype->allocate!=NULL) {
338 data=dtype->allocate(new_rec);
342 talloc_free(new_rec);
350 void trp_inforec_free(TRP_INFOREC *rec)
356 static int trp_upd_destructor(void *object)
358 TRP_UPD *upd=talloc_get_type_abort(object, TRP_UPD);
359 if (upd->realm!=NULL)
360 tr_free_name(upd->realm);
362 tr_free_name(upd->comm);
364 tr_free_name(upd->peer);
368 TRP_UPD *trp_upd_new(TALLOC_CTX *mem_ctx)
370 TRP_UPD *new_body=talloc(mem_ctx, TRP_UPD);
372 if (new_body!=NULL) {
373 new_body->realm=NULL;
375 new_body->records=NULL;
377 talloc_set_destructor((void *)new_body, trp_upd_destructor);
382 void trp_upd_free(TRP_UPD *update)
388 TRP_INFOREC *trp_upd_get_inforec(TRP_UPD *upd)
396 void trp_upd_set_inforec(TRP_UPD *upd, TRP_INFOREC *rec)
402 void trp_upd_add_inforec(TRP_UPD *upd, TRP_INFOREC *rec)
404 tr_debug("trp_upd_add_inforec: adding record.");
405 if (upd->records==NULL)
408 trp_inforec_set_next(trp_inforec_get_tail(upd->records), rec);
409 talloc_steal(upd, rec);
412 TR_NAME *trp_upd_get_realm(TRP_UPD *upd)
417 TR_NAME *trp_upd_dup_realm(TRP_UPD *upd)
419 return tr_dup_name(upd->realm);
422 void trp_upd_set_realm(TRP_UPD *upd, TR_NAME *realm)
424 if (upd->realm!=NULL)
425 tr_free_name(upd->realm);
429 TR_NAME *trp_upd_get_comm(TRP_UPD *upd)
434 TR_NAME *trp_upd_dup_comm(TRP_UPD *upd)
436 return tr_dup_name(upd->comm);
439 void trp_upd_set_comm(TRP_UPD *upd, TR_NAME *comm)
442 tr_free_name(upd->comm);
446 TR_NAME *trp_upd_get_peer(TRP_UPD *upd)
451 TR_NAME *trp_upd_dup_peer(TRP_UPD *upd)
453 return tr_dup_name(upd->peer);
456 void trp_upd_set_peer(TRP_UPD *upd, TR_NAME *peer)
461 void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port)
463 TRP_INFOREC *rec=NULL;
466 for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
467 if (trp_inforec_set_next_hop(rec, cpy=tr_new_name(hostname)) != TRP_SUCCESS) {
468 tr_err("trp_upd_set_peer: error setting peer.");
475 static void trp_inforec_route_print(TRP_INFOREC_DATA *data)
477 if (data->route!=NULL) {
478 printf(" trust_router=%.*s\n metric=%d\n interval=%d]\n",
479 data->route->trust_router->len, data->route->trust_router->buf,
480 data->route->metric, data->route->interval);
484 static void trp_inforec_comm_print(TRP_INFOREC_DATA *data)
486 if (data->comm!=NULL) {
487 printf(" type=%s\n service=%s\n IdP=%s\n owner=%.*s\n contact=%.*s]\n",
488 tr_comm_type_to_str(data->comm->type),
489 (data->comm->is_service_realm)?"yes":"no",
490 (data->comm->is_idp_realm)?"yes":"no",
491 data->comm->owner_realm->len, data->comm->owner_realm->buf,
492 data->comm->owner_contact->len, data->comm->owner_contact->buf);
493 /* TODO: print apcs */