Support non-default TRP and TID ports
authorJennifer Richards <jennifer@painless-security.com>
Thu, 24 May 2018 22:30:11 +0000 (18:30 -0400)
committerJennifer Richards <jennifer@painless-security.com>
Thu, 24 May 2018 22:30:11 +0000 (18:30 -0400)
  * Include trust_router and next_hop ports in inforecs, routes, and
    update msgs
    - affects encoders and decoders
    - use next_hop from the inforec instead of assuming it is the
      peer's server address
    - default next_hop to the trust_router for backward compatibility
    - default both ports to the standard well-known ports if not given
  * fill in local routes with our hostname/port
    - no longer permit empty next_hop fields
  * Update filter handlers
    - handle next_hop field
    - use hostname:port format (or just hostname with default port)
    - handle next_hop field
  * Keep track of AAA server ports
  * Be more careful with tr_msg JSON helper return values
  * Use tr_name_strdup() to avoid ad hoc conversion from name to string
  * Use signed int as port to allow -1 as an invalid port indicator
  * Remove now-obsolete tr_aaa_server_from_name() function

14 files changed:
common/tr_filter.c
common/tr_msg.c
common/tr_util.c
include/tr_aaa_server.h
include/tr_util.h
include/trp_internal.h
include/trp_route.h
include/trust_router/trp.h
tr/tr_tid.c
tr/tr_trp.c
trp/trp_route.c
trp/trp_route_encoders.c
trp/trp_upd.c
trp/trps.c

index 2b94526..0d7c5c4 100644 (file)
@@ -42,6 +42,7 @@
 #include <trp_internal.h>
 #include <tid_internal.h>
 #include <tr_debug.h>
+#include <tr_util.h>
 
 /* Function types for handling filter fields generally. All target values
  * are represented as strings in a TR_NAME.
@@ -280,15 +281,59 @@ static TR_NAME *tr_ff_get_trp_owner_realm(TR_FILTER_TARGET *target)
   return tr_dup_name(trp_inforec_get_owner_realm(target->trp_inforec));
 }
 
+/** Generic handlers for host:port fields*/
+static TR_NAME *tr_ff_get_hostname_and_port(TR_NAME *hn, int port)
+{
+  return tr_hostname_and_port_to_name(hn, port);
+}
+
+static int tr_ff_cmp_hostname_and_port(TR_NAME *hn, int port, int default_port, TR_NAME *val)
+{
+  int cmp = -1;
+  TR_NAME *n = NULL;
+
+  /* allow a match without :port if the default port is in use */
+  if ((port == default_port) && (tr_name_cmp(hn, val) == 0))
+    return 0;
+
+  /* need to match with the :port */
+  n = tr_ff_get_hostname_and_port(hn, port);
+
+  if (n) {
+    cmp = tr_name_cmp(n, val);
+    tr_free_name(n);
+  }
+  return cmp;
+}
+
 /** Handlers for TRP trust_router field */
 static int tr_ff_cmp_trp_trust_router(TR_FILTER_TARGET *target, TR_NAME *val)
 {
-  return tr_name_cmp(trp_inforec_get_trust_router(target->trp_inforec), val);
+  return tr_ff_cmp_hostname_and_port(trp_inforec_get_trust_router(target->trp_inforec),
+                                     trp_inforec_get_trust_router_port(target->trp_inforec),
+                                     TRP_PORT,
+                                     val);
 }
 
 static TR_NAME *tr_ff_get_trp_trust_router(TR_FILTER_TARGET *target)
 {
-  return tr_dup_name(trp_inforec_get_trust_router(target->trp_inforec));
+  return tr_ff_get_hostname_and_port(trp_inforec_get_trust_router(target->trp_inforec),
+                                     trp_inforec_get_trust_router_port(target->trp_inforec));
+}
+
+/** Handlers for TRP next_hop field */
+static int tr_ff_cmp_trp_next_hop(TR_FILTER_TARGET *target, TR_NAME *val)
+{
+  return tr_ff_cmp_hostname_and_port(trp_inforec_get_next_hop(target->trp_inforec),
+                                     trp_inforec_get_next_hop_port(target->trp_inforec),
+                                     TID_PORT,
+                                     val);
+}
+
+static TR_NAME *tr_ff_get_trp_next_hop(TR_FILTER_TARGET *target)
+{
+  return tr_ff_get_hostname_and_port(trp_inforec_get_next_hop(target->trp_inforec),
+                                     trp_inforec_get_next_hop_port(target->trp_inforec));
 }
 
 /** Handlers for TRP owner_contact field */
@@ -349,6 +394,10 @@ static struct tr_filter_field_entry tr_filter_field_table[] = {
     {TR_FILTER_TYPE_TRP_INBOUND, "trust_router", tr_ff_cmp_trp_trust_router, tr_ff_get_trp_trust_router},
     {TR_FILTER_TYPE_TRP_OUTBOUND, "trust_router", tr_ff_cmp_trp_trust_router, tr_ff_get_trp_trust_router},
 
+    /* next_hop */
+    {TR_FILTER_TYPE_TRP_INBOUND, "next_hop", tr_ff_cmp_trp_next_hop, tr_ff_get_trp_next_hop},
+    {TR_FILTER_TYPE_TRP_OUTBOUND, "next_hop", tr_ff_cmp_trp_next_hop, tr_ff_get_trp_next_hop},
+
     /* owner_realm */
     {TR_FILTER_TYPE_TRP_INBOUND, "owner_realm", tr_ff_cmp_trp_owner_realm, tr_ff_get_trp_owner_realm},
     {TR_FILTER_TYPE_TRP_OUTBOUND, "owner_realm", tr_ff_cmp_trp_owner_realm, tr_ff_get_trp_owner_realm},
index 50e8bc9..350fc5b 100644 (file)
 #include <trp_internal.h>
 #include <mon_internal.h>
 #include <tr_msg.h>
+#include <tr_util.h>
 #include <tr_name_internal.h>
 #include <trust_router/tr_constraint.h>
 #include <trust_router/tr_dh.h>
 #include <tr_debug.h>
 
 /* JSON helpers */
-/* Read attribute attr from msg as an integer. Returns nonzero on error. */
-static int tr_msg_get_json_integer(json_t *jmsg, const char *attr, int *dest)
+/* Read attribute attr from msg as an integer. */
+static TRP_RC tr_msg_get_json_integer(json_t *jmsg, const char *attr, int *dest)
 {
   json_t *obj;
 
   obj=json_object_get(jmsg, attr);
   if (obj == NULL) {
-    return -1;
+    return TRP_MISSING;
   }
   /* check type */
   if (!json_is_integer(obj)) {
-    return -1;
+    return TRP_BADTYPE;
   }
 
   (*dest)=json_integer_value(obj);
-  return 0;
+  return TRP_SUCCESS;
 }
 
 /* Read attribute attr from msg as a string. Copies string into mem_ctx context so jmsg can
@@ -78,15 +79,15 @@ static TRP_RC tr_msg_get_json_string(json_t *jmsg, const char *attr, char **dest
 
   obj=json_object_get(jmsg, attr);
   if (obj == NULL)
-    return TRP_ERROR;
+    return TRP_MISSING;
 
   /* check type */
   if (!json_is_string(obj))
-    return TRP_ERROR;
+    return TRP_BADTYPE;
 
   *dest=talloc_strdup(mem_ctx, json_string_value(obj));
   if (*dest==NULL)
-    return TRP_ERROR;
+    return TRP_NOMEM;
 
   return TRP_SUCCESS;
 }
@@ -678,14 +679,33 @@ static TID_RESP *tr_msg_decode_tidresp(TALLOC_CTX *mem_ctx, json_t *jresp)
   return tresp;
 }
 
+static json_t *hostname_and_port_to_json(TR_NAME *hostname, int port)
+{
+  char *s_hostname = tr_name_strdup(hostname);
+  char *s;
+  json_t *j;
+
+  if (s_hostname == NULL)
+    return NULL;
+
+  s = talloc_asprintf(NULL, "%s:%d", s_hostname, port);
+  free(s_hostname);
+
+  if (s == NULL)
+    return NULL;
+
+  j = json_string(s);
+  talloc_free(s);
+
+  return j;
+}
 
-/* Information records for TRP update msg 
+/* Information records for TRP update msg
  * requires that jrec already be allocated */
 static TRP_RC tr_msg_encode_inforec_route(json_t *jrec, TRP_INFOREC *rec)
 {
   json_t *jstr=NULL;
   json_t *jint=NULL;
-  char *s=NULL;
 
   if (rec==NULL)
     return TRP_BADTYPE;
@@ -693,15 +713,18 @@ static TRP_RC tr_msg_encode_inforec_route(json_t *jrec, TRP_INFOREC *rec)
   if (trp_inforec_get_trust_router(rec)==NULL)
     return TRP_ERROR;
 
-  s=tr_name_strdup(trp_inforec_get_trust_router(rec));
-  if (s==NULL)
-    return TRP_NOMEM;
-  jstr=json_string(s);
-  free(s);s=NULL;
+  jstr=hostname_and_port_to_json(trp_inforec_get_trust_router(rec),
+                                 trp_inforec_get_trust_router_port(rec));
   if(jstr==NULL)
-    return TRP_ERROR;
+    return TRP_NOMEM;
   json_object_set_new(jrec, "trust_router", jstr);
 
+  jstr=hostname_and_port_to_json(trp_inforec_get_next_hop(rec),
+                                 trp_inforec_get_next_hop_port(rec));
+  if(jstr==NULL)
+    return TRP_NOMEM;
+  json_object_set_new(jrec, "next_hop", jstr);
+
   jint=json_integer(trp_inforec_get_metric(rec));
   if(jint==NULL)
     return TRP_ERROR;
@@ -892,18 +915,63 @@ static TRP_RC tr_msg_decode_trp_inforec_route(json_t *jrecord, TRP_INFOREC *rec)
   TALLOC_CTX *tmp_ctx=talloc_new(NULL);
   TRP_RC rc=TRP_ERROR;
   char *s=NULL;
+  TR_NAME *name;
+  int port;
   int num=0;
 
+  /* get the trust router */
   rc=tr_msg_get_json_string(jrecord, "trust_router", &s, tmp_ctx);
   if (rc != TRP_SUCCESS)
     goto cleanup;
-  if (TRP_SUCCESS!=trp_inforec_set_trust_router(rec, tr_new_name(s))) {
+
+  if (0 != tr_parse_hostname_and_port(s, &name, &port)) {
+    rc = TRP_ERROR;
+    goto cleanup;
+  }
+  talloc_free(s); s=NULL;
+
+  if (port == 0)
+    port = TRP_PORT;
+
+  if (TRP_SUCCESS!= trp_inforec_set_trust_router(rec, name, port)) {
     rc=TRP_ERROR;
     goto cleanup;
   }
+
+  /* Now do the next hop. If it's not present, use the trust_router for backward
+   * compatibility */
+  switch(tr_msg_get_json_string(jrecord, "next_hop", &s, tmp_ctx)) {
+    case TRP_SUCCESS:
+      /* we got a next_hop field */
+      if (0 != tr_parse_hostname_and_port(s, &name, &port)) {
+        rc = TRP_ERROR;
+        goto cleanup;
+      }
+      break;
+
+    case TRP_MISSING:
+      /* no next_hop field; use the trust router */
+      name = tr_dup_name(trp_inforec_get_trust_router(rec));
+      if (name == NULL) {
+        rc = TRP_ERROR;
+        goto cleanup;
+      }
+      break;
+
+    default:
+      /* something went wrong */
+      rc = TRP_ERROR;
+      goto cleanup;
+  }
   talloc_free(s); s=NULL;
 
-  trp_inforec_set_next_hop(rec, NULL); /* make sure this is null (filled in later) */
+  if (port == 0)
+    port = TID_PORT;
+
+  if (TRP_SUCCESS!= trp_inforec_set_next_hop(rec, name, port)) {
+    rc=TRP_ERROR;
+    goto cleanup;
+  }
 
   rc=tr_msg_get_json_integer(jrecord, "metric", &num);
   if ((rc != TRP_SUCCESS) || (TRP_SUCCESS!=trp_inforec_set_metric(rec,num)))
index 527a743..cb62460 100644 (file)
@@ -39,6 +39,7 @@
 #include <tr_name_internal.h>
 #include <tr_util.h>
 #include <stdlib.h>
+#include <talloc.h>
 
 void tr_bin_to_hex(const unsigned char * bin, size_t bin_len,
                   char * hex_out, size_t hex_len)
@@ -306,3 +307,22 @@ int tr_parse_hostname_and_port(const char *s, TR_NAME **hn_dest, int *p_dest)
   return 0;
 }
 
+TR_NAME *tr_hostname_and_port_to_name(TR_NAME *hn, int port)
+{
+  TR_NAME *retval = NULL;
+  char *s = NULL;
+  char *hn_s = tr_name_strdup(hn);
+
+  if (!hn_s)
+    return NULL;
+
+  s = talloc_asprintf(NULL, "%s:%d", hn_s, port);
+  free(hn_s);
+
+  if (s) {
+    retval = tr_new_name(s);
+    talloc_free(s);
+  }
+
+  return retval;
+}
index 2c4cd20..fedc819 100644 (file)
@@ -57,7 +57,6 @@ void tr_aaa_server_set_hostname(TR_AAA_SERVER *aaa, TR_NAME *hostname);
 int tr_aaa_server_get_port(TR_AAA_SERVER *aaa);
 void tr_aaa_server_set_port(TR_AAA_SERVER *aaa, int port);
 TR_AAA_SERVER *tr_aaa_server_from_string(TALLOC_CTX *mem_ctx, const char *s);
-TR_AAA_SERVER *tr_aaa_server_from_name(TALLOC_CTX *mem_ctx, TR_NAME *n);
 
 TR_AAA_SERVER_ITER *tr_aaa_server_iter_new(TALLOC_CTX *mem_ctx);
 void tr_aaa_server_iter_free(TR_AAA_SERVER_ITER *iter);
index d1e2d03..d42f875 100644 (file)
@@ -50,5 +50,6 @@ struct timespec *tr_clock_convert(clockid_t from, const struct timespec *when,
 TR_NAME *tr_parse_hostname(const char *s);
 int tr_parse_port(const char *s);
 int tr_parse_hostname_and_port(const char *s, TR_NAME **hn_dest, int *p_dest);
+TR_NAME *tr_hostname_and_port_to_name(TR_NAME *hn, int port);
 
 #endif /* TR_UTIL_H */
index 8401bfa..b48706c 100644 (file)
@@ -58,8 +58,9 @@
 /* TRP update record types */
 typedef struct trp_inforec_route {
   TR_NAME *trust_router;
+  int trust_router_port;
   TR_NAME *next_hop;
-  unsigned int next_hop_port;
+  int next_hop_port;
   unsigned int metric;
   unsigned int interval;
 } TRP_INFOREC_ROUTE;
@@ -275,11 +276,13 @@ TR_NAME *trp_inforec_get_realm(TRP_INFOREC *rec);
 TR_NAME *trp_inforec_dup_realm(TRP_INFOREC *rec);
 TRP_RC trp_inforec_set_realm(TRP_INFOREC *rec, TR_NAME *realm);
 TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec);
+int trp_inforec_get_trust_router_port(TRP_INFOREC *rec);
 TR_NAME *trp_inforec_dup_trust_router(TRP_INFOREC *rec);
-TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router);
+TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router, int port);
 TR_NAME *trp_inforec_get_next_hop(TRP_INFOREC *rec);
+int trp_inforec_get_next_hop_port(TRP_INFOREC *rec);
 TR_NAME *trp_inforec_dup_next_hop(TRP_INFOREC *rec);
-TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop);
+TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop, int port);
 unsigned int trp_inforec_get_metric(TRP_INFOREC *rec);
 TRP_RC trp_inforec_set_metric(TRP_INFOREC *rec, unsigned int metric);
 unsigned int trp_inforec_get_interval(TRP_INFOREC *rec);
index aff0ba0..fb7c060 100644 (file)
@@ -42,9 +42,9 @@ typedef struct trp_route {
   TR_NAME *peer;
   unsigned int metric;
   TR_NAME *trust_router; /* hostname */
-  unsigned int trp_port;
-  unsigned int tid_port;
+  int trust_router_port;
   TR_NAME *next_hop;
+  int next_hop_port;
   int selected;
   unsigned int interval; /* interval from route update */
   struct timespec *expiry;
@@ -64,6 +64,8 @@ TR_NAME *trp_route_dup_realm(TRP_ROUTE *entry);
 void trp_route_set_trust_router(TRP_ROUTE *entry, TR_NAME *tr);
 TR_NAME *trp_route_get_trust_router(TRP_ROUTE *entry);
 TR_NAME *trp_route_dup_trust_router(TRP_ROUTE *entry);
+void trp_route_set_trust_router_port(TRP_ROUTE *entry, int port);
+int trp_route_get_trust_router_port(TRP_ROUTE *entry);
 void trp_route_set_peer(TRP_ROUTE *entry, TR_NAME *peer);
 TR_NAME *trp_route_get_peer(TRP_ROUTE *entry);
 TR_NAME *trp_route_dup_peer(TRP_ROUTE *entry);
@@ -72,6 +74,8 @@ unsigned int trp_route_get_metric(TRP_ROUTE *entry);
 void trp_route_set_next_hop(TRP_ROUTE *entry, TR_NAME *next_hop);
 TR_NAME *trp_route_get_next_hop(TRP_ROUTE *entry);
 TR_NAME *trp_route_dup_next_hop(TRP_ROUTE *entry);
+void trp_route_set_next_hop_port(TRP_ROUTE *entry, int port);
+int trp_route_get_next_hop_port(TRP_ROUTE *entry);
 void trp_route_set_selected(TRP_ROUTE *entry, int sel);
 int trp_route_is_selected(TRP_ROUTE *entry);
 void trp_route_set_interval(TRP_ROUTE *entry, int interval);
index 1c8e193..d0020a0 100644 (file)
@@ -60,6 +60,7 @@ typedef enum trp_rc {
   TRP_UNSUPPORTED, /* unsupported feature */
   TRP_BADARG, /* bad argument */
   TRP_CLOCKERR, /* error reading time */
+  TRP_MISSING, /* value not present */
 } TRP_RC;
 
 typedef enum trp_inforec_type {
index d9acd78..0020a05 100644 (file)
@@ -526,12 +526,19 @@ static int tr_tids_req_handler(TIDS_INSTANCE *tids,
                                              &idp_shared);
     } else {
       tr_debug("tr_tids_req_handler: route not local.");
-      aaa_servers = tr_aaa_server_from_name(tmp_ctx, trp_route_get_next_hop(route)); /* cleaned up via talloc */
+      aaa_servers = tr_aaa_server_new(tmp_ctx); /* cleaned up via talloc */
       if (aaa_servers == NULL) {
         tr_err("tr_tids_req_handler: error allocating next hop");
         retval=-1;
         goto cleanup;
       }
+      tr_aaa_server_set_hostname(aaa_servers, trp_route_dup_next_hop(route));
+      if (tr_aaa_server_get_hostname(aaa_servers) == NULL) {
+        tr_err("tr_tids_req_handler: error allocating next hop");
+        retval=-1;
+        goto cleanup;
+      }
+      tr_aaa_server_set_port(aaa_servers, trp_route_get_next_hop_port(route));
       idp_shared = 0;
     }
 
index 7788a01..eeb354c 100644 (file)
@@ -703,11 +703,25 @@ static void *tr_trpc_thread(void *arg)
   return NULL;
 }
 
-/* convert an IDP realm into routing table entries. Outputs number in *n_routes */
+/**
+ * convert an IDP realm into routing table entries.
+ *
+ * @param mem_ctx talloc context for the result
+ * @param realm IDP realm whose routes should be generated
+ * @param trust_router hostname for TRP connections to us
+ * @param trust_router_port TRP port of our trust router
+ * @param next_hop hostname for TID connections to us
+ * @param next_hop_port TID port of our trust router
+ * @param n_routes (output) the number of routes in the returned array
+ * @return Pointer to an array of pointers to routes
+ */
 static TRP_ROUTE **tr_make_local_routes(TALLOC_CTX *mem_ctx,
-                                         TR_IDP_REALM *realm,
-                                         char *trust_router,
-                                         size_t *n_routes)
+                                        TR_IDP_REALM *realm,
+                                        const char *trust_router,
+                                        int trust_router_port,
+                                        const char *next_hop,
+                                        int next_hop_port,
+                                        size_t *n_routes)
 {
   TALLOC_CTX *tmp_ctx=talloc_new(NULL);
   TR_APC *comm=NULL;
@@ -736,7 +750,9 @@ static TRP_ROUTE **tr_make_local_routes(TALLOC_CTX *mem_ctx,
     trp_route_set_peer(new_entry, tr_new_name("")); /* no peer, it's us */
     trp_route_set_metric(new_entry, 0);
     trp_route_set_trust_router(new_entry, tr_new_name(trust_router));
-    trp_route_set_next_hop(new_entry, tr_new_name(""));
+    trp_route_set_trust_router_port(new_entry, trust_router_port);
+    trp_route_set_next_hop(new_entry, tr_new_name(next_hop));
+    trp_route_set_next_hop_port(new_entry, next_hop_port);
     trp_route_set_local(new_entry, 1);
     entries[ii]=new_entry;
   }
@@ -816,14 +832,15 @@ TRP_RC tr_add_local_routes(TRPS_INSTANCE *trps, TR_CFG *cfg)
   TRP_ROUTE **local_routes=NULL;
   size_t n_routes=0;
   size_t ii=0;
-  char *trust_router_name=talloc_asprintf(tmp_ctx, "%s:%d", cfg->internal->hostname, cfg->internal->trps_port);
-
-  /* determine our trust router name */
-  if (trust_router_name==NULL)
-    return TRP_NOMEM;
 
   for (cur=cfg->ctable->idp_realms; cur!=NULL; cur=cur->next) {
-    local_routes=tr_make_local_routes(tmp_ctx, cur, trust_router_name, &n_routes);
+    local_routes=tr_make_local_routes(tmp_ctx,
+                                      cur,
+                                      cfg->internal->hostname,
+                                      cfg->internal->trps_port,
+                                      cfg->internal->hostname,
+                                      cfg->internal->tids_port,
+                                      &n_routes);
     for (ii=0; ii<n_routes; ii++)
       trps_add_route(trps, local_routes[ii]);
 
index 6178d97..19d7e22 100644 (file)
@@ -73,8 +73,8 @@ TRP_ROUTE *trp_route_new(TALLOC_CTX *mem_ctx)
     entry->comm=NULL;
     entry->realm=NULL;
     entry->trust_router=NULL;
-    entry->trp_port=TRP_PORT;
-    entry->tid_port=TID_PORT;
+    entry->trust_router_port=TRP_PORT;
+    entry->next_hop_port=TID_PORT;
     entry->peer=NULL;
     entry->next_hop=NULL;
     entry->selected=0;
@@ -262,3 +262,43 @@ int trp_route_is_triggered(TRP_ROUTE *entry)
 {
   return entry->triggered;
 }
+
+void trp_route_set_trust_router_port(TRP_ROUTE *entry, int port)
+{
+  if (entry)
+    entry->trust_router_port = port;
+}
+
+/**
+ * Get the port to use for TRP connections to the trust router
+ *
+ * @param entry
+ * @return port, or -1 if entry is null
+ */
+int trp_route_get_trust_router_port(TRP_ROUTE *entry)
+{
+  if (entry)
+    return entry->trust_router_port;
+
+  return -1;
+}
+
+void trp_route_set_next_hop_port(TRP_ROUTE *entry, int port)
+{
+  if (entry)
+    entry->next_hop_port = port;
+}
+
+/**
+ * Get the port to use for TID connections to the next hop
+ *
+ * @param entry
+ * @return port, or -1 if entry is null
+ */
+int trp_route_get_next_hop_port(TRP_ROUTE *entry)
+{
+  if (entry)
+    return entry->next_hop_port;
+
+  return -1;
+}
index 7cbb3ac..b7adf88 100644 (file)
@@ -62,13 +62,13 @@ char *trp_route_to_str(TALLOC_CTX *mem_ctx, TRP_ROUTE *entry, const char *sep)
     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",
+                         "%s%s%s%s%s%s%u%s%s:%d%s%s:%d%s%u%s%u%s%s%s%u",
                          comm, sep,
                          realm, sep,
                          peer, sep,
                          entry->metric, sep,
-                         trust_router, sep,
-                         next_hop, sep,
+                         trust_router, entry->trust_router_port, sep,
+                         next_hop, entry->next_hop_port, sep,
                          entry->selected, sep,
                          entry->local, sep,
                          expiry, sep,
@@ -108,6 +108,7 @@ json_t *trp_route_to_json(TRP_ROUTE *route)
 {
   json_t *route_json = NULL;
   json_t *retval = NULL;
+  TR_NAME *n;
 
   route_json = json_object();
   if (route_json == NULL)
@@ -118,9 +119,25 @@ json_t *trp_route_to_json(TRP_ROUTE *route)
   if (trp_route_get_peer(route)->len > 0)
     OBJECT_SET_OR_FAIL(route_json, "peer", tr_name_to_json_string(trp_route_get_peer(route)));
   OBJECT_SET_OR_FAIL(route_json, "metric", json_integer(trp_route_get_metric(route)));
-  OBJECT_SET_OR_FAIL(route_json, "trust_router", tr_name_to_json_string(trp_route_get_trust_router(route)));
-  if (trp_route_get_next_hop(route)->len > 0)
-    OBJECT_SET_OR_FAIL(route_json, "next_hop", tr_name_to_json_string(trp_route_get_next_hop(route)));
+
+  /* add trust_router as hostname:port */
+  n = tr_hostname_and_port_to_name(
+          trp_route_get_trust_router(route),
+          trp_route_get_trust_router_port(route));
+  if (n == NULL)
+    goto cleanup;
+  OBJECT_SET_OR_FAIL(route_json, "trust_router", tr_name_to_json_string(n));
+  tr_free_name(n);
+
+  /* add next_hop as hostname:port */
+  n = tr_hostname_and_port_to_name(
+      trp_route_get_next_hop(route),
+      trp_route_get_next_hop_port(route));
+  if (n == NULL)
+    goto cleanup;
+  OBJECT_SET_OR_FAIL(route_json, "next_hop", tr_name_to_json_string(n));
+  tr_free_name(n);
+
   OBJECT_SET_OR_FAIL(route_json, "selected", json_boolean(trp_route_is_selected(route)));
   OBJECT_SET_OR_FAIL(route_json, "local", json_boolean(trp_route_is_local(route)));
   OBJECT_SET_OR_SKIP(route_json, "expires", expiry_to_json_string(route));
index 9c520e3..26b976e 100644 (file)
@@ -211,22 +211,34 @@ void trp_inforec_set_type(TRP_INFOREC *rec, TRP_INFOREC_TYPE type)
 TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec)
 {
   switch (rec->type) {
-  case TRP_INFOREC_TYPE_ROUTE:
-    if (rec->data->route!=NULL)
-      return rec->data->route->trust_router;
-    break;
-  default:
-    break;
+    case TRP_INFOREC_TYPE_ROUTE:
+      if (rec->data->route!=NULL)
+        return rec->data->route->trust_router;
+      break;
+    default:
+      break;
   }
   return NULL;
 }
 
+int trp_inforec_get_trust_router_port(TRP_INFOREC *rec)
+{
+  switch (rec->type) {
+    case TRP_INFOREC_TYPE_ROUTE:
+      if (rec->data->route!=NULL)
+        return rec->data->route->trust_router_port;
+      /* fall through */
+    default:
+      return -1;
+  }
+}
+
 TR_NAME *trp_inforec_dup_trust_router(TRP_INFOREC *rec)
 {
   return tr_dup_name(trp_inforec_get_trust_router(rec));
 }
 
-TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router)
+TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router, int port)
 {
   switch (rec->type) {
   case TRP_INFOREC_TYPE_ROUTE:
@@ -241,16 +253,15 @@ TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router)
   return TRP_ERROR;
 }
 
-/* TODO: need to return hostname/port --jlr */
 TR_NAME *trp_inforec_get_next_hop(TRP_INFOREC *rec)
 {
   switch (rec->type) {
-  case TRP_INFOREC_TYPE_ROUTE:
-    if (rec->data->route!=NULL)
-      return rec->data->route->next_hop;
-    break;
-  default:
-    break;
+    case TRP_INFOREC_TYPE_ROUTE:
+      if (rec->data->route!=NULL)
+        return rec->data->route->next_hop;
+      break;
+    default:
+      break;
   }
   return NULL;
 }
@@ -272,14 +283,15 @@ TR_NAME *trp_inforec_dup_next_hop(TRP_INFOREC *rec)
  * @param next_hop
  * @return TRP_SUCCESS if the value was set, TRP_UNSUPPORTED if the inforec does not support next hop, or an error code on failure
  */
-TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop)
+TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop, int port)
 {
   /* Any inforec types that support next_hop should set it here. */
   switch (rec->type) {
   case TRP_INFOREC_TYPE_ROUTE:
     if (rec->data->route==NULL)
       return TRP_ERROR;
-    rec->data->route->next_hop=next_hop;
+    rec->data->route->next_hop = next_hop;
+    rec->data->route->next_hop_port = port;
     break;
 
   default:
@@ -289,6 +301,18 @@ TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop)
   return TRP_SUCCESS;
 }
 
+int trp_inforec_get_next_hop_port(TRP_INFOREC *rec)
+{
+  switch (rec->type) {
+    case TRP_INFOREC_TYPE_ROUTE:
+      if (rec->data->route!=NULL)
+        return rec->data->route->next_hop_port;
+      /* fall through */
+    default:
+      return -1;
+  }
+}
+
 unsigned int trp_inforec_get_metric(TRP_INFOREC *rec)
 {
   switch (rec->type) {
@@ -784,7 +808,7 @@ void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port)
   TR_NAME *cpy=NULL;
 
   for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
-    switch (trp_inforec_set_next_hop(rec, cpy=tr_new_name(hostname))) {
+    switch (trp_inforec_set_next_hop(rec, cpy=tr_new_name(hostname), port)) {
       case TRP_SUCCESS:
         /* Success, the TR_NAME in cpy is now stored with the inforec */
         break;
index 2c3337a..694c022 100644 (file)
@@ -361,11 +361,9 @@ static TRP_RC trps_read_message(TRPS_INSTANCE *trps, TRP_CONNECTION *conn, TR_MS
   /* verify we received a message we support, otherwise drop it now */
   switch (tr_msg_get_msg_type(*msg)) {
   case TRP_UPDATE:
-    trp_upd_set_peer(tr_msg_get_trp_upd(*msg), tr_dup_name(conn_peer));
-    trp_upd_set_next_hop(tr_msg_get_trp_upd(*msg), trp_peer_get_server(peer), 0); /* TODO: 0 should be the configured TID port */
     /* update provenance if necessary */
     trp_upd_add_to_provenance(tr_msg_get_trp_upd(*msg), trp_peer_get_label(peer));
-    break;
+    /* fall through to next case */
 
   case TRP_REQUEST:
     trp_req_set_peer(tr_msg_get_trp_req(*msg), tr_dup_name(conn_peer));
@@ -502,12 +500,27 @@ static TRP_RC trps_validate_inforec(TRPS_INSTANCE *trps, TRP_INFOREC *rec)
   switch(trp_inforec_get_type(rec)) {
   case TRP_INFOREC_TYPE_ROUTE:
     if ((trp_inforec_get_trust_router(rec)==NULL)
-       || (trp_inforec_get_next_hop(rec)==NULL)) {
+        || (trp_inforec_get_next_hop(rec)==NULL)) {
       tr_debug("trps_validate_inforec: missing record info.");
       return TRP_ERROR;
     }
 
-    /* check for valid metric */
+    /* check for valid ports */
+    if ((trp_inforec_get_trust_router_port(rec) <= 0)
+        || (trp_inforec_get_trust_router_port(rec) > 65535)) {
+      tr_debug("trps_validate_inforec: invalid trust router port (%d)",
+               trp_inforec_get_trust_router_port(rec));
+      return TRP_ERROR;
+    }
+
+      if ((trp_inforec_get_next_hop_port(rec) <= 0)
+          || (trp_inforec_get_next_hop_port(rec) > 65535)) {
+        tr_debug("trps_validate_inforec: invalid next hop port (%d)",
+                 trp_inforec_get_next_hop_port(rec));
+        return TRP_ERROR;
+      }
+
+      /* check for valid metric */
     if (trp_metric_is_invalid(trp_inforec_get_metric(rec))) {
       tr_debug("trps_validate_inforec: invalid metric (%u).", trp_inforec_get_metric(rec));
       return TRP_ERROR;
@@ -593,6 +606,17 @@ static struct timespec *trps_compute_expiry(TRPS_INSTANCE *trps, unsigned int in
   return ts;
 }
 
+
+/* compare hostname/port of the trust router, return 0 if they match */
+static int trust_router_changed(TRP_ROUTE *route, TRP_INFOREC *rec)
+{
+  if (trp_route_get_trust_router_port(route) != trp_inforec_get_trust_router_port(rec))
+    return 1;
+
+  return tr_name_cmp(trp_route_get_trust_router(route),
+                     trp_inforec_get_trust_router(rec));
+}
+
 static TRP_RC trps_accept_update(TRPS_INSTANCE *trps, TRP_UPD *upd, TRP_INFOREC *rec)
 {
   TRP_ROUTE *entry=NULL;
@@ -635,13 +659,13 @@ static TRP_RC trps_accept_update(TRPS_INSTANCE *trps, TRP_UPD *upd, TRP_INFOREC
   trp_route_set_metric(entry, trp_inforec_get_metric(rec));
   trp_route_set_interval(entry, trp_inforec_get_interval(rec));
 
-  /* check whether the trust router has changed */
-  if (0!=tr_name_cmp(trp_route_get_trust_router(entry),
-                     trp_inforec_get_trust_router(rec))) {
+  /* check whether the trust router has changed (either name or port) */
+  if (trust_router_changed(entry, rec)) {
     /* The name changed. Set this route as triggered. */
     tr_debug("trps_accept_update: trust router for route changed.");
     trp_route_set_triggered(entry, 1);
     trp_route_set_trust_router(entry, trp_inforec_dup_trust_router(rec)); /* frees old name */
+    trp_route_set_trust_router_port(entry, trp_inforec_get_trust_router_port(rec));
   }
   if (!trps_route_retracted(trps, entry)) {
     tr_debug("trps_accept_update: route not retracted, setting expiry timer.");
@@ -689,8 +713,7 @@ static TRP_RC trps_handle_inforec_route(TRPS_INSTANCE *trps, TRP_UPD *upd, TRP_I
         trps_accept_update(trps, upd, rec);
       } else {
         /* Update is infeasible. Ignore it unless the trust router has changed. */
-        if (0!=tr_name_cmp(trp_route_get_trust_router(route),
-                           trp_inforec_get_trust_router(rec))) {
+        if (trust_router_changed(route, rec)) {
           /* the trust router associated with the route has changed, treat update as a retraction */
           trps_retract_route(trps, route);
         }
@@ -1351,11 +1374,16 @@ static TRP_INFOREC *trps_route_to_inforec(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *tr
 
     /* Note that we leave the next hop empty since the recipient fills that in.
      * This is where we add the link cost (currently always 1) to the next peer. */
-    if ((trp_inforec_set_trust_router(rec, trp_route_dup_trust_router(route)) != TRP_SUCCESS)
-       ||(trp_inforec_set_metric(rec,
-                                 trps_metric_add(trp_route_get_metric(route),
-                                                 linkcost)) != TRP_SUCCESS)
-       ||(trp_inforec_set_interval(rec, trps_get_update_interval(trps)) != TRP_SUCCESS)) {
+    if ((TRP_SUCCESS != trp_inforec_set_trust_router(rec,
+                                                     trp_route_dup_trust_router(route),
+                                                     trp_route_get_trust_router_port(route)))
+        ||(TRP_SUCCESS != trp_inforec_set_next_hop(rec,
+                                                   trp_route_dup_next_hop(route),
+                                                   trp_route_get_next_hop_port(route)))
+        ||(TRP_SUCCESS != trp_inforec_set_metric(rec,
+                                                 trps_metric_add(trp_route_get_metric(route),
+                                                                 linkcost)))
+        ||(TRP_SUCCESS != trp_inforec_set_interval(rec, trps_get_update_interval(trps)))) {
       tr_err("trps_route_to_inforec: error creating route update.");
       talloc_free(rec);
       rec=NULL;