Fix JSON reference counting errors
[trust_router.git] / common / tr_comm.c
index 0a0fd93..f8f91df 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, JANET(UK)
+ * Copyright (c) 2012-2018, JANET(UK)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,7 @@
 
 #include <tr_rp.h>
 #include <tr_idp.h>
-#include <trust_router/tr_name.h>
+#include <tr_name_internal.h>
 #include <tr_comm.h>
 #include <tr_debug.h>
 
@@ -246,6 +246,7 @@ void tr_comm_add_idp_realm(TR_COMM_TABLE *ctab,
   tr_comm_memb_set_comm(newmemb, comm);
   tr_comm_memb_set_interval(newmemb, interval);
   tr_comm_memb_set_provenance(newmemb, provenance);
+  tr_comm_memb_set_expiry(newmemb, expiry);
 
   existing=tr_comm_table_find_idp_memb_origin(ctab,
                                               tr_idp_realm_get_id(realm),
@@ -278,6 +279,7 @@ void tr_comm_add_rp_realm(TR_COMM_TABLE *ctab,
   tr_comm_memb_set_comm(newmemb, comm);
   tr_comm_memb_set_interval(newmemb, interval);
   tr_comm_memb_set_provenance(newmemb, provenance);
+  tr_comm_memb_set_expiry(newmemb, expiry);
 
   existing=tr_comm_table_find_rp_memb_origin(ctab,
                                              tr_rp_realm_get_id(realm),
@@ -370,10 +372,10 @@ static TR_COMM *tr_comm_sweep_func(TR_COMM *head)
     return NULL;
 
   /* will not remove the head here, that has already been done */
-  for (comm=head; comm->next!=NULL; comm=comm->next) {
+  for (comm=head; (comm!=NULL) && (comm->next!=NULL); comm=comm->next) {
     if (comm->next->refcount==0) {
       old_next=comm->next;
-      tr_comm_remove(head, comm->next); /* changes comm->next */
+      tr_comm_remove(head, comm->next); /* changes comm->next, may make it null */
       tr_comm_free(old_next);
     }
   }
@@ -1017,6 +1019,11 @@ struct timespec *tr_comm_memb_get_expiry(TR_COMM_MEMB *memb)
 
 int tr_comm_memb_is_expired(TR_COMM_MEMB *memb, struct timespec *curtime)
 {
+  tr_debug("tr_comm_memb_is_expired: (cur->tv_sec>memb->expiry->tv_sec)=(%u > %u)=%s",
+           curtime->tv_sec,
+           memb->expiry->tv_sec,
+           (curtime->tv_sec > memb->expiry->tv_sec)?"true":"false");
+
   return ((curtime->tv_sec > memb->expiry->tv_sec)
          || ((curtime->tv_sec == memb->expiry->tv_sec)
             &&(curtime->tv_nsec >= memb->expiry->tv_nsec)));
@@ -1404,24 +1411,77 @@ TR_REALM_ROLE tr_realm_role_from_str(const char *s)
   return TR_ROLE_UNKNOWN;
 }
 
-void tr_comm_table_print(FILE *f, TR_COMM_TABLE *ctab)
+static char *tr_comm_table_append_provenance(char *ctable_s, json_t *prov)
 {
+  const char *s=NULL;
+  char *tmp=NULL;
+  size_t ii=0;
+
+  for (ii=0; ii<json_array_size(prov); ii++) {
+    s=json_string_value(json_array_get(prov, ii));
+    if (s!=NULL) {
+      tmp=talloc_asprintf_append(ctable_s, "%s%s", s, ((ii + 1) == json_array_size(prov)) ? "" : ", ");
+      if (tmp==NULL)
+        return NULL;
+      ctable_s=tmp;
+    }
+  }
+  return ctable_s;
+}
+
+char *tr_comm_table_to_str(TALLOC_CTX *mem_ctx, TR_COMM_TABLE *ctab)
+{
+  TALLOC_CTX *tmp_ctx=talloc_new(NULL);
+  char *ctable_s=NULL;
+  char *tmp=NULL;
+#define append_on_success_helper(tab,tmp,expr) if(NULL==((tmp)=(expr))){(tab)=NULL;goto cleanup;}(tab)=(tmp)
+
   TR_COMM_MEMB *p1=NULL; /* for walking the main list */
   TR_COMM_MEMB *p2=NULL; /* for walking the same-origin lists */
 
-  fprintf(f, ">> Membership table start <<\n");
+  ctable_s=talloc_asprintf(tmp_ctx, ">> Membership table start <<\n");
+  if (ctable_s==NULL)
+    goto cleanup;
+
   for (p1=ctab->memberships; p1!=NULL; p1=p1->next) {
-    fprintf(f, "* %s %s/%s\n  %s (%p)\n",
-            tr_realm_role_to_str(tr_comm_memb_get_role(p1)),
-            tr_comm_memb_get_realm_id(p1)->buf,
-            tr_comm_get_id(tr_comm_memb_get_comm(p1))->buf,
-            (tr_comm_memb_get_origin(p1)==NULL)?"null origin":(tr_comm_memb_get_origin(p1)->buf),
-            p1);
+    append_on_success_helper(
+        ctable_s, tmp,
+        talloc_asprintf_append(ctable_s, "* %s %s/%s\n  %s (%p) - prov: ",
+                               tr_realm_role_to_str(tr_comm_memb_get_role(p1)),
+                               tr_comm_memb_get_realm_id(p1)->buf,
+                               tr_comm_get_id(tr_comm_memb_get_comm(p1))->buf,
+                               (tr_comm_memb_get_origin(p1)==NULL)?"null origin":(tr_comm_memb_get_origin(p1)->buf),
+                               p1));
+
+    append_on_success_helper(ctable_s, tmp, tr_comm_table_append_provenance(ctable_s, p1->provenance));
+
+    append_on_success_helper(ctable_s, tmp, talloc_strdup_append_buffer(ctable_s, "\n"));
+
     for (p2=p1->origin_next; p2!=NULL; p2=p2->origin_next) {
-      fprintf(f, "  %s (%p)\n",
-              (tr_comm_memb_get_origin(p2)==NULL)?"null origin":(tr_comm_memb_get_origin(p2)->buf),
-              p2);
+      append_on_success_helper(
+          ctable_s, tmp,
+          talloc_asprintf_append(ctable_s, "  %s (%p) - prov: ",
+          (tr_comm_memb_get_origin(p2)==NULL)?"null origin":(tr_comm_memb_get_origin(p2)->buf),
+              p2));
+      append_on_success_helper(ctable_s, tmp, tr_comm_table_append_provenance(ctable_s, p2->provenance));
+      append_on_success_helper(ctable_s, tmp, talloc_strdup_append_buffer(ctable_s, "\n"));
     }
-    fprintf(f, "\n");
+    append_on_success_helper(ctable_s, tmp, talloc_strdup_append_buffer(ctable_s, "\n"));
   }
+
+cleanup:
+  if (ctable_s!=NULL)
+    talloc_steal(mem_ctx, ctable_s);
+
+  talloc_free(tmp_ctx);
+  return ctable_s;
 }
+
+void tr_comm_table_print(FILE *f, TR_COMM_TABLE *ctab)
+{
+  char *s=tr_comm_table_to_str(NULL, ctab);
+  if (s!=NULL) {
+    tr_debug("%s", s);
+    talloc_free(s);
+  }
+}
\ No newline at end of file