Don't send communities in triggered updates. Comms now flood!
authorJennifer Richards <jennifer@painless-security.com>
Thu, 27 Oct 2016 18:21:41 +0000 (14:21 -0400)
committerJennifer Richards <jennifer@painless-security.com>
Thu, 27 Oct 2016 18:21:41 +0000 (14:21 -0400)
Community flooding appears to be functional. Does not yet do
correct loop prevention (mismatch between peer labels prevents
detection) or expiration of abandoned community memberships.

common/tr_comm.c
include/tr_comm.h
tr/tr_trp.c
trp/trps.c

index 6222aaf..52d93f1 100644 (file)
@@ -722,6 +722,7 @@ TR_COMM_MEMB *tr_comm_memb_new(TALLOC_CTX *mem_ctx)
     memb->origin=NULL;
     memb->provenance=NULL;
     memb->interval=0;
+    memb->triggered=0;
     memb->expiry=talloc(memb, struct timespec);
     if (memb->expiry==NULL) {
       talloc_free(memb);
@@ -880,8 +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->tv_sec=time->tv_sec;
-  memb->expiry->tv_nsec=time->tv_nsec;
+  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)
@@ -896,6 +901,17 @@ 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);
index 2d91e6a..4d47eaf 100644 (file)
@@ -72,6 +72,7 @@ typedef struct tr_comm_memb {
   json_t *provenance; /* array of names of systems traversed */
   unsigned int interval;
   struct timespec *expiry;
+  int triggered; /* do we need to send this with triggered updates? */
 } TR_COMM_MEMB;
 
 /* table of communities/memberships */
@@ -141,6 +142,8 @@ unsigned int tr_comm_memb_get_interval(TR_COMM_MEMB *memb);
 void tr_comm_memb_set_expiry(TR_COMM_MEMB *memb, struct timespec *time);
 struct timespec *tr_comm_memb_get_expiry(TR_COMM_MEMB *memb);
 int tr_comm_memb_is_expired(TR_COMM_MEMB *memb, struct timespec *curtime);
+void tr_comm_set_triggered(TR_COMM_MEMB *memb, int trig);
+int tr_comm_is_triggered(TR_COMM_MEMB *memb);
 
 TR_COMM *tr_comm_new(TALLOC_CTX *mem_ctx);
 void tr_comm_free(TR_COMM *comm);
index fc8661e..b2b570f 100644 (file)
@@ -317,6 +317,7 @@ static void tr_trps_update(int listener, short event, void *arg)
   tr_debug("tr_trps_update: sending scheduled route/community updates.");
   trps_update(trps, TRP_UPDATE_SCHEDULED);
   event_add(ev, &(trps->update_interval));
+  tr_debug("tr_trps_update: update interval=%d", trps->update_interval.tv_sec);
 }
 
 static void tr_trps_sweep(int listener, short event, void *arg)
index 69c6bde..e7703e3 100644 (file)
@@ -973,10 +973,12 @@ static TRP_RC trps_handle_update(TRPS_INSTANCE *trps, TRP_UPD *upd)
   for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
     switch (trp_inforec_get_type(rec)) {
     case TRP_INFOREC_TYPE_ROUTE:
+      tr_debug("trps_handle_update: handling route inforec.");
       if (TRP_SUCCESS!=trps_handle_inforec_route(trps, upd, rec))
         tr_notice("trps_handle_update: error handling route inforec.");
       break;
     case TRP_INFOREC_TYPE_COMMUNITY:
+      tr_debug("trps_handle_update: handling community inforec.");
       if (TRP_SUCCESS!=trps_handle_inforec_comm(trps, upd, rec))
         tr_notice("trps_handle_update: error handling community inforec.");
       break;
@@ -1422,7 +1424,11 @@ cleanup:
 
 /* Find all community updates to send to a peer and add these as TR_UPD records
  * to the updates GPtrArray. */
-static TRP_RC trps_select_comm_updates_for_peer(TALLOC_CTX *mem_ctx, GPtrArray *updates, TRPS_INSTANCE *trps, TR_NAME *peer_gssname)
+static TRP_RC trps_select_comm_updates_for_peer(TALLOC_CTX *mem_ctx,
+                                                GPtrArray *updates,
+                                                TRPS_INSTANCE *trps,
+                                                TR_NAME *peer_gssname,
+                                                int triggered)
 {
   TALLOC_CTX *tmp_ctx=talloc_new(NULL);
   TR_COMM_ITER *comm_iter=NULL;
@@ -1431,7 +1437,13 @@ static TRP_RC trps_select_comm_updates_for_peer(TALLOC_CTX *mem_ctx, GPtrArray *
   TR_REALM *realm=NULL;
   TRP_UPD *upd=NULL;
   TRP_RC rc=TRP_ERROR;
-  
+
+  /* currently do not send any communities on triggered updates */
+  if (triggered) {
+    rc=TRP_SUCCESS;
+    goto cleanup;
+  }
+
   comm_iter=tr_comm_iter_new(tmp_ctx);
   realm_iter=tr_comm_iter_new(tmp_ctx);
   if ((comm_iter==NULL) || (realm_iter==NULL)) {
@@ -1553,7 +1565,7 @@ static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps,
 
   /* Second, gather community updates */
   tr_debug("trps_update_one_peer: selecting community updates for %.*s.", peer_label->len, peer_label->buf);
-  rc=trps_select_comm_updates_for_peer(tmp_ctx, updates, trps, peer_label);
+  rc=trps_select_comm_updates_for_peer(tmp_ctx, updates, trps, peer_label, update_type==TRP_UPDATE_TRIGGERED);
 
   /* see if we have anything to send */
   if (updates->len<=0)
@@ -1609,7 +1621,7 @@ TRP_RC trps_update(TRPS_INSTANCE *trps, TRP_UPDATE_TYPE update_type)
   }
 
   for (peer=trp_ptable_iter_first(iter, trps->ptable);
-       peer!=NULL && rc==TRP_SUCCESS;
+       (peer!=NULL) && (rc==TRP_SUCCESS);
        peer=trp_ptable_iter_next(iter))
   {
     if (!trps_peer_connected(trps, peer)) {