#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.
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 */
{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},
#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
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;
}
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;
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;
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)))
#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)
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;
+}
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);
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 */
/* 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;
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);
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;
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);
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);
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 {
&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;
}
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;
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;
}
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]);
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;
{
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;
+}
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,
{
json_t *route_json = NULL;
json_t *retval = NULL;
+ TR_NAME *n;
route_json = json_object();
if (route_json == NULL)
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));
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:
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;
}
* @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:
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) {
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;
/* 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));
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;
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;
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.");
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);
}
/* 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;