Support "show routes" monitoring request
authorJennifer Richards <jennifer@painless-security.com>
Thu, 19 Apr 2018 15:51:28 +0000 (11:51 -0400)
committerJennifer Richards <jennifer@painless-security.com>
Thu, 19 Apr 2018 15:51:28 +0000 (11:51 -0400)
  * Separate _to_string and _to_json functions into _encoders.c files
    for trp_rtable and trp_route
  * Add monitoring handler to call trp_rtable_to_json()

13 files changed:
CMakeLists.txt
Makefile.am
include/tr_trp.h
include/trp_route.h
include/trp_rtable.h
tr/tr_main.c
tr/tr_trp_mons.c [new file with mode: 0644]
trp/test/rtbl_test.c
trp/trp_route.c
trp/trp_route_encoders.c [new file with mode: 0644]
trp/trp_rtable.c
trp/trp_rtable_encoders.c [new file with mode: 0644]
trp/trps.c

index cbf7714..06ec038 100644 (file)
@@ -96,7 +96,7 @@ set(SOURCE_FILES
     trp/trp_upd.c
     trp/trpc.c
     trp/trps.c include/tr_name_internal.h mon/mon_req.c mon/mon_req_encode.c mon/mon_req_decode.c
-        mon/mon_resp.c mon/mon_common.c mon/mon_resp_encode.c mon/mon_resp_decode.c tr/tr_mon.c mon/mons.c include/tr_socket.h common/tr_gss.c include/tr_gss.h common/tr_config_internal.c mon/mons_handlers.c include/mons_handlers.h tr/tr_tid_mons.c tr/tr_tid_mons.c trp/trp_route.c include/trp_route.h)
+        mon/mon_resp.c mon/mon_common.c mon/mon_resp_encode.c mon/mon_resp_decode.c tr/tr_mon.c mon/mons.c include/tr_socket.h common/tr_gss.c include/tr_gss.h common/tr_config_internal.c mon/mons_handlers.c include/mons_handlers.h tr/tr_tid_mons.c tr/tr_tid_mons.c trp/trp_route.c include/trp_route.h trp/trp_rtable_encoders.c trp/trp_route_encoders.c)
 
 # Does not actually build!
 add_executable(trust_router ${SOURCE_FILES})
index 8aedded..a558bbc 100644 (file)
@@ -32,9 +32,11 @@ tid/tidc.c
 trp_srcs = trp/trp_conn.c \
 trp/trps.c \
 trp/trpc.c \
-trp/trp_route.c \
 trp/trp_ptable.c \
+trp/trp_route.c \
+trp/trp_route_encoders.c \
 trp/trp_rtable.c \
+trp/trp_rtable_encoders.c \
 trp/trp_req.c \
 trp/trp_upd.c \
 common/tr_config.c \
@@ -89,6 +91,7 @@ tr/tr_cfgwatch.c \
 tr/tr_tid.c \
 tr/tr_tid_mons.c \
 tr/tr_trp.c \
+tr/tr_trp_mons.c \
 tr/tr_mon.c \
 common/tr_gss.c \
 common/tr_gss_client.c \
@@ -136,7 +139,9 @@ common/tr_gss_names.c \
 common/tr_debug.c \
 common/tr_util.c \
 trp/trp_route.c \
-trp/trp_rtable.c
+trp/trp_route_encoders.c \
+trp/trp_rtable.c \
+trp/trp_rtable_encoders.c
 trp_test_rtbl_test_LDADD =  $(GLIB_LIBS)
 
 trp_test_ptbl_test_SOURCES = trp/test/ptbl_test.c \
index 80c9a61..dea20e4 100644 (file)
@@ -80,4 +80,8 @@ TRP_RC tr_trpc_initiate(TRPS_INSTANCE *trps, TRP_PEER *peer, struct event *ev);
 void tr_config_changed(TR_CFG *new_cfg, void *cookie);
 TRP_RC tr_connect_to_peers(TRPS_INSTANCE *trps, struct event *ev);
 void tr_peer_status_change(TRP_PEER *peer, void *cookie);
+
+/* tr_trp_mons.h */
+void tr_trp_register_mons_handlers(TRPS_INSTANCE *trps, MONS_INSTANCE *mons);
+
 #endif /* TR_TRP_H */
index f4451c4..d159861 100644 (file)
@@ -35,6 +35,7 @@
 
 #ifndef TRUST_ROUTER_TRP_ROUTE_H
 #define TRUST_ROUTER_TRP_ROUTE_H
+
 typedef struct trp_route {
   TR_NAME *comm;
   TR_NAME *realm;
@@ -51,6 +52,7 @@ typedef struct trp_route {
   int triggered;
 } TRP_ROUTE;
 
+/* trp_route.c */
 TRP_ROUTE *trp_route_new(TALLOC_CTX *mem_ctx);
 void trp_route_free(TRP_ROUTE *entry);
 void trp_route_set_comm(TRP_ROUTE *entry, TR_NAME *comm);
@@ -80,6 +82,9 @@ void trp_route_set_local(TRP_ROUTE *entry, int local);
 int trp_route_is_local(TRP_ROUTE *entry);
 void trp_route_set_triggered(TRP_ROUTE *entry, int trig);
 int trp_route_is_triggered(TRP_ROUTE *entry);
+
+/* trp_route_encoders.c */
 char *trp_route_to_str(TALLOC_CTX *mem_ctx, TRP_ROUTE *entry, const char *sep);
+json_t *trp_route_to_json(TRP_ROUTE *route);
 
 #endif //TRUST_ROUTER_TRP_ROUTE_H
index 6b3b915..0e0639d 100644 (file)
@@ -45,6 +45,7 @@
 
 typedef GHashTable TRP_RTABLE;
 
+/* trp_rtable.c */
 TRP_RTABLE *trp_rtable_new(void);
 void trp_rtable_free(TRP_RTABLE *rtbl);
 void trp_rtable_add(TRP_RTABLE *rtbl, TRP_ROUTE *entry); /* adds or updates */
@@ -53,7 +54,7 @@ void trp_rtable_clear(TRP_RTABLE *rtbl);
 size_t trp_rtable_size(TRP_RTABLE *rtbl);
 size_t trp_rtable_comm_size(TRP_RTABLE *rtbl, TR_NAME *comm);
 size_t trp_rtable_realm_size(TRP_RTABLE *rtbl, TR_NAME *comm, TR_NAME *realm);
-TRP_ROUTE **trp_rtable_get_entries(TRP_RTABLE *rtbl, size_t *n_out);
+TRP_ROUTE **trp_rtable_get_entries(TALLOC_CTX *mem_ctx, TRP_RTABLE *rtbl, size_t *n_out);
 TR_NAME **trp_rtable_get_comms(TRP_RTABLE *rtbl, size_t *n_out);
 TRP_ROUTE **trp_rtable_get_comm_entries(TRP_RTABLE *rtbl, TR_NAME *comm, size_t *n_out);
 TR_NAME **trp_rtable_get_comm_realms(TRP_RTABLE *rtbl, TR_NAME *comm, size_t *n_out);
@@ -62,7 +63,9 @@ TR_NAME **trp_rtable_get_comm_realm_peers(TRP_RTABLE *rtbl, TR_NAME *comm, TR_NA
 TRP_ROUTE *trp_rtable_get_entry(TRP_RTABLE *rtbl, TR_NAME *comm, TR_NAME *realm, TR_NAME *peer);
 TRP_ROUTE *trp_rtable_get_selected_entry(TRP_RTABLE *rtbl, TR_NAME *comm, TR_NAME *realm);
 void trp_rtable_clear_triggered(TRP_RTABLE *rtbl);
-char *trp_rtable_to_str(TALLOC_CTX *mem_ctx, TRP_RTABLE *rtbl, const char *sep, const char *lineterm);
 
+/* trp_rtable_encoders.c */
+char *trp_rtable_to_str(TALLOC_CTX *mem_ctx, TRP_RTABLE *rtbl, const char *sep, const char *lineterm);
+json_t *trp_rtable_to_json(TRP_RTABLE *rtbl);
 
 #endif /* _TRP_RTABLE_H_ */
index 68f682e..1b8da2b 100644 (file)
@@ -234,7 +234,8 @@ int main(int argc, char *argv[])
   mons_register_handler(tr->mons, MON_CMD_SHOW, OPT_TYPE_SHOW_VERSION, tr_mon_handle_version, NULL);
   mons_register_handler(tr->mons, MON_CMD_SHOW, OPT_TYPE_SHOW_UPTIME, tr_mon_handle_uptime, &start_time);
   tr_tid_register_mons_handlers(tr->tids, tr->mons);
-  
+  tr_trp_register_mons_handlers(tr->trps, tr->mons);
+
   /***** process configuration *****/
   tr->cfgwatch=tr_cfgwatch_create(tr);
   if (tr->cfgwatch == NULL) {
diff --git a/tr/tr_trp_mons.c b/tr/tr_trp_mons.c
new file mode 100644 (file)
index 0000000..9c38f0d
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Monitoring handlers for trust router TID server */
+
+#include <jansson.h>
+#include <trp_internal.h>
+#include <tr_trp.h>
+#include <trp_rtable.h>
+#include <mon_internal.h>
+#include <mons_handlers.h>
+
+static MON_RC handle_show_routes(void *cookie, json_t **response_ptr)
+{
+  TRPS_INSTANCE *trps = talloc_get_type_abort(cookie, TRPS_INSTANCE);
+
+  *response_ptr = trp_rtable_to_json(trps->rtable);
+  return (*response_ptr == NULL) ? MON_NOMEM : MON_SUCCESS;
+}
+
+void tr_trp_register_mons_handlers(TRPS_INSTANCE *trps, MONS_INSTANCE *mons)
+{
+  mons_register_handler(mons,
+                        MON_CMD_SHOW, OPT_TYPE_SHOW_ROUTES,
+                        handle_show_routes, trps);
+}
index 8faccca..e651941 100644 (file)
@@ -244,7 +244,7 @@ static void update_metric(TRP_RTABLE *table, unsigned int (*new_metric)(size_t,
   TRP_ROUTE **entries=NULL;
   size_t n=0, ii=0,jj=0,kk=0;
 
-  entries=trp_rtable_get_entries(table, &n);
+  entries= trp_rtable_get_entries(NULL, table, &n);
   while (n--) {
     ii=get_index(trp_route_get_comm(entries[n])->buf, apc, n_apc);
     jj=get_index(trp_route_get_realm(entries[n])->buf, realm, n_realm);
index d333a8f..1334032 100644 (file)
@@ -45,7 +45,6 @@
 #include <tr_debug.h>
 #include <trust_router/trp.h>
 #include <trust_router/tid.h>
-#include <tr_util.h>
 
 
 /* Note: be careful mixing talloc with glib. */
@@ -250,39 +249,3 @@ int trp_route_is_triggered(TRP_ROUTE *entry)
 {
   return entry->triggered;
 }
-
-/* Pretty print a route table entry to a newly allocated string. If sep is NULL,
- * returns comma+space separated string. */
-char *trp_route_to_str(TALLOC_CTX *mem_ctx, TRP_ROUTE *entry, const char *sep)
-{
-  char *comm=tr_name_strdup(entry->comm);
-  char *realm=tr_name_strdup(entry->realm);
-  char *peer=tr_name_strdup(entry->peer);
-  char *trust_router=tr_name_strdup(entry->trust_router);
-  char *next_hop=tr_name_strdup(entry->next_hop);
-  char *expiry=timespec_to_str(entry->expiry);
-  char *result=NULL;
-
-  if (sep==NULL)
-    sep=", ";
-
-  result=talloc_asprintf(mem_ctx,
-                         "%s%s%s%s%s%s%u%s%s%s%s%s%u%s%u%s%s%s%u",
-                         comm, sep,
-                         realm, sep,
-                         peer, sep,
-                         entry->metric, sep,
-                         trust_router, sep,
-                         next_hop, sep,
-                         entry->selected, sep,
-                         entry->local, sep,
-                         expiry, sep,
-                         entry->triggered);
-  free(comm);
-  free(realm);
-  free(peer);
-  free(trust_router);
-  free(next_hop);
-  free(expiry);
-  return result;
-}
diff --git a/trp/trp_route_encoders.c b/trp/trp_route_encoders.c
new file mode 100644 (file)
index 0000000..66546af
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016-2018, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <talloc.h>
+#include <jansson.h>
+
+#include <tr_name_internal.h>
+#include <trp_route.h>
+#include <trp_internal.h>
+#include <trp_rtable.h>
+#include <trust_router/trp.h>
+#include <tr_util.h>
+
+/* Pretty print a route table entry to a newly allocated string. If sep is NULL,
+ * returns comma+space separated string. */
+char *trp_route_to_str(TALLOC_CTX *mem_ctx, TRP_ROUTE *entry, const char *sep)
+{
+  char *comm=tr_name_strdup(entry->comm);
+  char *realm=tr_name_strdup(entry->realm);
+  char *peer=tr_name_strdup(entry->peer);
+  char *trust_router=tr_name_strdup(entry->trust_router);
+  char *next_hop=tr_name_strdup(entry->next_hop);
+  char *expiry=timespec_to_str(entry->expiry);
+  char *result=NULL;
+
+  if (sep==NULL)
+    sep=", ";
+
+  result=talloc_asprintf(mem_ctx,
+                         "%s%s%s%s%s%s%u%s%s%s%s%s%u%s%u%s%s%s%u",
+                         comm, sep,
+                         realm, sep,
+                         peer, sep,
+                         entry->metric, sep,
+                         trust_router, sep,
+                         next_hop, sep,
+                         entry->selected, sep,
+                         entry->local, sep,
+                         expiry, sep,
+                         entry->triggered);
+  free(comm);
+  free(realm);
+  free(peer);
+  free(trust_router);
+  free(next_hop);
+  free(expiry);
+  return result;
+}
+
+/* helper for below */
+#define OBJECT_SET_OR_FAIL(jobj, key, val)     \
+do {                                           \
+  if (val)                                     \
+    json_object_set_new((jobj),(key),(val));   \
+  else                                         \
+    goto cleanup;                              \
+} while (0)
+
+json_t *trp_route_to_json(TRP_ROUTE *route)
+{
+  json_t *route_json = NULL;
+  char *expires = NULL;
+  struct timespec ts_zero = {0, 0};
+
+  route_json = json_object();
+  if (route_json == NULL)
+    return NULL;
+
+  if (tr_cmp_timespec(trp_route_get_expiry(route), &ts_zero) == 0) {
+    expires = strdup("");
+  } else {
+    expires = timespec_to_str(route->expiry);
+    if (expires == NULL) {
+      json_decref(route_json);
+      return NULL;
+    }
+  }
+
+  OBJECT_SET_OR_FAIL(route_json, "community", tr_name_to_json_string(route->comm));
+  OBJECT_SET_OR_FAIL(route_json, "realm", tr_name_to_json_string(route->realm));
+  OBJECT_SET_OR_FAIL(route_json, "peer", tr_name_to_json_string(route->peer));
+  OBJECT_SET_OR_FAIL(route_json, "metric", json_integer(route->metric));
+  OBJECT_SET_OR_FAIL(route_json, "trust_router", tr_name_to_json_string(route->trust_router));
+  OBJECT_SET_OR_FAIL(route_json, "next_hop", tr_name_to_json_string(route->next_hop));
+  OBJECT_SET_OR_FAIL(route_json, "selected", json_boolean(route->selected));
+  OBJECT_SET_OR_FAIL(route_json, "local", json_boolean(route->local));
+  OBJECT_SET_OR_FAIL(route_json, "expires", json_string(expires));
+
+cleanup:
+  free(expires);
+  return route_json;
+}
\ No newline at end of file
index 7f79351..2926309 100644 (file)
@@ -229,9 +229,9 @@ size_t trp_rtable_realm_size(TRP_RTABLE *rtbl, TR_NAME *comm, TR_NAME *realm)
 }
 
 /* Returns an array of pointers to TRP_ROUTE, length of array in n_out.
- * Caller must free the array (in the talloc NULL context), but must
+ * Caller must free the array (in the mem_ctx context), but must
  * not free its contents. */
-TRP_ROUTE **trp_rtable_get_entries(TRP_RTABLE *rtbl, size_t *n_out)
+TRP_ROUTE **trp_rtable_get_entries(TALLOC_CTX *mem_ctx, TRP_RTABLE *rtbl, size_t *n_out)
 {
   TRP_ROUTE **ret=NULL;
   TR_NAME **comm=NULL;
@@ -244,7 +244,7 @@ TRP_ROUTE **trp_rtable_get_entries(TRP_RTABLE *rtbl, size_t *n_out)
   if (*n_out==0)
     return NULL;
 
-  ret=talloc_array(NULL, TRP_ROUTE *, *n_out);
+  ret=talloc_array(mem_ctx, TRP_ROUTE *, *n_out);
   if (ret==NULL) {
     tr_crit("trp_rtable_get_entries: unable to allocate return array.");
     *n_out=0;
@@ -457,7 +457,7 @@ TRP_ROUTE *trp_rtable_get_selected_entry(TRP_RTABLE *rtbl, TR_NAME *comm, TR_NAM
 void trp_rtable_clear_triggered(TRP_RTABLE *rtbl)
 {
   size_t n_entries=0;
-  TRP_ROUTE **entries=trp_rtable_get_entries(rtbl, &n_entries);
+  TRP_ROUTE **entries= trp_rtable_get_entries(NULL, rtbl, &n_entries);
   size_t ii=0;
 
   if (entries!=NULL) {
@@ -466,84 +466,3 @@ void trp_rtable_clear_triggered(TRP_RTABLE *rtbl)
     talloc_free(entries);
   }
 }
-
-static int sort_tr_names_cmp(const void *a, const void *b)
-{
-  TR_NAME **n1=(TR_NAME **)a;
-  TR_NAME **n2=(TR_NAME **)b;
-  return tr_name_cmp(*n1, *n2);
-}
-
-static void sort_tr_names(TR_NAME **names, size_t n_names)
-{
-  qsort(names, n_names, sizeof(TR_NAME *), sort_tr_names_cmp);
-}
-
-char *trp_rtable_to_str(TALLOC_CTX *mem_ctx, TRP_RTABLE *rtbl, const char *sep, const char *lineterm)
-{
-  TALLOC_CTX *tmp_ctx=talloc_new(NULL);
-  TR_NAME **comms=NULL;
-  size_t n_comms=0;
-  TR_NAME **realms=NULL;
-  size_t n_realms=0;
-  TRP_ROUTE **entries=NULL;
-  size_t n_entries=0;
-  char **tbl_strings=NULL;
-  size_t ii_tbl=0; /* counts tbl_strings */
-  size_t tbl_size=0;
-  size_t len=0;
-  size_t ii=0, jj=0, kk=0;
-  char *p=NULL;
-  char *result=NULL;
-
-  if (lineterm==NULL)
-    lineterm="\n";
-
-  tbl_size=trp_rtable_size(rtbl);
-  if (tbl_size==0) {
-    result=talloc_strdup(mem_ctx, lineterm);
-    goto cleanup;
-  }
-
-  tbl_strings=talloc_array(tmp_ctx, char *, tbl_size);
-  if (tbl_strings==NULL) {
-    result=talloc_strdup(mem_ctx, "error");
-    goto cleanup;
-  }
-  
-  comms=trp_rtable_get_comms(rtbl, &n_comms);
-  talloc_steal(tmp_ctx, comms);
-  sort_tr_names(comms, n_comms);
-  ii_tbl=0;
-  len=0;
-  for (ii=0; ii<n_comms; ii++) {
-    realms=trp_rtable_get_comm_realms(rtbl, comms[ii], &n_realms);
-    talloc_steal(tmp_ctx, realms);
-    sort_tr_names(realms, n_realms);
-    for (jj=0; jj<n_realms; jj++) {
-      entries=trp_rtable_get_realm_entries(rtbl, comms[ii], realms[jj], &n_entries);
-      talloc_steal(tmp_ctx, entries);
-      for (kk=0; kk<n_entries; kk++) {
-        tbl_strings[ii_tbl]=trp_route_to_str(tmp_ctx, entries[kk], sep);
-        len+=strlen(tbl_strings[ii_tbl]);
-        ii_tbl++;
-      }
-      talloc_free(entries);
-    }
-    talloc_free(realms);
-  }
-  talloc_free(comms);
-
-  /* now combine all the strings */
-  len += tbl_size*strlen(lineterm); /* space for line terminations*/
-  len += 1; /* nul terminator */
-  result=(char *)talloc_size(tmp_ctx, len);
-  for (p=result,ii=0; ii < tbl_size; ii++) {
-    p+=sprintf(p, "%s%s", tbl_strings[ii], lineterm);
-  }
-  talloc_steal(mem_ctx, result);
-  
-cleanup:
-  talloc_free(tmp_ctx);
-  return result;
-}
diff --git a/trp/trp_rtable_encoders.c b/trp/trp_rtable_encoders.c
new file mode 100644 (file)
index 0000000..ca63d6b
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2016-2018, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdlib.h>
+
+#include <talloc.h>
+#include <jansson.h>
+
+#include <tr_name_internal.h>
+#include <trp_route.h>
+#include <trp_internal.h>
+#include <trp_rtable.h>
+#include <trust_router/trp.h>
+
+
+static int sort_tr_names_cmp(const void *a, const void *b)
+{
+  TR_NAME **n1=(TR_NAME **)a;
+  TR_NAME **n2=(TR_NAME **)b;
+  return tr_name_cmp(*n1, *n2);
+}
+
+static void sort_tr_names(TR_NAME **names, size_t n_names)
+{
+  qsort(names, n_names, sizeof(TR_NAME *), sort_tr_names_cmp);
+}
+
+char *trp_rtable_to_str(TALLOC_CTX *mem_ctx, TRP_RTABLE *rtbl, const char *sep, const char *lineterm)
+{
+  TALLOC_CTX *tmp_ctx=talloc_new(NULL);
+  TR_NAME **comms=NULL;
+  size_t n_comms=0;
+  TR_NAME **realms=NULL;
+  size_t n_realms=0;
+  TRP_ROUTE **entries=NULL;
+  size_t n_entries=0;
+  char **tbl_strings=NULL;
+  size_t ii_tbl=0; /* counts tbl_strings */
+  size_t tbl_size=0;
+  size_t len=0;
+  size_t ii=0, jj=0, kk=0;
+  char *p=NULL;
+  char *result=NULL;
+
+  if (lineterm==NULL)
+    lineterm="\n";
+
+  tbl_size=trp_rtable_size(rtbl);
+  if (tbl_size==0) {
+    result=talloc_strdup(mem_ctx, lineterm);
+    goto cleanup;
+  }
+
+  tbl_strings=talloc_array(tmp_ctx, char *, tbl_size);
+  if (tbl_strings==NULL) {
+    result=talloc_strdup(mem_ctx, "error");
+    goto cleanup;
+  }
+
+  comms=trp_rtable_get_comms(rtbl, &n_comms);
+  talloc_steal(tmp_ctx, comms);
+  sort_tr_names(comms, n_comms);
+  ii_tbl=0;
+  len=0;
+  for (ii=0; ii<n_comms; ii++) {
+    realms=trp_rtable_get_comm_realms(rtbl, comms[ii], &n_realms);
+    talloc_steal(tmp_ctx, realms);
+    sort_tr_names(realms, n_realms);
+    for (jj=0; jj<n_realms; jj++) {
+      entries=trp_rtable_get_realm_entries(rtbl, comms[ii], realms[jj], &n_entries);
+      talloc_steal(tmp_ctx, entries);
+      for (kk=0; kk<n_entries; kk++) {
+        tbl_strings[ii_tbl]=trp_route_to_str(tmp_ctx, entries[kk], sep);
+        len+=strlen(tbl_strings[ii_tbl]);
+        ii_tbl++;
+      }
+      talloc_free(entries);
+    }
+    talloc_free(realms);
+  }
+  talloc_free(comms);
+
+  /* now combine all the strings */
+  len += tbl_size*strlen(lineterm); /* space for line terminations*/
+  len += 1; /* nul terminator */
+  result=(char *)talloc_size(tmp_ctx, len);
+  for (p=result,ii=0; ii < tbl_size; ii++) {
+    p+=sprintf(p, "%s%s", tbl_strings[ii], lineterm);
+  }
+  talloc_steal(mem_ctx, result);
+
+cleanup:
+  talloc_free(tmp_ctx);
+  return result;
+}
+
+
+json_t *trp_rtable_to_json(TRP_RTABLE *rtbl)
+{
+  TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+  json_t *rtable_json = NULL;
+  json_t *route_json = NULL;
+  TRP_ROUTE **routes = NULL;
+  size_t n_routes = 0;
+  json_t *retval = NULL;
+
+  /* Get the JSON array to return */
+  rtable_json = json_array();
+  if (rtable_json == NULL)
+    goto cleanup;
+
+  /* Get the array of routes */
+  routes = trp_rtable_get_entries(tmp_ctx, rtbl, &n_routes);
+  if (routes == NULL)
+    goto cleanup;
+
+  /* Gather JSON for each route */
+  while (n_routes > 0) {
+    route_json = trp_route_to_json(routes[--n_routes]);
+    if (route_json == NULL)
+      goto cleanup;
+    json_array_append_new(rtable_json, route_json);
+  }
+
+  /* Success - set the return value and increment the reference count */
+  retval = rtable_json;
+  json_incref(retval);
+
+cleanup:
+  if (rtable_json)
+    json_decref(rtable_json);
+  talloc_free(tmp_ctx);
+  return retval;
+}
index c97ac8f..e2339b5 100644 (file)
@@ -1146,7 +1146,7 @@ TRP_RC trps_sweep_routes(TRPS_INSTANCE *trps)
     return TRP_ERROR;
   }
 
-  entry=trp_rtable_get_entries(trps->rtable, &n_entry); /* must talloc_free *entry */
+  entry= trp_rtable_get_entries(NULL, trps->rtable, &n_entry); /* must talloc_free *entry */
 
   /* loop over the entries */
   for (ii=0; ii<n_entry; ii++) {