e1057f1b4e558071adaf394c1136fce9cbd99430
[trust_router.git] / trp / trp_upd.c
1 /*
2  * Copyright (c) 2016, JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
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.
15  *
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.
19  *
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.
32  *
33  */
34
35 #include <strings.h>
36 #include <jansson.h>
37 #include <talloc.h>
38
39 #include <tr_name_internal.h>
40 #include <trp_internal.h>
41 #include <tr_comm.h>
42 #include <tr_apc.h>
43 #include <tr_debug.h>
44
45
46 /* static prototypes */
47 static TRP_INFOREC_DATA *trp_inforec_route_new(TALLOC_CTX *mem_ctx);
48 static void trp_inforec_route_print(TRP_INFOREC_DATA *);
49 static TRP_INFOREC_DATA *trp_inforec_comm_new(TALLOC_CTX *mem_ctx);
50 static void trp_inforec_comm_print(TRP_INFOREC_DATA *);
51
52
53 struct trp_inforec_type_entry {
54   const char *name;
55   TRP_INFOREC_TYPE type;
56   TRP_INFOREC_DATA *(*allocate)(TALLOC_CTX *);
57   void (*print)(TRP_INFOREC_DATA *);
58 };
59 static struct trp_inforec_type_entry trp_inforec_type_table[] = {
60   { "route", TRP_INFOREC_TYPE_ROUTE, trp_inforec_route_new, trp_inforec_route_print },
61   { "comm", TRP_INFOREC_TYPE_COMMUNITY, trp_inforec_comm_new, trp_inforec_comm_print },
62   { NULL, TRP_INFOREC_TYPE_UNKNOWN, NULL, NULL } /* must be the last entry */
63 };
64
65
66 /* look up an entry in the trp_inforec_type_table */
67 static struct trp_inforec_type_entry *get_trp_inforec_type_entry(TRP_INFOREC_TYPE msgtype)
68 {
69   struct trp_inforec_type_entry *entry=trp_inforec_type_table;
70
71   while ((entry->type != TRP_INFOREC_TYPE_UNKNOWN)
72         && (entry->type != msgtype)) {
73     entry ++;
74   }
75   return entry;
76 }
77
78 /* translate strings to codes */
79 TRP_INFOREC_TYPE trp_inforec_type_from_string(const char *s)
80 {
81   struct trp_inforec_type_entry *entry=trp_inforec_type_table;
82
83   while ((entry->type != TRP_INFOREC_TYPE_UNKNOWN)
84         && (strcasecmp(s, entry->name)!=0)) {
85     entry++;
86   }
87   return entry->type;
88 }
89 /* translate codes to strings (do not need to be freed) 
90  * Returns NULL on an unknown code */
91 const char *trp_inforec_type_to_string(TRP_INFOREC_TYPE msgtype)
92 {
93   struct trp_inforec_type_entry *entry=get_trp_inforec_type_entry(msgtype);
94   return entry->name;
95 }
96
97 /* called by talloc when destroying an update message body */
98 static int trp_inforec_route_destructor(void *object)
99 {
100   TRP_INFOREC_ROUTE *body=talloc_get_type_abort(object, TRP_INFOREC_ROUTE);
101   
102   /* clean up TR_NAME data, which are not managed by talloc */
103   if (body->trust_router != NULL)
104     tr_free_name(body->trust_router);
105   if (body->next_hop != NULL)
106     tr_free_name(body->next_hop);
107   return 0;
108 }
109
110 static TRP_INFOREC_DATA *trp_inforec_route_new(TALLOC_CTX *mem_ctx)
111 {
112   TRP_INFOREC_DATA *new_data=talloc(mem_ctx, TRP_INFOREC_DATA);
113   TRP_INFOREC_ROUTE *new_rec=NULL;
114
115   if (new_data==NULL)
116     return NULL;
117
118   new_rec=talloc(new_data, TRP_INFOREC_ROUTE);
119   if (new_rec == NULL) {
120     talloc_free(new_data);
121     new_data=NULL;
122   } else {
123     new_rec->trust_router=NULL;
124     new_rec->next_hop=NULL;
125     new_rec->next_hop_port=0;
126     new_rec->metric=TRP_METRIC_INFINITY;
127     new_rec->interval=0;
128     talloc_set_destructor((void *)new_rec, trp_inforec_route_destructor);
129     new_data->route=new_rec;
130   }
131     
132   return new_data;
133 }
134
135
136 static int trp_inforec_comm_destructor(void *obj)
137 {
138   TRP_INFOREC_COMM *rec=talloc_get_type_abort(obj, TRP_INFOREC_COMM);
139   if (rec->owner_realm!=NULL)
140     tr_free_name(rec->owner_realm);
141   if (rec->owner_contact!=NULL)
142     tr_free_name(rec->owner_contact);
143   if (rec->provenance!=NULL)
144     json_decref(rec->provenance);
145   return 0;
146 }
147
148 static TRP_INFOREC_DATA *trp_inforec_comm_new(TALLOC_CTX *mem_ctx)
149 {
150   TRP_INFOREC_DATA *new_data=talloc(mem_ctx, TRP_INFOREC_DATA);
151   TRP_INFOREC_COMM *new_rec=NULL;
152
153   if (new_data==NULL)
154     return NULL;
155
156   new_rec=talloc(new_data, TRP_INFOREC_COMM);
157   if (new_rec==NULL) {
158     talloc_free(new_data);
159     new_data=NULL;
160   } else {
161     new_rec->comm_type=TR_COMM_UNKNOWN;
162     new_rec->role=TR_ROLE_UNKNOWN;
163     new_rec->apcs=NULL;
164     new_rec->owner_realm=NULL;
165     new_rec->owner_contact=NULL;
166     new_rec->expiration_interval=0;
167     new_rec->provenance=NULL;
168     new_rec->interval=0;
169     talloc_set_destructor((void *)new_rec, trp_inforec_comm_destructor);
170     new_data->comm=new_rec;
171   }
172
173   return new_data;
174 }
175
176 TRP_INFOREC *trp_inforec_get_next(TRP_INFOREC *rec)
177 {
178   if (rec!=NULL)
179     return rec->next;
180   else
181     return NULL;
182 }
183
184 static TRP_INFOREC *trp_inforec_get_tail(TRP_INFOREC *rec)
185 {
186   while ((rec->next)!=NULL)
187     rec=trp_inforec_get_next(rec);
188   return rec;
189 }
190
191 void trp_inforec_set_next(TRP_INFOREC *rec, TRP_INFOREC *next_rec)
192 {
193   if (rec !=NULL)
194     rec->next=next_rec;
195 }
196
197 TRP_INFOREC_TYPE trp_inforec_get_type(TRP_INFOREC *rec)
198 {
199   if (rec!=NULL)
200     return rec->type;
201   else
202     return TRP_INFOREC_TYPE_UNKNOWN;
203 }
204
205 void trp_inforec_set_type(TRP_INFOREC *rec, TRP_INFOREC_TYPE type)
206 {
207   if (rec!=NULL)
208     rec->type=type;
209 }
210
211 TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec)
212 {
213   switch (rec->type) {
214   case TRP_INFOREC_TYPE_ROUTE:
215     if (rec->data->route!=NULL)
216       return rec->data->route->trust_router;
217     break;
218   default:
219     break;
220   }
221   return NULL;
222 }
223
224 TR_NAME *trp_inforec_dup_trust_router(TRP_INFOREC *rec)
225 {
226   return tr_dup_name(trp_inforec_get_trust_router(rec));
227 }
228
229 TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router)
230 {
231   switch (rec->type) {
232   case TRP_INFOREC_TYPE_ROUTE:
233     if (rec->data->route!=NULL) {
234       rec->data->route->trust_router=trust_router;
235       return TRP_SUCCESS;
236     }
237     break;
238   default:
239     break;
240   }
241   return TRP_ERROR;
242 }
243
244 /* TODO: need to return hostname/port --jlr */
245 TR_NAME *trp_inforec_get_next_hop(TRP_INFOREC *rec)
246 {
247   switch (rec->type) {
248   case TRP_INFOREC_TYPE_ROUTE:
249     if (rec->data->route!=NULL)
250       return rec->data->route->next_hop;
251     break;
252   default:
253     break;
254   }
255   return NULL;
256 }
257
258 TR_NAME *trp_inforec_dup_next_hop(TRP_INFOREC *rec)
259 {
260   return tr_dup_name(trp_inforec_get_next_hop(rec));
261 }
262
263 TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop)
264 {
265   switch (rec->type) {
266   case TRP_INFOREC_TYPE_ROUTE:
267     if (rec->data->route==NULL)
268       return TRP_ERROR;
269     rec->data->route->next_hop=next_hop;
270     break;
271   case TRP_INFOREC_TYPE_COMMUNITY:
272     /* next hop not used for community records */
273     break;
274   default:
275     break;
276   }
277   return TRP_SUCCESS;
278 }
279
280 unsigned int trp_inforec_get_metric(TRP_INFOREC *rec)
281 {
282   switch (rec->type) {
283   case TRP_INFOREC_TYPE_ROUTE:
284     if (rec->data->route!=NULL)
285       return rec->data->route->metric;
286     break;
287   default:
288     break;
289   }
290   return TRP_METRIC_INVALID;
291 }
292
293 TRP_RC trp_inforec_set_metric(TRP_INFOREC *rec, unsigned int metric)
294 {
295   switch (rec->type) {
296   case TRP_INFOREC_TYPE_ROUTE:
297     if (rec->data->route!=NULL) {
298       rec->data->route->metric=metric;
299       return TRP_SUCCESS;
300     }
301     break;
302   default:
303     break;
304   }
305   return TRP_ERROR;
306 }
307
308 unsigned int trp_inforec_get_interval(TRP_INFOREC *rec)
309 {
310   switch (rec->type) {
311   case TRP_INFOREC_TYPE_ROUTE:
312     if (rec->data->route!=NULL)
313       return rec->data->route->interval;
314     break;
315   case TRP_INFOREC_TYPE_COMMUNITY:
316     if (rec->data->comm!=NULL)
317       return rec->data->comm->interval;
318     break;
319   default:
320     break;
321   }
322   return TRP_INTERVAL_INVALID;
323 }
324
325 TRP_RC trp_inforec_set_interval(TRP_INFOREC *rec, unsigned int interval)
326 {
327   switch (rec->type) {
328   case TRP_INFOREC_TYPE_ROUTE:
329     if (rec->data->route!=NULL) {
330       rec->data->route->interval=interval;
331       return TRP_SUCCESS;
332     }
333     break;
334   case TRP_INFOREC_TYPE_COMMUNITY:
335     if (rec->data->comm!=NULL) {
336       rec->data->comm->interval=interval;
337       return TRP_SUCCESS;
338     }
339   default:
340     break;
341   }
342   return TRP_ERROR;
343 }
344
345 time_t trp_inforec_get_exp_interval(TRP_INFOREC *rec)
346 {
347   switch (rec->type) {
348   case TRP_INFOREC_TYPE_COMMUNITY:
349     if (rec->data->comm!=NULL)
350       return rec->data->comm->expiration_interval;
351     break;
352   default:
353     break;
354   }
355   return 0;
356 }
357
358 TRP_RC trp_inforec_set_exp_interval(TRP_INFOREC *rec, time_t expint)
359 {
360   switch (rec->type) {
361   case TRP_INFOREC_TYPE_COMMUNITY:
362     if (rec->data->comm!=NULL) {
363       rec->data->comm->expiration_interval=expint;
364       return TRP_SUCCESS;
365     }
366     break;
367   default:
368     break;
369   }
370   return TRP_ERROR;
371 }
372
373 TR_COMM_TYPE trp_inforec_get_comm_type(TRP_INFOREC *rec)
374 {
375   switch (rec->type) {
376   case TRP_INFOREC_TYPE_COMMUNITY:
377     if (rec->data->comm!=NULL)
378       return rec->data->comm->comm_type;
379     break;
380   default:
381     break;
382   }
383   return TR_COMM_UNKNOWN;
384 }
385
386 TRP_RC trp_inforec_set_comm_type(TRP_INFOREC *rec, TR_COMM_TYPE type)
387 {
388   switch (rec->type) {
389   case TRP_INFOREC_TYPE_COMMUNITY:
390     if (rec->data->comm!=NULL) {
391       rec->data->comm->comm_type=type;
392       return TRP_SUCCESS;
393     }
394     break;
395   default:
396     break;
397   }
398   return TRP_ERROR;
399 }
400
401 TR_REALM_ROLE trp_inforec_get_role(TRP_INFOREC *rec)
402 {
403   switch (rec->type) {
404   case TRP_INFOREC_TYPE_COMMUNITY:
405     if (rec->data->comm!=NULL)
406       return rec->data->comm->role;
407     break;
408   default:
409     break;
410   }
411   return TR_ROLE_UNKNOWN;
412 }
413
414 TRP_RC trp_inforec_set_role(TRP_INFOREC *rec, TR_REALM_ROLE role)
415 {
416   switch (rec->type) {
417   case TRP_INFOREC_TYPE_COMMUNITY:
418     if (rec->data->comm!=NULL) {
419       rec->data->comm->role=role;
420       return TRP_SUCCESS;
421       break;
422     }
423   default:
424     break;
425   }
426   return TRP_ERROR;
427 }
428
429 TR_APC *trp_inforec_get_apcs(TRP_INFOREC *rec)
430 {
431   switch (rec->type) {
432   case TRP_INFOREC_TYPE_COMMUNITY:
433     if (rec->data->comm!=NULL)
434       return rec->data->comm->apcs;
435     break;
436   default:
437     break;
438   }
439   return NULL;
440 }
441
442 TRP_RC trp_inforec_set_apcs(TRP_INFOREC *rec, TR_APC *apcs)
443 {
444   switch (rec->type) {
445   case TRP_INFOREC_TYPE_COMMUNITY:
446     if (rec->data->comm!=NULL) {
447       rec->data->comm->apcs=apcs;
448       talloc_steal(rec, apcs);
449       return TRP_SUCCESS;
450     }
451     break;
452
453   default:
454     break;
455   }
456   return TRP_ERROR;
457 }
458
459 TR_NAME *trp_inforec_get_owner_realm(TRP_INFOREC *rec)
460 {
461   switch (rec->type) {
462   case TRP_INFOREC_TYPE_COMMUNITY:
463     if (rec->data->comm!=NULL)
464       return rec->data->comm->owner_realm;
465     break;
466   default:
467     break;
468   }
469   return NULL;
470 }
471
472 TRP_RC trp_inforec_set_owner_realm(TRP_INFOREC *rec, TR_NAME *name)
473 {
474   switch (rec->type) {
475   case TRP_INFOREC_TYPE_COMMUNITY:
476     if (rec->data->comm!=NULL) {
477       rec->data->comm->owner_realm=name;
478       return TRP_SUCCESS;
479   default:
480     break;
481     }
482     break;
483   }
484   return TRP_ERROR;
485 }
486
487 TR_NAME *trp_inforec_get_owner_contact(TRP_INFOREC *rec)
488 {
489   switch (rec->type) {
490   case TRP_INFOREC_TYPE_COMMUNITY:
491     if (rec->data->comm!=NULL)
492       return rec->data->comm->owner_contact;
493     break;
494   default:
495     break;
496   }
497   return NULL;
498 }
499
500 TRP_RC trp_inforec_set_owner_contact(TRP_INFOREC *rec, TR_NAME *name)
501 {
502   switch (rec->type) {
503   case TRP_INFOREC_TYPE_COMMUNITY:
504     if (rec->data->comm!=NULL) {
505       rec->data->comm->owner_contact=name;
506       return TRP_SUCCESS;
507     }
508     break;
509   default:
510     break;
511   }
512   return TRP_ERROR;
513 }
514
515 /* caller needs to incref the output if they're going to hang on to it */
516 json_t *trp_inforec_get_provenance(TRP_INFOREC *rec)
517 {
518   switch (rec->type) {
519   case TRP_INFOREC_TYPE_COMMUNITY:
520     if (rec->data->comm!=NULL)
521       return rec->data->comm->provenance;
522     break;
523   default:
524     break;
525   }
526   return NULL;
527 }
528
529 /* increments the reference count */
530 TRP_RC trp_inforec_set_provenance(TRP_INFOREC *rec, json_t *prov)
531 {
532   switch (rec->type) {
533   case TRP_INFOREC_TYPE_COMMUNITY:
534     if (rec->data->comm!=NULL) {
535       if (rec->data->comm->provenance!=NULL)
536         json_decref(rec->data->comm->provenance);
537       rec->data->comm->provenance=prov;
538       json_incref(prov);
539       return TRP_SUCCESS;
540     }
541     break;
542   default:
543     break;
544   }
545   return TRP_ERROR;
546 }
547
548 static TRP_RC trp_inforec_add_to_provenance(TRP_INFOREC *rec, TR_NAME *name)
549 {
550   json_t *jname=NULL;
551
552   switch (rec->type) {
553   case TRP_INFOREC_TYPE_ROUTE:
554     /* no provenance list */
555     break;
556   case TRP_INFOREC_TYPE_COMMUNITY:
557     jname=tr_name_to_json_string(name);
558     if (jname==NULL)
559       return TRP_ERROR;
560     if (rec->data->comm->provenance==NULL) {
561       rec->data->comm->provenance=json_array();
562       if (rec->data->comm->provenance==NULL) {
563         json_decref(jname);
564         return TRP_ERROR;
565       }
566     }
567     if (0!=json_array_append_new(rec->data->comm->provenance, jname)) {
568       json_decref(jname);
569       return TRP_ERROR;
570     }
571     break;
572   default:
573     break;
574   }
575   return TRP_SUCCESS;
576 }
577
578 TR_NAME *trp_inforec_dup_origin(TRP_INFOREC *rec)
579 {
580   TR_NAME *origin=NULL;
581   json_t *prov=trp_inforec_get_provenance(rec);
582   const char *s=NULL;
583
584   if (prov==NULL)
585     return NULL;
586
587   s=json_string_value(json_array_get(prov, 0));
588   if (s==NULL) {
589     tr_debug("trp_inforec_dup_origin: empty origin in provenance list.");
590     return NULL;
591   }
592   origin=tr_new_name(s);
593   return origin;
594 }
595
596 /* generic record type */
597 TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type)
598 {
599   TRP_INFOREC *new_rec=talloc(mem_ctx, TRP_INFOREC);
600   TRP_INFOREC_DATA *data=NULL;
601   struct trp_inforec_type_entry *dtype=get_trp_inforec_type_entry(type);
602
603   if ((new_rec != NULL) && (dtype->type != TRP_INFOREC_TYPE_UNKNOWN)) {
604     trp_inforec_set_type(new_rec, type);
605     trp_inforec_set_next(new_rec, NULL);
606     if (dtype->allocate!=NULL) {
607       data=dtype->allocate(new_rec);
608       if (data!=NULL)
609         new_rec->data=data;
610       else {
611         talloc_free(new_rec);
612         return NULL;
613       }
614     }
615   }
616   return new_rec;
617 }
618
619 void trp_inforec_free(TRP_INFOREC *rec)
620 {
621   if (rec!=NULL)
622     talloc_free(rec);
623 }
624
625 static int trp_upd_destructor(void *object)
626 {
627   TRP_UPD *upd=talloc_get_type_abort(object, TRP_UPD);
628   if (upd->realm!=NULL)
629     tr_free_name(upd->realm);
630   if (upd->comm!=NULL)
631     tr_free_name(upd->comm);
632   if (upd->peer!=NULL)
633     tr_free_name(upd->peer);
634   return 0;
635 }
636
637 TRP_UPD *trp_upd_new(TALLOC_CTX *mem_ctx)
638 {
639   TRP_UPD *new_body=talloc(mem_ctx, TRP_UPD);
640
641   if (new_body!=NULL) {
642     new_body->realm=NULL;
643     new_body->comm=NULL;
644     new_body->records=NULL;
645     new_body->peer=NULL;
646     talloc_set_destructor((void *)new_body, trp_upd_destructor);
647   }
648   return new_body;
649 }
650
651 void trp_upd_free(TRP_UPD *update)
652 {
653   if (update!=NULL)
654     talloc_free(update);
655 }
656
657 TRP_INFOREC *trp_upd_get_inforec(TRP_UPD *upd)
658 {
659   if (upd!=NULL)
660     return upd->records;
661   else
662     return NULL;
663 }
664
665 void trp_upd_set_inforec(TRP_UPD *upd, TRP_INFOREC *rec)
666 {
667   if (upd!=NULL)
668     upd->records=rec;
669 }
670
671 void trp_upd_add_inforec(TRP_UPD *upd, TRP_INFOREC *rec)
672 {
673   tr_debug("trp_upd_add_inforec: adding record.");
674   if (upd->records==NULL)
675     upd->records=rec;
676   else
677     trp_inforec_set_next(trp_inforec_get_tail(upd->records), rec);
678   talloc_steal(upd, rec);
679 }
680
681 /**
682  * Removes and frees the selected inforec.
683  *
684  * @param upd Update to remove from
685  * @param rec Inforec to remove
686  */
687 void trp_upd_remove_inforec(TRP_UPD *upd, TRP_INFOREC *rec)
688 {
689   TRP_INFOREC *this=upd->records;
690
691   /* special case for the first element */
692   if (this==rec) {
693     upd->records=upd->records->next;
694     trp_inforec_free(this);
695     return;
696   }
697
698   while (this->next!=NULL) {
699     if (this->next==rec) {
700       this->next=this->next->next; /* this->next is not null */
701       trp_inforec_free(rec);
702     }
703     this=this->next;
704   }
705 }
706
707 size_t trp_upd_num_inforecs(TRP_UPD *upd)
708 {
709   size_t count=0;
710   TRP_INFOREC *this=upd->records;
711
712   while (this != NULL) {
713     count++;
714     this=this->next;
715   }
716   return count;
717 }
718
719
720 TR_NAME *trp_upd_get_realm(TRP_UPD *upd)
721 {
722   return upd->realm;
723 }
724
725 TR_NAME *trp_upd_dup_realm(TRP_UPD *upd)
726 {
727   return tr_dup_name(upd->realm);
728 }
729
730 void trp_upd_set_realm(TRP_UPD *upd, TR_NAME *realm)
731 {
732   if (upd->realm!=NULL)
733     tr_free_name(upd->realm);
734   upd->realm=realm;
735 }
736
737 TR_NAME *trp_upd_get_comm(TRP_UPD *upd)
738 {
739   return upd->comm;
740 }
741
742 TR_NAME *trp_upd_dup_comm(TRP_UPD *upd)
743 {
744   return tr_dup_name(upd->comm);
745 }
746
747 void trp_upd_set_comm(TRP_UPD *upd, TR_NAME *comm)
748 {
749   if (upd->comm!=NULL)
750     tr_free_name(upd->comm);
751   upd->comm=comm;
752 }
753
754 TR_NAME *trp_upd_get_peer(TRP_UPD *upd)
755 {
756   return upd->peer;
757 }
758
759 TR_NAME *trp_upd_dup_peer(TRP_UPD *upd)
760 {
761   return tr_dup_name(upd->peer);
762 }
763
764 void trp_upd_set_peer(TRP_UPD *upd, TR_NAME *peer)
765 {
766   upd->peer=peer;
767 }
768
769 void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port)
770 {
771   TRP_INFOREC *rec=NULL;
772   TR_NAME *cpy=NULL;
773   
774   for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
775     if (trp_inforec_set_next_hop(rec, cpy=tr_new_name(hostname)) != TRP_SUCCESS) {
776       tr_err("trp_upd_set_next_hop: error setting next hop.");
777       tr_free_name(cpy);
778     }
779   }
780 }
781
782 void trp_upd_add_to_provenance(TRP_UPD *upd, TR_NAME *name)
783 {
784   TRP_INFOREC *rec=NULL;
785
786   /* add it to all inforecs */
787   for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
788     if (TRP_SUCCESS!=trp_inforec_add_to_provenance(rec, name))
789       tr_err("trp_upd_set_peer: error adding peer to provenance list.");
790   }
791 }
792
793 /* pretty print */
794 static void trp_inforec_route_print(TRP_INFOREC_DATA *data)
795 {
796   if (data->route!=NULL) {
797     tr_info("     trust_router=%.*s\n     metric=%d\n     interval=%d]\n",
798            data->route->trust_router->len, data->route->trust_router->buf,
799            data->route->metric, data->route->interval);
800   }
801 }
802
803 static void trp_inforec_comm_print(TRP_INFOREC_DATA *data)
804 {
805   if (data->comm!=NULL) {
806     tr_info("     type=%s\n     role=%s\n     owner=%.*s\n     contact=%.*s]\n",
807            tr_comm_type_to_str(data->comm->comm_type),
808            tr_realm_role_to_str(data->comm->role),
809            data->comm->owner_realm->len, data->comm->owner_realm->buf,
810            data->comm->owner_contact->len, data->comm->owner_contact->buf);
811     /* TODO: print apcs */
812   }
813 }