Don't send communities in triggered updates. Comms now flood!
[trust_router.git] / common / tr_comm.c
index 2dd637a..52d93f1 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <jansson.h>
 #include <talloc.h>
+#include <sys/time.h>
 
 #include <tr_rp.h>
 #include <tr_idp.h>
@@ -98,6 +99,14 @@ void tr_comm_decref(TR_COMM *comm)
     comm->refcount--;
 }
 
+void tr_comm_set_apcs(TR_COMM *comm, TR_APC *apc)
+{
+  if (comm->apcs!=NULL)
+    tr_apc_free(comm->apcs);
+  comm->apcs=apc;
+  talloc_steal(comm, apc);
+}
+
 TR_APC *tr_comm_get_apcs(TR_COMM *comm)
 {
   return comm->apcs;
@@ -268,18 +277,33 @@ static TR_COMM *tr_comm_add_func(TR_COMM *comms, TR_COMM *new)
   return comms;
 }
 
-/* guarantees comm is not in the list, not an error if it was't there */
+/* Guarantees comm is not in the list, not an error if it was't there.
+ * Does not free the removed element, nor change its talloc context. */
 #define tr_comm_remove(comms, c) ((comms)=tr_comm_remove_func((comms), (c)))
 static TR_COMM *tr_comm_remove_func(TR_COMM *comms, TR_COMM *remove)
 {
-  TR_COMM *this=comms;
+  TALLOC_CTX *list_ctx=talloc_parent(comms); /* in case we need to remove the head */
+  TR_COMM *this=NULL;
 
-  if ((this==NULL) || (this==remove))
+  if (comms==NULL)
     return NULL;
-  
-  for (; this->next!=NULL; this=this->next) {
-    if (this->next==remove)
-      this->next=remove->next;
+
+  if (comms==remove) {
+    /* if we're removing the head, put the next element (if present) into the context
+     * the list head was in. */
+    comms=comms->next;
+    if (comms!=NULL) {
+      talloc_steal(list_ctx, comms->next);
+      /* now put all the other elements in the context of the list head */
+      for (this=comms->next; this!=NULL; this=this->next)
+        talloc_steal(comms, this);
+    }
+  } else {
+    /* not removing the head; no need to play with contexts */
+    for (this=comms; this->next!=NULL; this=this->next) {
+      if (this->next==remove)
+        this->next=remove->next;
+    }
   }
   return comms;
 }
@@ -464,24 +488,16 @@ static void tr_realm_free(TR_REALM *realm)
 
 static void tr_realm_set_rp(TR_REALM *realm, TR_RP_REALM *rp)
 {
-  if (realm->rp!=NULL)
-    talloc_free(realm->rp);
-  if (realm->idp!=NULL) {
-    talloc_free(realm->idp);
+  if (realm->idp!=NULL)
     realm->idp=NULL;
-  }
   realm->role=TR_ROLE_RP;
   realm->rp=rp;
 }
 
 static void tr_realm_set_idp(TR_REALM *realm, TR_IDP_REALM *idp)
 {
-  if (realm->idp!=NULL)
-    talloc_free(realm->idp);
-  if (realm->rp!=NULL) {
-    talloc_free(realm->rp);
+  if (realm->rp!=NULL)
     realm->rp=NULL;
-  }
   realm->role=TR_ROLE_IDP;
   realm->idp=idp;
 }
@@ -699,13 +715,20 @@ TR_COMM_MEMB *tr_comm_memb_new(TALLOC_CTX *mem_ctx)
   TR_COMM_MEMB *memb=talloc(mem_ctx, TR_COMM_MEMB);
   if (memb!=NULL) {
     memb->next=NULL;
+    memb->origin_next=NULL;
     memb->idp=NULL;
     memb->rp=NULL;
     memb->comm=NULL;
     memb->origin=NULL;
     memb->provenance=NULL;
     memb->interval=0;
-    memb->expiry=NULL;
+    memb->triggered=0;
+    memb->expiry=talloc(memb, struct timespec);
+    if (memb->expiry==NULL) {
+      talloc_free(memb);
+      return NULL;
+    }
+    *(memb->expiry)=(struct timespec){0,0};
     talloc_set_destructor(memb, tr_comm_memb_destructor);
   }
   return memb;
@@ -858,7 +881,12 @@ unsigned int tr_comm_memb_get_interval(TR_COMM_MEMB *memb)
 
 void tr_comm_memb_set_expiry(TR_COMM_MEMB *memb, struct timespec *time)
 {
-  memb->expiry=time;
+  if (time==NULL)
+    *(memb->expiry)=(struct timespec){0,0};
+  else {
+    memb->expiry->tv_sec=time->tv_sec;
+    memb->expiry->tv_nsec=time->tv_nsec;
+  }
 }
 
 struct timespec *tr_comm_memb_get_expiry(TR_COMM_MEMB *memb)
@@ -873,12 +901,25 @@ int tr_comm_memb_is_expired(TR_COMM_MEMB *memb, struct timespec *curtime)
             &&(curtime->tv_nsec >= memb->expiry->tv_nsec)));
 }
 
+void tr_comm_set_triggered(TR_COMM_MEMB *memb, int trig)
+{
+  memb->triggered=trig;
+}
+
+int tr_comm_is_triggered(TR_COMM_MEMB *memb)
+{
+  return memb->triggered;
+}
+
+
 TR_COMM_TABLE *tr_comm_table_new(TALLOC_CTX *mem_ctx)
 {
   TR_COMM_TABLE *ctab=talloc(mem_ctx, TR_COMM_TABLE);
   if (ctab!=NULL) {
     ctab->comms=NULL;
     ctab->memberships=NULL;
+    ctab->idp_realms=NULL;
+    ctab->rp_realms=NULL;
   }
   return ctab;
 }
@@ -902,6 +943,8 @@ void tr_comm_table_add_memb(TR_COMM_TABLE *ctab, TR_COMM_MEMB *new)
 {
   TR_COMM_MEMB *cur=NULL;
 
+  /* TODO: validate the member (must have valid comm and realm) */
+
   /* handle the empty list case */
   if (ctab->memberships==NULL) {
     ctab->memberships=new;