Merge pull request #72 from painless-security/jennifer/peer_label_for_updates
[trust_router.git] / trp / trp_upd.c
index a76c76b..e1057f1 100644 (file)
  *
  */
 
+#include <strings.h>
 #include <jansson.h>
 #include <talloc.h>
 
-#include <trust_router/tr_name.h>
+#include <tr_name_internal.h>
 #include <trp_internal.h>
 #include <tr_comm.h>
 #include <tr_apc.h>
@@ -80,7 +81,7 @@ TRP_INFOREC_TYPE trp_inforec_type_from_string(const char *s)
   struct trp_inforec_type_entry *entry=trp_inforec_type_table;
 
   while ((entry->type != TRP_INFOREC_TYPE_UNKNOWN)
-        && (strcmp(s, entry->name)!=0)) {
+        && (strcasecmp(s, entry->name)!=0)) {
     entry++;
   }
   return entry->type;
@@ -162,7 +163,9 @@ static TRP_INFOREC_DATA *trp_inforec_comm_new(TALLOC_CTX *mem_ctx)
     new_rec->apcs=NULL;
     new_rec->owner_realm=NULL;
     new_rec->owner_contact=NULL;
+    new_rec->expiration_interval=0;
     new_rec->provenance=NULL;
+    new_rec->interval=0;
     talloc_set_destructor((void *)new_rec, trp_inforec_comm_destructor);
     new_data->comm=new_rec;
   }
@@ -193,7 +196,7 @@ void trp_inforec_set_next(TRP_INFOREC *rec, TRP_INFOREC *next_rec)
 
 TRP_INFOREC_TYPE trp_inforec_get_type(TRP_INFOREC *rec)
 {
-  if (rec)
+  if (rec!=NULL)
     return rec->type;
   else
     return TRP_INFOREC_TYPE_UNKNOWN;
@@ -261,15 +264,17 @@ TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop)
 {
   switch (rec->type) {
   case TRP_INFOREC_TYPE_ROUTE:
-    if (rec->data->route!=NULL) {
-      rec->data->route->next_hop=next_hop;
-      return TRP_SUCCESS;
-    }
+    if (rec->data->route==NULL)
+      return TRP_ERROR;
+    rec->data->route->next_hop=next_hop;
+    break;
+  case TRP_INFOREC_TYPE_COMMUNITY:
+    /* next hop not used for community records */
     break;
   default:
     break;
   }
-  return TRP_ERROR;
+  return TRP_SUCCESS;
 }
 
 unsigned int trp_inforec_get_metric(TRP_INFOREC *rec)
@@ -337,6 +342,34 @@ TRP_RC trp_inforec_set_interval(TRP_INFOREC *rec, unsigned int interval)
   return TRP_ERROR;
 }
 
+time_t trp_inforec_get_exp_interval(TRP_INFOREC *rec)
+{
+  switch (rec->type) {
+  case TRP_INFOREC_TYPE_COMMUNITY:
+    if (rec->data->comm!=NULL)
+      return rec->data->comm->expiration_interval;
+    break;
+  default:
+    break;
+  }
+  return 0;
+}
+
+TRP_RC trp_inforec_set_exp_interval(TRP_INFOREC *rec, time_t expint)
+{
+  switch (rec->type) {
+  case TRP_INFOREC_TYPE_COMMUNITY:
+    if (rec->data->comm!=NULL) {
+      rec->data->comm->expiration_interval=expint;
+      return TRP_SUCCESS;
+    }
+    break;
+  default:
+    break;
+  }
+  return TRP_ERROR;
+}
+
 TR_COMM_TYPE trp_inforec_get_comm_type(TRP_INFOREC *rec)
 {
   switch (rec->type) {
@@ -414,10 +447,11 @@ TRP_RC trp_inforec_set_apcs(TRP_INFOREC *rec, TR_APC *apcs)
       rec->data->comm->apcs=apcs;
       talloc_steal(rec, apcs);
       return TRP_SUCCESS;
-  default:
-    break;
     }
     break;
+
+  default:
+    break;
   }
   return TRP_ERROR;
 }
@@ -511,6 +545,54 @@ TRP_RC trp_inforec_set_provenance(TRP_INFOREC *rec, json_t *prov)
   return TRP_ERROR;
 }
 
+static TRP_RC trp_inforec_add_to_provenance(TRP_INFOREC *rec, TR_NAME *name)
+{
+  json_t *jname=NULL;
+
+  switch (rec->type) {
+  case TRP_INFOREC_TYPE_ROUTE:
+    /* no provenance list */
+    break;
+  case TRP_INFOREC_TYPE_COMMUNITY:
+    jname=tr_name_to_json_string(name);
+    if (jname==NULL)
+      return TRP_ERROR;
+    if (rec->data->comm->provenance==NULL) {
+      rec->data->comm->provenance=json_array();
+      if (rec->data->comm->provenance==NULL) {
+        json_decref(jname);
+        return TRP_ERROR;
+      }
+    }
+    if (0!=json_array_append_new(rec->data->comm->provenance, jname)) {
+      json_decref(jname);
+      return TRP_ERROR;
+    }
+    break;
+  default:
+    break;
+  }
+  return TRP_SUCCESS;
+}
+
+TR_NAME *trp_inforec_dup_origin(TRP_INFOREC *rec)
+{
+  TR_NAME *origin=NULL;
+  json_t *prov=trp_inforec_get_provenance(rec);
+  const char *s=NULL;
+
+  if (prov==NULL)
+    return NULL;
+
+  s=json_string_value(json_array_get(prov, 0));
+  if (s==NULL) {
+    tr_debug("trp_inforec_dup_origin: empty origin in provenance list.");
+    return NULL;
+  }
+  origin=tr_new_name(s);
+  return origin;
+}
+
 /* generic record type */
 TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type)
 {
@@ -596,6 +678,45 @@ void trp_upd_add_inforec(TRP_UPD *upd, TRP_INFOREC *rec)
   talloc_steal(upd, rec);
 }
 
+/**
+ * Removes and frees the selected inforec.
+ *
+ * @param upd Update to remove from
+ * @param rec Inforec to remove
+ */
+void trp_upd_remove_inforec(TRP_UPD *upd, TRP_INFOREC *rec)
+{
+  TRP_INFOREC *this=upd->records;
+
+  /* special case for the first element */
+  if (this==rec) {
+    upd->records=upd->records->next;
+    trp_inforec_free(this);
+    return;
+  }
+
+  while (this->next!=NULL) {
+    if (this->next==rec) {
+      this->next=this->next->next; /* this->next is not null */
+      trp_inforec_free(rec);
+    }
+    this=this->next;
+  }
+}
+
+size_t trp_upd_num_inforecs(TRP_UPD *upd)
+{
+  size_t count=0;
+  TRP_INFOREC *this=upd->records;
+
+  while (this != NULL) {
+    count++;
+    this=this->next;
+  }
+  return count;
+}
+
+
 TR_NAME *trp_upd_get_realm(TRP_UPD *upd)
 {
   return upd->realm;
@@ -652,17 +773,28 @@ void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port)
   
   for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
     if (trp_inforec_set_next_hop(rec, cpy=tr_new_name(hostname)) != TRP_SUCCESS) {
-      tr_err("trp_upd_set_peer: error setting peer.");
+      tr_err("trp_upd_set_next_hop: error setting next hop.");
       tr_free_name(cpy);
     }
   }
 }
 
+void trp_upd_add_to_provenance(TRP_UPD *upd, TR_NAME *name)
+{
+  TRP_INFOREC *rec=NULL;
+
+  /* add it to all inforecs */
+  for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
+    if (TRP_SUCCESS!=trp_inforec_add_to_provenance(rec, name))
+      tr_err("trp_upd_set_peer: error adding peer to provenance list.");
+  }
+}
+
 /* pretty print */
 static void trp_inforec_route_print(TRP_INFOREC_DATA *data)
 {
   if (data->route!=NULL) {
-    printf("     trust_router=%.*s\n     metric=%d\n     interval=%d]\n",
+    tr_info("     trust_router=%.*s\n     metric=%d\n     interval=%d]\n",
            data->route->trust_router->len, data->route->trust_router->buf,
            data->route->metric, data->route->interval);
   }
@@ -671,7 +803,7 @@ static void trp_inforec_route_print(TRP_INFOREC_DATA *data)
 static void trp_inforec_comm_print(TRP_INFOREC_DATA *data)
 {
   if (data->comm!=NULL) {
-    printf("     type=%s\n     role=%s\n     owner=%.*s\n     contact=%.*s]\n",
+    tr_info("     type=%s\n     role=%s\n     owner=%.*s\n     contact=%.*s]\n",
            tr_comm_type_to_str(data->comm->comm_type),
            tr_realm_role_to_str(data->comm->role),
            data->comm->owner_realm->len, data->comm->owner_realm->buf,