From: Jennifer Richards Date: Thu, 24 May 2018 22:30:11 +0000 (-0400) Subject: Support non-default TRP and TID ports X-Git-Tag: 3.4.0~1^2~18^2~11 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=trust_router.git;a=commitdiff_plain;h=7d902566f139ab6603c2b4a534c12f465526790d Support non-default TRP and TID ports * 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 --- diff --git a/common/tr_filter.c b/common/tr_filter.c index 2b94526..0d7c5c4 100644 --- a/common/tr_filter.c +++ b/common/tr_filter.c @@ -42,6 +42,7 @@ #include #include #include +#include /* 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}, diff --git a/common/tr_msg.c b/common/tr_msg.c index 50e8bc9..350fc5b 100644 --- a/common/tr_msg.c +++ b/common/tr_msg.c @@ -46,28 +46,29 @@ #include #include #include +#include #include #include #include #include /* 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))) diff --git a/common/tr_util.c b/common/tr_util.c index 527a743..cb62460 100644 --- a/common/tr_util.c +++ b/common/tr_util.c @@ -39,6 +39,7 @@ #include #include #include +#include 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; +} diff --git a/include/tr_aaa_server.h b/include/tr_aaa_server.h index 2c4cd20..fedc819 100644 --- a/include/tr_aaa_server.h +++ b/include/tr_aaa_server.h @@ -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); diff --git a/include/tr_util.h b/include/tr_util.h index d1e2d03..d42f875 100644 --- a/include/tr_util.h +++ b/include/tr_util.h @@ -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 */ diff --git a/include/trp_internal.h b/include/trp_internal.h index 8401bfa..b48706c 100644 --- a/include/trp_internal.h +++ b/include/trp_internal.h @@ -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); diff --git a/include/trp_route.h b/include/trp_route.h index aff0ba0..fb7c060 100644 --- a/include/trp_route.h +++ b/include/trp_route.h @@ -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); diff --git a/include/trust_router/trp.h b/include/trust_router/trp.h index 1c8e193..d0020a0 100644 --- a/include/trust_router/trp.h +++ b/include/trust_router/trp.h @@ -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 { diff --git a/tr/tr_tid.c b/tr/tr_tid.c index d9acd78..0020a05 100644 --- a/tr/tr_tid.c +++ b/tr/tr_tid.c @@ -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; } diff --git a/tr/tr_trp.c b/tr/tr_trp.c index 7788a01..eeb354c 100644 --- a/tr/tr_trp.c +++ b/tr/tr_trp.c @@ -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; iicomm=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; +} diff --git a/trp/trp_route_encoders.c b/trp/trp_route_encoders.c index 7cbb3ac..b7adf88 100644 --- a/trp/trp_route_encoders.c +++ b/trp/trp_route_encoders.c @@ -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)); diff --git a/trp/trp_upd.c b/trp/trp_upd.c index 9c520e3..26b976e 100644 --- a/trp/trp_upd.c +++ b/trp/trp_upd.c @@ -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; diff --git a/trp/trps.c b/trp/trps.c index 2c3337a..694c022 100644 --- a/trp/trps.c +++ b/trp/trps.c @@ -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;