From: Jennifer Richards Date: Wed, 30 May 2018 05:07:02 +0000 (-0400) Subject: Merge pull request #86 from painless-security/jennifer/aaa_server_port X-Git-Tag: 3.4.0~1^2~18 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=trust_router.git;a=commitdiff_plain;h=b5117dd88f660ee157de3cf96f8fb6d952ac342a;hp=a6b70c983165f3c50265b55a4b09264fdd0dfff0 Merge pull request #86 from painless-security/jennifer/aaa_server_port Allow configurable TID and TRP ports --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 2aa60bc..0761bfc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 trp/trp_rtable_encoders.c trp/trp_route_encoders.c trp/trp_peer.c include/trp_peer.h trp/trp_peer_encoders.c trp/trp_ptable_encoders.c common/tr_idp_encoders.c common/tr_comm_encoders.c common/tr_rp_client.c include/tr_rp_client.h common/tr_rp_client_encoders.c common/tr_filter_encoders.c common/tr_config_encoders.c common/tr_config_filters.c common/tr_config_realms.c common/tr_config_rp_clients.c common/tr_config_orgs.c common/tr_config_comms.c common/tr_list.c include/tr_list.h include/tr_constraint_internal.h include/tr_json_util.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 trp/trp_peer.c include/trp_peer.h trp/trp_peer_encoders.c trp/trp_ptable_encoders.c common/tr_idp_encoders.c common/tr_comm_encoders.c common/tr_rp_client.c include/tr_rp_client.h common/tr_rp_client_encoders.c common/tr_filter_encoders.c common/tr_config_encoders.c common/tr_config_filters.c common/tr_config_realms.c common/tr_config_rp_clients.c common/tr_config_orgs.c common/tr_config_comms.c common/tr_list.c include/tr_list.h include/tr_constraint_internal.h include/tr_json_util.h common/tr_aaa_server.c include/tr_aaa_server.h common/tr_inet_util.c include/tr_inet_util.h) # Does not actually build! add_executable(trust_router ${SOURCE_FILES}) diff --git a/Makefile.am b/Makefile.am index 291f889..c08e9df 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,6 +15,7 @@ common_srcs = common/tr_name.c \ common/tr_dh.c \ common/tr_debug.c \ common/tr_util.c \ + common/tr_inet_util.c \ common/tr_apc.c \ common/tr_comm.c \ common/tr_comm_encoders.c \ @@ -22,6 +23,7 @@ common_srcs = common/tr_name.c \ common/tr_rp_client.c \ common/tr_rp_client_encoders.c \ common/tr_idp.c \ + common/tr_aaa_server.c \ common/tr_idp_encoders.c \ common/tr_filter.c \ common/tr_filter_encoders.c \ @@ -161,6 +163,7 @@ common/tr_name.c \ common/tr_gss_names.c \ common/tr_debug.c \ common/tr_util.c \ +common/tr_inet_util.c \ common/tr_list.c \ trp/trp_route.c \ trp/trp_route_encoders.c \ @@ -278,6 +281,7 @@ noinst_HEADERS = include/gsscon.h \ include/tr.h \ include/tr_msg.h \ include/tr_idp.h \ + include/tr_aaa_server.h \ include/tr_rp.h include/tr_rp_client.h \ include/tr_comm.h \ include/tr_apc.h \ @@ -293,7 +297,7 @@ noinst_HEADERS = include/gsscon.h \ include/trp_route.h include/trp_rtable.h \ include/tr_list.h \ include/tr_name_internal.h \ - include/tr_util.h include/tr_json_util.h \ + include/tr_util.h include/tr_json_util.h include/tr_inet_util.h\ include/tr_rand_id.h include/tr_socket.h \ include/tr_constraint_internal.h diff --git a/common/tests/commtest.c b/common/tests/commtest.c index 72a2844..d2becc0 100644 --- a/common/tests/commtest.c +++ b/common/tests/commtest.c @@ -239,11 +239,9 @@ struct aaa_entry { static TR_AAA_SERVER *aaa_entry_to_aaa_server(TALLOC_CTX *mem_ctx, struct aaa_entry *ae) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); - TR_AAA_SERVER *aaa=tr_aaa_server_new(tmp_ctx, tr_new_name(ae->hostname)); + TR_AAA_SERVER *aaa=tr_aaa_server_from_string(tmp_ctx, ae->hostname); - if ((aaa==NULL) || (aaa->hostname==NULL)) - aaa=NULL; - else + if (aaa) talloc_steal(mem_ctx, aaa); talloc_free(tmp_ctx); diff --git a/common/tr_aaa_server.c b/common/tr_aaa_server.c new file mode 100644 index 0000000..dedf054 --- /dev/null +++ b/common/tr_aaa_server.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2012-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 + +#include +#include +#include +#include +#include + +static int tr_aaa_server_destructor(void *obj) +{ + TR_AAA_SERVER *aaa=talloc_get_type_abort(obj, TR_AAA_SERVER); + if (aaa->hostname!=NULL) + tr_free_name(aaa->hostname); + return 0; +} + +TR_AAA_SERVER *tr_aaa_server_new(TALLOC_CTX *mem_ctx) +{ + TR_AAA_SERVER *aaa=talloc(mem_ctx, TR_AAA_SERVER); + if (aaa!=NULL) { + aaa->next=NULL; + aaa->hostname = NULL; + tr_aaa_server_set_port(aaa, 0); /* go through setter to guarantee consistent default */ + talloc_set_destructor((void *)aaa, tr_aaa_server_destructor); + } + return aaa; +} + +void tr_aaa_server_free(TR_AAA_SERVER *aaa) +{ + talloc_free(aaa); +} + +TR_NAME *tr_aaa_server_get_hostname(TR_AAA_SERVER *aaa) +{ + return aaa->hostname; +} + +/** + * Set the hostname for a AAA server + * + * Takes ownership of the TR_NAME. Does nothing if aaa is null. + * + * @param aaa + * @param hostname + */ +void tr_aaa_server_set_hostname(TR_AAA_SERVER *aaa, TR_NAME *hostname) +{ + if (aaa == NULL) + return; + + if (aaa->hostname != NULL) { + tr_free_name(aaa->hostname); + } + + aaa->hostname = hostname; +} + +int tr_aaa_server_get_port(TR_AAA_SERVER *aaa) +{ + return aaa->port; +} + +/** + * Set the port for a AAA server + * + * If port is 0, uses the standard TID port (12309). Other invalid values are stored + * as-is. + * + * Does nothing if aaa is null. + * + * @param aaa + * @param port + */ +void tr_aaa_server_set_port(TR_AAA_SERVER *aaa, int port) +{ + if (aaa == NULL) + return; + + if (port == 0) + port = TID_PORT; + + aaa->port = port; +} + +/** + * Allocate a AAA server record and fill it in by parsing a hostname:port string + * + * If hostname or port are invalid, hostname will be empty and port will be -1. + * + * @return newly allocated TR_AAA_SERVER in the mem_ctx context, or NULL on error + */ +TR_AAA_SERVER *tr_aaa_server_from_string(TALLOC_CTX *mem_ctx, const char *s) +{ + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + TR_AAA_SERVER *aaa = tr_aaa_server_new(tmp_ctx); + char *hostname; + int port; + + if (aaa == NULL) + goto failed; + + hostname = tr_parse_host(tmp_ctx, s, &port); + if (NULL == hostname) { + hostname = ""; + port = -1; + } + + tr_aaa_server_set_hostname(aaa, tr_new_name(hostname)); + if (tr_aaa_server_get_hostname(aaa) == NULL) + goto failed; + + tr_aaa_server_set_port(aaa, port); /* port = 0 uses default TID port */ + talloc_steal(mem_ctx, aaa); /*put this in the caller's context */ + goto succeeded; + +failed: + aaa = NULL; /* talloc will free the memory if it was allocated */ + +succeeded: + talloc_free(tmp_ctx); + return aaa; +} + +TR_AAA_SERVER_ITER *tr_aaa_server_iter_new(TALLOC_CTX *mem_ctx) +{ + return talloc(mem_ctx, TR_AAA_SERVER_ITER); +} + +void tr_aaa_server_iter_free(TR_AAA_SERVER_ITER *iter) +{ + talloc_free(iter); +} + +TR_AAA_SERVER *tr_aaa_server_iter_first(TR_AAA_SERVER_ITER *iter, TR_AAA_SERVER *aaa) +{ + iter->this=aaa; + return iter->this; +} + +TR_AAA_SERVER *tr_aaa_server_iter_next(TR_AAA_SERVER_ITER *iter) +{ + if (iter->this!=NULL) { + iter->this=iter->this->next; + } + return iter->this; +} diff --git a/common/tr_config_internal.c b/common/tr_config_internal.c index d06dc51..b6a16ad 100644 --- a/common/tr_config_internal.c +++ b/common/tr_config_internal.c @@ -71,6 +71,38 @@ static TR_CFG_RC tr_cfg_parse_boolean(json_t *src, const char *key, int *dest) } /** + * Parse a signed integer + * + * If the key does not exist in the src object, returns success but does fill in *dest. + * + * @param src JSON object to pull a value from + * @param key key to pull + * @param dest (output) pointer to an allocated integer + * @return TR_CFG_SUCCESS or an error code + */ +static TR_CFG_RC tr_cfg_parse_integer(json_t *src, const char *key, int *dest) +{ + json_t *jtmp; + + /* Validate parameters */ + if ((src == NULL) || (key == NULL) || (dest == NULL)) + return TR_CFG_BAD_PARAMS; + + /* See if we have a value for this key; do nothing if not */ + jtmp = json_object_get(src, key); + if (jtmp) { + if (json_is_number(jtmp)) { + *dest = (int) json_integer_value(jtmp); + } else { + tr_debug("tr_cfg_parse_unsigned: Parsing error, %s is not a number.", key); + return TR_CFG_NOPARSE; + } + } + + return TR_CFG_SUCCESS; +} + +/** * Parse an unsigned integer * * If the key does not exist in the src object, returns success but does fill in *dest. @@ -150,7 +182,7 @@ static void set_defaults(TR_CFG_INTERNAL *cfg) cfg->max_tree_depth = TR_DEFAULT_MAX_TREE_DEPTH; cfg->tids_port = TR_DEFAULT_TIDS_PORT; cfg->trps_port = TR_DEFAULT_TRPS_PORT; - cfg->monitoring_port = TR_DEFAULT_MONITORING_PORT; + cfg->mons_port = TR_DEFAULT_MONITORING_PORT; cfg->cfg_poll_interval = TR_CFGWATCH_DEFAULT_POLL; cfg->cfg_settling_time = TR_CFGWATCH_DEFAULT_SETTLE; cfg->trp_connect_interval = TR_DEFAULT_TRP_CONNECT_INTERVAL; @@ -177,7 +209,7 @@ static TR_CFG_RC tr_cfg_parse_monitoring(TR_CFG *trc, json_t *jmon) NOPARSE_UNLESS(tr_cfg_parse_boolean(jmon, "enabled", &enabled)); if (enabled) { - NOPARSE_UNLESS(tr_cfg_parse_unsigned(jmon, "port", &(trc->internal->monitoring_port))); + NOPARSE_UNLESS(tr_cfg_parse_integer(jmon, "port", &(trc->internal->mons_port))); NOPARSE_UNLESS(tr_cfg_parse_gss_names(trc->internal, json_object_get(jmon, "authorized_credentials"), &(trc->internal->monitoring_credentials))); @@ -213,8 +245,8 @@ TR_CFG_RC tr_cfg_parse_internal(TR_CFG *trc, json_t *jint) talloc_steal(trc->internal, trc->internal->hostname); NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "max_tree_depth", &(trc->internal->max_tree_depth))); - NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "tids_port", &(trc->internal->tids_port))); - NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "trps_port", &(trc->internal->trps_port))); + NOPARSE_UNLESS(tr_cfg_parse_integer(jint, "tids_port", &(trc->internal->tids_port))); + NOPARSE_UNLESS(tr_cfg_parse_integer(jint, "trps_port", &(trc->internal->trps_port))); NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "cfg_poll_interval", &(trc->internal->cfg_poll_interval))); NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "cfg_settling_time", &(trc->internal->cfg_settling_time))); NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "trp_connect_interval", &(trc->internal->trp_connect_interval))); diff --git a/common/tr_config_orgs.c b/common/tr_config_orgs.c index f6925ca..e9b2c3c 100644 --- a/common/tr_config_orgs.c +++ b/common/tr_config_orgs.c @@ -48,6 +48,8 @@ #include #include #include +#include +#include #if JANSSON_VERSION_HEX < 0x020500 #include "jansson_iterators.h" @@ -164,16 +166,16 @@ static TR_CFG_RC tr_cfg_parse_one_peer_org(TR_CFG *trc, json_t *jporg) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); json_t *jhost=NULL; - json_t *jport=NULL; json_t *jgss=NULL; json_t *jfilt=NULL; TRP_PEER *new_peer=NULL; TR_GSS_NAMES *names=NULL; TR_FILTER_SET *filt_set=NULL; TR_CFG_RC rc=TR_CFG_ERROR; + char *hostname=NULL; + int port; jhost=json_object_get(jporg, "hostname"); - jport=json_object_get(jporg, "port"); jgss=json_object_get(jporg, "gss_names"); jfilt=json_object_get(jporg, "filters"); @@ -183,13 +185,6 @@ static TR_CFG_RC tr_cfg_parse_one_peer_org(TR_CFG *trc, json_t *jporg) goto cleanup; } - if ((jport!=NULL) && (!json_is_number(jport))) { - /* note that not specifying the port is allowed, but if set it must be a number */ - tr_err("tr_cfg_parse_one_peer_org: port is not a number."); - rc=TR_CFG_NOPARSE; - goto cleanup; - } - if ((jgss==NULL) || (!json_is_array(jgss))) { tr_err("tr_cfg_parse_one_peer_org: gss_names not specified or not an array."); rc=TR_CFG_NOPARSE; @@ -209,11 +204,30 @@ static TR_CFG_RC tr_cfg_parse_one_peer_org(TR_CFG *trc, json_t *jporg) goto cleanup; } - trp_peer_set_server(new_peer, json_string_value(jhost)); /* string is strdup'ed in _set_server() */ - if (jport==NULL) - trp_peer_set_port(new_peer, TRP_PORT); - else - trp_peer_set_port(new_peer, json_integer_value(jport)); + /* parse / validate the hostname and port */ + hostname = tr_parse_host(tmp_ctx, json_string_value(jhost), &port); + if (NULL == hostname) { + tr_err("tr_cfg_parse_one_peer_org: error parsing hostname (%s)", json_string_value(jhost)); + rc=TR_CFG_NOPARSE; + goto cleanup; + } + + if (port < 0) { + tr_err("tr_cfg_parse_one_peer_org: invalid port (%s)", json_string_value(jhost)); + rc=TR_CFG_NOPARSE; + goto cleanup; + } + + if (port == 0) + port = TRP_PORT; + trp_peer_set_port(new_peer, port); + + trp_peer_set_server(new_peer, hostname); /* string is strdup'ed in _set_server() */ + if (trp_peer_get_server(new_peer) == NULL) { + tr_err("tr_cfg_parse_one_peer: could not set server hostname for new peer"); + rc = TR_CFG_NOMEM; + goto cleanup; + } rc = tr_cfg_parse_gss_names(tmp_ctx, jgss, &names); if (rc!=TR_CFG_SUCCESS) { diff --git a/common/tr_config_realms.c b/common/tr_config_realms.c index 2f6fa09..60bae00 100644 --- a/common/tr_config_realms.c +++ b/common/tr_config_realms.c @@ -55,30 +55,45 @@ TR_AAA_SERVER *tr_cfg_parse_one_aaa_server(TALLOC_CTX *mem_ctx, json_t *jaddr, TR_CFG_RC *rc) { + TALLOC_CTX *tmp_ctx = talloc_new(NULL); TR_AAA_SERVER *aaa = NULL; - TR_NAME *name=NULL; if ((!jaddr) || (!json_is_string(jaddr))) { tr_debug("tr_cfg_parse_one_aaa_server: Bad parameters."); *rc = TR_CFG_BAD_PARAMS; - return NULL; + goto cleanup; } - name=tr_new_name(json_string_value(jaddr)); - if (name==NULL) { - tr_debug("tr_cfg_parse_one_aaa_server: Out of memory allocating hostname."); + aaa = tr_aaa_server_from_string(mem_ctx, json_string_value(jaddr)); + if (aaa == NULL) { + tr_debug("tr_cfg_parse_one_aaa_server: Out of memory allocating AAA server."); *rc = TR_CFG_NOMEM; - return NULL; + goto cleanup; } - aaa=tr_aaa_server_new(mem_ctx, name); - if (aaa==NULL) { - tr_free_name(name); - tr_debug("tr_cfg_parse_one_aaa_server: Out of memory allocating AAA server."); - *rc = TR_CFG_NOMEM; - return NULL; + if (tr_aaa_server_get_hostname(aaa)->len == 0) { + tr_debug("tr_cfg_parse_one_aaa_server: Invalid hostname for AAA server (%s)", + json_string_value(jaddr)); + *rc = TR_CFG_NOPARSE; + goto cleanup; + } + + if ((tr_aaa_server_get_port(aaa) <= 0) + || (tr_aaa_server_get_port(aaa) > 65535)) { + tr_debug("tr_cfg_parse_one_aaa_server: Invalid AAA server port (%s)", + json_string_value(jaddr)); + *rc = TR_CFG_NOPARSE; + goto cleanup; } + /* success ! */ + *rc = TR_CFG_SUCCESS; + talloc_steal(mem_ctx, aaa); + +cleanup: + if (*rc != TR_CFG_SUCCESS) + aaa = NULL; + talloc_free(tmp_ctx); return aaa; } diff --git a/common/tr_filter.c b/common/tr_filter.c index 2b94526..1df9aa4 100644 --- a/common/tr_filter.c +++ b/common/tr_filter.c @@ -41,6 +41,7 @@ #include #include #include +#include #include /* Function types for handling filter fields generally. All target values @@ -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_gss_client.c b/common/tr_gss_client.c index 7b61acb..f45af3a 100644 --- a/common/tr_gss_client.c +++ b/common/tr_gss_client.c @@ -68,10 +68,15 @@ void tr_gssc_instance_free(TR_GSSC_INSTANCE *tr_gssc) * @param port TCP port to connect * @return 0 on success, -1 on failure */ -int tr_gssc_open_connection(TR_GSSC_INSTANCE *gssc, const char *server, unsigned int port) +int tr_gssc_open_connection(TR_GSSC_INSTANCE *gssc, const char *server, int port) { + if ((port <= 0) || (port > 65535)) { + tr_err("tr_gssc_open_connection: invalid port requested (%d)", port); + return -1; + } + tr_debug("tr_gssc_open_connection: opening connection to %s:%d", server, port); - if (0 != gsscon_connect(server, port, gssc->service_name, &(gssc->conn), gssc->gss_ctx)) + if (0 != gsscon_connect(server, (unsigned int) port, gssc->service_name, &(gssc->conn), gssc->gss_ctx)) return -1; return 0; /* success */ diff --git a/common/tr_idp.c b/common/tr_idp.c index 50a9330..a3d84a7 100644 --- a/common/tr_idp.c +++ b/common/tr_idp.c @@ -35,60 +35,12 @@ #include #include +#include #include #include #include #include -static int tr_aaa_server_destructor(void *obj) -{ - TR_AAA_SERVER *aaa=talloc_get_type_abort(obj, TR_AAA_SERVER); - if (aaa->hostname!=NULL) - tr_free_name(aaa->hostname); - return 0; -} - -TR_AAA_SERVER *tr_aaa_server_new(TALLOC_CTX *mem_ctx, TR_NAME *hostname) -{ - TR_AAA_SERVER *aaa=talloc(mem_ctx, TR_AAA_SERVER); - if (aaa!=NULL) { - aaa->next=NULL; - aaa->hostname=hostname; - talloc_set_destructor((void *)aaa, tr_aaa_server_destructor); - } - return aaa; -} - -void tr_aaa_server_free(TR_AAA_SERVER *aaa) -{ - talloc_free(aaa); -} - -TR_AAA_SERVER_ITER *tr_aaa_server_iter_new(TALLOC_CTX *mem_ctx) -{ - return talloc(mem_ctx, TR_AAA_SERVER_ITER); -} - -void tr_aaa_server_iter_free(TR_AAA_SERVER_ITER *iter) -{ - talloc_free(iter); -} - -TR_AAA_SERVER *tr_aaa_server_iter_first(TR_AAA_SERVER_ITER *iter, TR_AAA_SERVER *aaa) -{ - iter->this=aaa; - return iter->this; -} - -TR_AAA_SERVER *tr_aaa_server_iter_next(TR_AAA_SERVER_ITER *iter) -{ - if (iter->this!=NULL) { - iter->this=iter->this->next; - } - return iter->this; -} - - /* fills in shared if pointer not null */ TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_IDP_REALM *idp_realms, TR_NAME *idp_realm_name, TR_NAME *comm, int *shared_out) { diff --git a/common/tr_idp_encoders.c b/common/tr_idp_encoders.c index 72acd15..4b3d845 100644 --- a/common/tr_idp_encoders.c +++ b/common/tr_idp_encoders.c @@ -44,7 +44,18 @@ static char *tr_aaa_server_to_str(TALLOC_CTX *mem_ctx, TR_AAA_SERVER *aaa) { - return talloc_strndup(mem_ctx, aaa->hostname->buf, aaa->hostname->len); + char *aaa_hostname = tr_name_strdup( tr_aaa_server_get_hostname(aaa) ); + char *result = NULL; + + if (aaa_hostname == NULL) + return NULL; + + result = talloc_asprintf(mem_ctx, + "%s:%d", + aaa_hostname, + tr_aaa_server_get_port(aaa)); + free(aaa_hostname); + return result; } @@ -151,14 +162,9 @@ cleanup: static json_t *tr_aaa_server_to_json(TR_AAA_SERVER *aaa) { - char *hostname = tr_name_strdup(aaa->hostname); - char *s = NULL; + char *s = tr_aaa_server_to_str(NULL, aaa); json_t *jstr = NULL; - if (hostname == NULL) - return NULL; - - s = talloc_asprintf(NULL, "%s:%d", hostname, TID_PORT); if (s) { jstr = json_string(s); talloc_free(s); diff --git a/common/tr_inet_util.c b/common/tr_inet_util.c new file mode 100644 index 0000000..6d84918 --- /dev/null +++ b/common/tr_inet_util.c @@ -0,0 +1,221 @@ +/* + * 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. + * + */ + +#include +#include +#include +#include +#include + +#include + +/** + * Determine whether a string is a valid address of a given family + * + * @param s string to check + * @param af address family (probably AF_INET or AF_INET6) + * @return 1 if string is a valid address in the given family, 0 if not, -1 on error (errno set) + */ +static int is_valid_address(int af, const char *s) +{ + unsigned char buf[sizeof(struct in6_addr)]; + + if (s == NULL) + return 0; + return inet_pton(af, s, buf); +} + +/** + * Determine whether a string is a valid IPv6 address reference + * + * I.e., an IPv6 address in brackets + * + * @param s string to validate + * @return 1 if a valid reference, 0 otherwise + */ +static int tr_valid_ipv6_reference(const char *s) +{ + char *cpy; + size_t len; + int valid_ipv6; + + /* check that it starts with an open bracket */ + if (*s != '[') + return 0; + + /* check that it ends with a close bracket */ + len = strlen(s); + if (*(s+len-1) != ']') + return 0; + + /* make a null-terminated copy of the string omitting the brackets */ + cpy = talloc_strndup(NULL, s+1, len-2); + if (cpy == NULL) + return 0; /* an error occurred - fail safe */ + + valid_ipv6 = is_valid_address(AF_INET6, cpy); + talloc_free(cpy); + + return valid_ipv6; +} + +/** + * Validate a host string + * + * The intention is to reject strings that may appear to contain a ':port' spec. + * Takes a permissive view of valid: a hostname is valid if either it is a + * bracketed IPv6 address reference ([address]) or has no brackets or colons. + * This accepts all valid DNS names and IPv4 addresses, as well as many invalid + * hostnames. This is ok for accepting a hostname that will later be resolved + * because invalid names will fail to resolve. It should *not* be used to ensure + * a hostname is compliant with RFC! + * + * Ignores a trailing colon followed by decimal digits. + * + * @param s string to validate + * @return 1 if a valid host specification, 0 otherwise + */ +static int tr_valid_host(const char *s) +{ + if (strchr(s, '[') || strchr(s, ']') || strchr(s, ':')) + return tr_valid_ipv6_reference(s); + + return 1; +} + +/** + * Check that all characters are decimal digits + * + * @param s + * @return 1 if all digits, 0 otherwise + */ +static int tr_str_all_digits(const char *s) +{ + if (s == NULL) + return 0; + + for( ; *s; s++) { + if ( (*s < '0') || (*s > '9')) + return 0; + } + + return 1; +} + +/** + * Validate and parse a hostname or hostname/port + * + * If port_out is not null, accepts a port as well. This is + * stored in *port_out. If no port is given, a 0 is stored. + * If an invalid port is given, -1 is stored. + * + * If the hostname is invalid, null is returned and no value + * is written to *port_out. + * + * If port_out is null, null will be returned if the string + * contains a port. + * + * The return value must be freed with talloc_free unless + * it is null. + * + * @param mem_ctx talloc context for hostname result + * @param s string to parse + * @param port_out pointer to an allocated integer, or NULL + * @return pointer to the hostname or null on error + */ +char *tr_parse_host(TALLOC_CTX *mem_ctx, const char *s, int *port_out) +{ + const char *colon; + char *hostname; + long int port; + + if (s == NULL) + return NULL; + + /* If we are accepting a port, find the last colon. */ + if (port_out == NULL) + colon = NULL; + else + colon = strrchr(s, ':'); + + /* Get a copy of the hostname portion, which may be the entire string. */ + if (colon == NULL) + hostname = talloc_strdup(NULL, s); + else + hostname = talloc_strndup(NULL, s, colon-s); + + if (hostname == NULL) + return NULL; /* failed to dup the hostname */ + + /* Check that the hostname is valid; if not, return null and ignore the port. */ + if (! tr_valid_host(hostname)) { + talloc_free(hostname); + return NULL; + } + + /* If we are accepting a port, parse and validate it. */ + if (port_out != NULL) { + if (colon == NULL) { + *port_out = 0; + } else { + port = strtol(colon+1, NULL, 10); + if (tr_str_all_digits(colon+1) && (port > 0) && (port <= 65535)) + *port_out = (int) port; + else + *port_out = -1; + } + } + + return hostname; +} + +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; +} \ No newline at end of file diff --git a/common/tr_msg.c b/common/tr_msg.c index 50e8bc9..886b535 100644 --- a/common/tr_msg.c +++ b/common/tr_msg.c @@ -46,28 +46,30 @@ #include #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 +80,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 +680,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 +714,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 +916,71 @@ 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; + char *hostname; + 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))) { + + hostname = tr_parse_host(tmp_ctx, s, &port); + if ((NULL == hostname) + || (NULL == (name = tr_new_name(hostname))) + || (port < 0)) { + rc = TRP_ERROR; + goto cleanup; + } + talloc_free(s); s=NULL; + talloc_free(hostname); + + 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 */ + hostname = tr_parse_host(tmp_ctx, s, &port); + if ((hostname == NULL) + || (NULL == (name = tr_new_name(hostname))) + || (port < 0)) { + 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_socket.c b/common/tr_socket.c index 1bb3cc2..a45ff31 100644 --- a/common/tr_socket.c +++ b/common/tr_socket.c @@ -55,7 +55,7 @@ * @param max_fd maximum number of file descriptors to write * @return number of file descriptors written into the output array */ -nfds_t tr_sock_listen_all(unsigned int port, int *fd_out, nfds_t max_fd) +nfds_t tr_sock_listen_all(int port, int *fd_out, nfds_t max_fd) { int rc = 0; int conn = -1; diff --git a/common/tr_util.c b/common/tr_util.c index 2e59606..c3d03fb 100644 --- a/common/tr_util.c +++ b/common/tr_util.c @@ -209,4 +209,4 @@ struct timespec *tr_clock_convert(clockid_t from, const struct timespec *when, return NULL; } return dst; -} \ No newline at end of file +} diff --git a/include/mon_internal.h b/include/mon_internal.h index 6e42750..6d94a60 100644 --- a/include/mon_internal.h +++ b/include/mon_internal.h @@ -127,7 +127,7 @@ struct mon_resp { /* Monitoring server instance */ struct mons_instance { const char *hostname; - unsigned int port; + int mon_port; TR_GSS_NAMES *authorized_gss_names; TIDS_INSTANCE *tids; TRPS_INSTANCE *trps; @@ -178,14 +178,20 @@ MON_RESP * mon_resp_decode(TALLOC_CTX *mem_ctx, json_t *resp_json); /* mons.c */ MONS_INSTANCE *mons_new(TALLOC_CTX *mem_ctx); -int mons_get_listener(MONS_INSTANCE *mons, MONS_REQ_FUNC *req_handler, MONS_AUTH_FUNC *auth_handler, const char *hostname, - unsigned int port, void *cookie, int *fd_out, size_t max_fd); +int mons_get_listener(MONS_INSTANCE *mons, + MONS_REQ_FUNC *req_handler, + MONS_AUTH_FUNC *auth_handler, + const char *hostname, + int port, + void *cookie, + int *fd_out, + size_t max_fd); int mons_accept(MONS_INSTANCE *mons, int listen); /* monc.c */ MONC_INSTANCE *monc_new(TALLOC_CTX *mem_ctx); void monc_free(MONC_INSTANCE *monc); -int monc_open_connection(MONC_INSTANCE *monc, const char *server, unsigned int port); +int monc_open_connection(MONC_INSTANCE *monc, const char *server, int port); MON_RESP *monc_send_request(TALLOC_CTX *mem_ctx, MONC_INSTANCE *monc, MON_REQ *req); #endif //TRUST_ROUTER_MON_REQ_H diff --git a/include/tid_internal.h b/include/tid_internal.h index ecaf647..220775b 100644 --- a/include/tid_internal.h +++ b/include/tid_internal.h @@ -104,7 +104,7 @@ struct tids_instance { TIDS_REQ_FUNC *req_handler; tids_auth_func *auth_handler; void *cookie; - unsigned int tids_port; + int tids_port; TR_NAME *gss_name; /* GSS name client used for authentication */ GArray *pids; /* PIDs of active tids processes */ }; @@ -114,7 +114,7 @@ struct tids_instance { reference they already hold to the TID_REQ.*/ void tid_req_cleanup_json(TID_REQ *, json_t *json); -int tid_req_add_path(TID_REQ *, const char *this_system, unsigned port); +int tid_req_add_path(TID_REQ *req, const char *this_system, int port); TID_SRVR_BLK *tid_srvr_blk_new(TALLOC_CTX *mem_ctx); void tid_srvr_blk_free(TID_SRVR_BLK *srvr); diff --git a/include/tr_aaa_server.h b/include/tr_aaa_server.h new file mode 100644 index 0000000..fedc819 --- /dev/null +++ b/include/tr_aaa_server.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012-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. + * + */ + +#ifndef TRUST_ROUTER_TR_AAA_SERVER_H +#define TRUST_ROUTER_TR_AAA_SERVER_H + +#include + +#include + +typedef struct tr_aaa_server { + struct tr_aaa_server *next; + TR_NAME *hostname; + int port; +} TR_AAA_SERVER; + +typedef struct tr_aaa_server_iter { + TR_AAA_SERVER *this; +} TR_AAA_SERVER_ITER; + +TR_AAA_SERVER *tr_aaa_server_new(TALLOC_CTX *mem_ctx); +void tr_aaa_server_free(TR_AAA_SERVER *aaa); + +TR_NAME *tr_aaa_server_get_hostname(TR_AAA_SERVER *aaa); +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_ITER *tr_aaa_server_iter_new(TALLOC_CTX *mem_ctx); +void tr_aaa_server_iter_free(TR_AAA_SERVER_ITER *iter); +TR_AAA_SERVER *tr_aaa_server_iter_first(TR_AAA_SERVER_ITER *iter, TR_AAA_SERVER *aaa); +TR_AAA_SERVER *tr_aaa_server_iter_next(TR_AAA_SERVER_ITER *iter); + +#endif //TRUST_ROUTER_TR_AAA_SERVER_H diff --git a/include/tr_config.h b/include/tr_config.h index 8dc66c4..47be960 100644 --- a/include/tr_config.h +++ b/include/tr_config.h @@ -76,9 +76,9 @@ typedef enum tr_cfg_rc { typedef struct tr_cfg_internal { unsigned int max_tree_depth; - unsigned int tids_port; - unsigned int trps_port; - unsigned int monitoring_port; + int tids_port; + int trps_port; + int mons_port; const char *hostname; int log_threshold; int console_threshold; diff --git a/include/tr_gss_client.h b/include/tr_gss_client.h index 3353184..2b24200 100644 --- a/include/tr_gss_client.h +++ b/include/tr_gss_client.h @@ -50,7 +50,7 @@ struct tr_gssc_instance { /* tr_gss_client.c */ TR_GSSC_INSTANCE *tr_gssc_instance_new(TALLOC_CTX *mem_ctx); void tr_gssc_instance_free(TR_GSSC_INSTANCE *tr_gssc); -int tr_gssc_open_connection(TR_GSSC_INSTANCE *gssc, const char *server, unsigned int port); +int tr_gssc_open_connection(TR_GSSC_INSTANCE *gssc, const char *server, int port); TR_MSG *tr_gssc_exchange_msgs(TALLOC_CTX *mem_ctx, TR_GSSC_INSTANCE *gssc, TR_MSG *req_msg); #endif //TRUST_ROUTER_TR_GSS_CLIENT_H diff --git a/include/tr_idp.h b/include/tr_idp.h index 68d669e..8b56c37 100644 --- a/include/tr_idp.h +++ b/include/tr_idp.h @@ -39,17 +39,9 @@ #include #include +#include #include -typedef struct tr_aaa_server { - struct tr_aaa_server *next; - TR_NAME *hostname; -} TR_AAA_SERVER; - -typedef struct tr_aaa_server_iter { - TR_AAA_SERVER *this; -} TR_AAA_SERVER_ITER; - /* may also want to use in tr_rp.h */ typedef enum tr_realm_origin { TR_REALM_LOCAL=0, /* realm we were configured to contact */ @@ -86,16 +78,8 @@ TR_IDP_REALM *tr_idp_realm_sweep_func(TR_IDP_REALM *head); int tr_idp_realm_aaa_server_count(TR_IDP_REALM *idp); int tr_idp_realm_apc_count(TR_IDP_REALM *idp); void tr_idp_realm_incref(TR_IDP_REALM *realm); -void tr_idp_realm_decref(TR_IDP_REALM *realm); - -TR_AAA_SERVER *tr_aaa_server_new(TALLOC_CTX *mem_ctx, TR_NAME *hostname); -void tr_aaa_server_free(TR_AAA_SERVER *aaa); - -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_AAA_SERVER *tr_aaa_server_iter_first(TR_AAA_SERVER_ITER *iter, TR_AAA_SERVER *aaa); -TR_AAA_SERVER *tr_aaa_server_iter_next(TR_AAA_SERVER_ITER *iter); +void tr_idp_realm_decref(TR_IDP_REALM *realm); TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_IDP_REALM *idp_realms, TR_NAME *idp_realm_name, TR_NAME *comm, int *shared_out); TR_AAA_SERVER *tr_default_server_lookup(TR_AAA_SERVER *default_servers, TR_NAME *comm); diff --git a/include/tr_inet_util.h b/include/tr_inet_util.h new file mode 100644 index 0000000..44d8ba5 --- /dev/null +++ b/include/tr_inet_util.h @@ -0,0 +1,45 @@ +/* + * 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. + * + */ + +#ifndef TRUST_ROUTER_TR_INET_UTIL_H +#define TRUST_ROUTER_TR_INET_UTIL_H + +#include +#include + +char *tr_parse_host(TALLOC_CTX *mem_ctx, const char *s, int *port_out); + +TR_NAME *tr_hostname_and_port_to_name(TR_NAME *hn, int port); + +#endif //TRUST_ROUTER_TR_INET_UTIL_H diff --git a/include/tr_socket.h b/include/tr_socket.h index e90a912..73c8d15 100644 --- a/include/tr_socket.h +++ b/include/tr_socket.h @@ -39,7 +39,7 @@ #include // for nfds_t #include -nfds_t tr_sock_listen_all(unsigned int port, int *fd_out, nfds_t max_fd); +nfds_t tr_sock_listen_all(int port, int *fd_out, nfds_t max_fd); int tr_sock_accept(int sock); #endif //TRUST_ROUTER_TR_SOCKET_H diff --git a/include/tr_util.h b/include/tr_util.h index 9bf7d8e..9b2da06 100644 --- a/include/tr_util.h +++ b/include/tr_util.h @@ -35,6 +35,7 @@ #ifndef TR_UTIL_H #define TR_UTIL_H +#include #include /* NB, tr_bin_to_hex() is also prototyped in trust_router/tr_dh.h */ diff --git a/include/trp_internal.h b/include/trp_internal.h index 8401bfa..0655a62 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; @@ -139,7 +140,7 @@ struct trpc_instance { TRPC_INSTANCE *next; TR_NAME *gssname; char *server; - unsigned int port; + int port; TRP_CONNECTION *conn; TR_MQ *mq; /* msgs from master to trpc */ }; @@ -147,7 +148,8 @@ struct trpc_instance { /* TRP Server Instance Data */ struct trps_instance { char *hostname; - unsigned int port; + int trps_port; + int tids_port; /* used for route advertisements; must agree with our tids configuration */ TRP_AUTH_FUNC auth_handler; TRPS_MSG_FUNC msg_handler; void *cookie; @@ -188,7 +190,7 @@ TRP_CONNECTION *trp_connection_remove(TRP_CONNECTION *conn, TRP_CONNECTION *remo void trp_connection_append(TRP_CONNECTION *conn, TRP_CONNECTION *new); int trp_connection_auth(TRP_CONNECTION *conn, TRP_AUTH_FUNC auth_callback, void *callback_data); TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME *gss_servicename); -TRP_RC trp_connection_initiate(TRP_CONNECTION *conn, char *server, unsigned int port); +TRP_RC trp_connection_initiate(TRP_CONNECTION *conn, char *server, int port); TRPC_INSTANCE *trpc_new (TALLOC_CTX *mem_ctx); void trpc_free (TRPC_INSTANCE *trpc); @@ -203,7 +205,7 @@ void trpc_set_server(TRPC_INSTANCE *trpc, char *server); TR_NAME *trpc_get_gssname(TRPC_INSTANCE *trpc); void trpc_set_gssname(TRPC_INSTANCE *trpc, TR_NAME *gssname); unsigned int trpc_get_port(TRPC_INSTANCE *trpc); -void trpc_set_port(TRPC_INSTANCE *trpc, unsigned int port); +void trpc_set_port(TRPC_INSTANCE *trpc, int port); TRP_CONNECTION_STATUS trpc_get_status(TRPC_INSTANCE *trpc); TR_MQ *trpc_get_mq(TRPC_INSTANCE *trpc); void trpc_set_mq(TRPC_INSTANCE *trpc, TR_MQ *mq); @@ -239,7 +241,7 @@ int trps_get_listener(TRPS_INSTANCE *trps, TRPS_MSG_FUNC msg_handler, TRP_AUTH_FUNC auth_handler, const char *hostname, - unsigned int port, + int port, void *cookie, int *fd_out, size_t max_fd); @@ -275,11 +277,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_peer.h b/include/trp_peer.h index 8886bef..557e2a3 100644 --- a/include/trp_peer.h +++ b/include/trp_peer.h @@ -50,7 +50,7 @@ struct trp_peer { char *server; TR_GSS_NAMES *gss_names; TR_NAME *servicename; - unsigned int port; + int port; unsigned int linkcost; struct timespec last_conn_attempt; TRP_PEER_CONN_STATUS outgoing_status; @@ -73,8 +73,8 @@ void trp_peer_set_gss_names(TRP_PEER *peer, TR_GSS_NAMES *gss_names); TR_GSS_NAMES *trp_peer_get_gss_names(TRP_PEER *peer); TR_NAME *trp_peer_get_servicename(TRP_PEER *peer); TR_NAME *trp_peer_dup_servicename(TRP_PEER *peer); -unsigned int trp_peer_get_port(TRP_PEER *peer); -void trp_peer_set_port(TRP_PEER *peer, unsigned int port); +int trp_peer_get_port(TRP_PEER *peer); +void trp_peer_set_port(TRP_PEER *peer, int port); unsigned int trp_peer_get_linkcost(TRP_PEER *peer); struct timespec *trp_peer_get_last_conn_attempt(TRP_PEER *peer); void trp_peer_set_last_conn_attempt(TRP_PEER *peer, struct timespec *time); 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/tid.h b/include/trust_router/tid.h index 38833f1..33f530c 100644 --- a/include/trust_router/tid.h +++ b/include/trust_router/tid.h @@ -148,7 +148,7 @@ TR_EXPORT int tid_srvr_get_key_expiration(const TID_SRVR_BLK *, struct timeval * /* TID Client functions, in tid/tidc.c */ TR_EXPORT TIDC_INSTANCE *tidc_create (void); -TR_EXPORT int tidc_open_connection (TIDC_INSTANCE *tidc, const char *server, unsigned int port, gss_ctx_id_t *gssctx); +TR_EXPORT int tidc_open_connection(TIDC_INSTANCE *tidc, const char *server, int port, gss_ctx_id_t *gssctx); TR_EXPORT int tidc_send_request (TIDC_INSTANCE *tidc, int conn, gss_ctx_id_t gssctx, const char *rp_realm, const char *realm, const char *coi, TIDC_RESP_FUNC *resp_handler, void *cookie); TR_EXPORT int tidc_fwd_request (TIDC_INSTANCE *tidc, TID_REQ *req, TIDC_RESP_FUNC *resp_handler, void *cookie); TR_EXPORT DH *tidc_get_dh(TIDC_INSTANCE *); @@ -158,12 +158,12 @@ TR_EXPORT void tidc_destroy(TIDC_INSTANCE *tidc); /* TID Server functions, in tid/tids.c */ TIDS_INSTANCE *tids_new(TALLOC_CTX *mem_ctx); TR_EXPORT TIDS_INSTANCE *tids_create (void); -TR_EXPORT int tids_start (TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler, - tids_auth_func *auth_handler, const char *hostname, - unsigned int port, void *cookie); +TR_EXPORT int tids_start(TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler, + tids_auth_func *auth_handler, const char *hostname, + int port, void *cookie); TR_EXPORT nfds_t tids_get_listener(TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler, tids_auth_func *auth_handler, const char *hostname, - unsigned int port, void *cookie, int *fd_out, size_t max_fd); + int port, void *cookie, int *fd_out, size_t max_fd); TR_EXPORT int tids_accept(TIDS_INSTANCE *tids, int listen); TR_EXPORT int tids_send_response (TIDS_INSTANCE *tids, TID_REQ *req, TID_RESP *resp); TR_EXPORT int tids_send_err_response (TIDS_INSTANCE *tids, TID_REQ *req, const char *err_msg); diff --git a/include/trust_router/trp.h b/include/trust_router/trp.h index 1c8e193..b650cf8 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 { @@ -90,7 +91,7 @@ void trp_upd_set_comm(TRP_UPD *upd, TR_NAME *comm); TR_EXPORT TR_NAME *trp_upd_get_peer(TRP_UPD *upd); TR_NAME *trp_upd_dup_peer(TRP_UPD *upd); void trp_upd_set_peer(TRP_UPD *upd, TR_NAME *peer); -void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port); +void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, int port); void trp_upd_add_to_provenance(TRP_UPD *upd, TR_NAME *name); /* Functions for TRP_REQ structures */ diff --git a/mon/monc.c b/mon/monc.c index 6e5b26a..c16d328 100644 --- a/mon/monc.c +++ b/mon/monc.c @@ -65,7 +65,7 @@ void monc_free(MONC_INSTANCE *monc) int monc_open_connection(MONC_INSTANCE *monc, const char *server, - unsigned int port) + int port) { return tr_gssc_open_connection(monc->gssc, server, port); } diff --git a/mon/mons.c b/mon/mons.c index 3733357..72070cf 100644 --- a/mon/mons.c +++ b/mon/mons.c @@ -73,7 +73,7 @@ MONS_INSTANCE *mons_new(TALLOC_CTX *mem_ctx) if (mons) { mons->hostname = NULL; - mons->port = 0; + mons->mon_port = 0; mons->tids = NULL; mons->trps = NULL; mons->req_handler = NULL; @@ -175,13 +175,19 @@ cleanup: * @param max_fd * @return */ -int mons_get_listener(MONS_INSTANCE *mons, MONS_REQ_FUNC *req_handler, MONS_AUTH_FUNC *auth_handler, const char *hostname, - unsigned int port, void *cookie, int *fd_out, size_t max_fd) +int mons_get_listener(MONS_INSTANCE *mons, + MONS_REQ_FUNC *req_handler, + MONS_AUTH_FUNC *auth_handler, + const char *hostname, + int port, + void *cookie, + int *fd_out, + size_t max_fd) { size_t n_fd=0; size_t ii=0; - mons->port = port; + mons->mon_port = port; n_fd = tr_sock_listen_all(port, fd_out, max_fd); if (n_fd<=0) tr_err("mons_get_listener: Error opening port %d", port); diff --git a/tid/tid_req.c b/tid/tid_req.c index 002b720..1bfce70 100644 --- a/tid/tid_req.c +++ b/tid/tid_req.c @@ -253,7 +253,7 @@ void tid_req_free(TID_REQ *req) } int tid_req_add_path(TID_REQ *req, - const char *this_system, unsigned port) + const char *this_system, int port) { char *path_element = talloc_asprintf(req, "%s:%u", this_system, port); diff --git a/tid/tidc.c b/tid/tidc.c index 1cff6f0..9578f3d 100644 --- a/tid/tidc.c +++ b/tid/tidc.c @@ -79,12 +79,12 @@ void tidc_destroy(TIDC_INSTANCE *tidc) talloc_free(tidc); } -int tidc_open_connection (TIDC_INSTANCE *tidc, - const char *server, - unsigned int port, - gss_ctx_id_t *gssctx) +int tidc_open_connection(TIDC_INSTANCE *tidc, + const char *server, + int port, + gss_ctx_id_t *gssctx) { - unsigned int use_port = 0; + int use_port = 0; tidc->gssc->gss_ctx = gssctx; if (0 == port) diff --git a/tid/tids.c b/tid/tids.c index ddd91b0..f600d66 100644 --- a/tid/tids.c +++ b/tid/tids.c @@ -356,7 +356,7 @@ nfds_t tids_get_listener(TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler, tids_auth_func *auth_handler, const char *hostname, - unsigned int port, + int port, void *cookie, int *fd_out, size_t max_fd) @@ -574,12 +574,12 @@ void tids_sweep_procs(TIDS_INSTANCE *tids) } /* Process tids requests forever. Should not return except on error. */ -int tids_start (TIDS_INSTANCE *tids, - TIDS_REQ_FUNC *req_handler, - tids_auth_func *auth_handler, - const char *hostname, - unsigned int port, - void *cookie) +int tids_start(TIDS_INSTANCE *tids, + TIDS_REQ_FUNC *req_handler, + tids_auth_func *auth_handler, + const char *hostname, + int port, + void *cookie) { int fd[TR_MAX_SOCKETS]={0}; nfds_t n_fd=0; diff --git a/tr/tr_main.c b/tr/tr_main.c index ba738c7..73c429e 100644 --- a/tr/tr_main.c +++ b/tr/tr_main.c @@ -310,6 +310,9 @@ int main(int argc, char *argv[]) return 1; } + /* tell the trps which port the tid server listens on */ + tr->trps->tids_port = tr->tids->tids_port; + /* install TRP handler events */ tr_debug("Initializing Dynamic Trust Router Protocol events."); if (TRP_SUCCESS != tr_trps_event_init(ev_base, tr)) { diff --git a/tr/tr_mon.c b/tr/tr_mon.c index 84ab353..1327082 100644 --- a/tr/tr_mon.c +++ b/tr/tr_mon.c @@ -144,7 +144,7 @@ int tr_mons_event_init(struct event_base *base, goto cleanup; } - if (cfg_mgr->active->internal->monitoring_port == 0) { + if (cfg_mgr->active->internal->mons_port == 0) { tr_notice("tr_mons_event_init: monitoring is disabled, not enabling events or opening sockets"); retval = 0; goto cleanup; @@ -166,7 +166,7 @@ int tr_mons_event_init(struct event_base *base, mons_ev->n_sock_fd = mons_get_listener(mons, tr_mons_req_handler, tr_mons_auth_handler, cfg_mgr->active->internal->hostname, - cfg_mgr->active->internal->monitoring_port, + cfg_mgr->active->internal->mons_port, (void *) cookie, mons_ev->sock_fd, TR_MAX_SOCKETS); if (mons_ev->n_sock_fd==0) { diff --git a/tr/tr_tid.c b/tr/tr_tid.c index 0e324eb..9d32edc 100644 --- a/tr/tr_tid.c +++ b/tr/tr_tid.c @@ -87,7 +87,7 @@ struct tr_tids_fwd_cookie { int thread_id; pthread_mutex_t mutex; /* lock on the mq (separate from the locking within the mq, see below) */ TR_MQ *mq; /* messages from thread to main process; set to NULL to disable response */ - TR_NAME *aaa_hostname; + TR_AAA_SERVER *aaa; /* AAA server to contact */ DH *dh_params; TID_REQ *fwd_req; /* the req to duplicate */ }; @@ -95,8 +95,6 @@ struct tr_tids_fwd_cookie { static int tr_tids_fwd_cookie_destructor(void *obj) { struct tr_tids_fwd_cookie *c=talloc_get_type_abort(obj, struct tr_tids_fwd_cookie); - if (c->aaa_hostname!=NULL) - tr_free_name(c->aaa_hostname); if (c->dh_params!=NULL) tr_destroy_dh_params(c->dh_params); return 0; @@ -136,6 +134,8 @@ static void *tr_tids_req_fwd_thread(void *arg) TIDC_INSTANCE *tidc=tidc_create(); TR_MQ_MSG *msg=NULL; TR_RESP_COOKIE *cookie=NULL; + char *aaa_hostname = NULL; + int aaa_port; int rc=0; int success=0; @@ -147,7 +147,7 @@ static void *tr_tids_req_fwd_thread(void *arg) /* create the cookie we will use for our response */ cookie=talloc(tmp_ctx, TR_RESP_COOKIE); if (cookie==NULL) { - tr_notice("tr_tids_req_fwd_thread: unable to allocate response cookie."); + tr_crit("tr_tids_req_fwd_thread: unable to allocate response cookie."); success=0; goto cleanup; } @@ -164,19 +164,31 @@ static void *tr_tids_req_fwd_thread(void *arg) } /* Set-up TID connection */ + aaa_hostname = tr_name_strdup(tr_aaa_server_get_hostname(args->aaa)); + if (aaa_hostname == NULL) { + tr_crit("tr_tids_req_fwd_thread: unable to allocate AAA hostname string"); + success=0; + goto cleanup; + } + aaa_port = tr_aaa_server_get_port(args->aaa); + if ((aaa_port <= 0) || (aaa_port > 65535)) { + tr_notice("tr_tids_req_fwd_thread: invalid port (%d) for %s", aaa_port, aaa_hostname); + success=0; + goto cleanup; + } + if (-1==(args->fwd_req->conn = tidc_open_connection(tidc, - args->aaa_hostname->buf, - TID_PORT, /* TODO: make this configurable */ - &(args->fwd_req->gssctx)))) { + aaa_hostname, + aaa_port, + &(args->fwd_req->gssctx)))) { tr_notice("tr_tids_req_fwd_thread: Error in tidc_open_connection."); /* tids_send_err_response(tids, orig_req, "Can't open connection to next hop TIDS"); */ /* TODO: encode reason for failure */ success=0; goto cleanup; }; - tr_debug("tr_tids_req_fwd_thread: thread %d opened TID connection to %s.", - cookie->thread_id, - args->aaa_hostname->buf); + tr_debug("tr_tids_req_fwd_thread: thread %d opened TID connection to %s:%d.", + cookie->thread_id, aaa_hostname, aaa_port); /* Send a TID request. */ if (0 > (rc = tidc_fwd_request(tidc, args->fwd_req, tr_tidc_resp_handler, (void *)cookie))) { @@ -213,6 +225,9 @@ cleanup: tr_notice("tr_tids_req_fwd_thread: Error releasing mutex."); } + if (aaa_hostname != NULL) + free(aaa_hostname); + talloc_free(tmp_ctx); return NULL; } @@ -511,7 +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_new(tmp_ctx, trp_route_get_next_hop(route)); + 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; } @@ -586,7 +613,7 @@ static int tr_tids_req_handler(TIDS_INSTANCE *tids, goto cleanup; } aaa_cookie[n_aaa]->mq=mq; - aaa_cookie[n_aaa]->aaa_hostname=tr_dup_name(this_aaa->hostname); + aaa_cookie[n_aaa]->aaa=this_aaa; aaa_cookie[n_aaa]->dh_params=tr_dh_dup(orig_req->tidc_dh); aaa_cookie[n_aaa]->fwd_req=tid_dup_req(fwd_req); talloc_steal(aaa_cookie[n_aaa], aaa_cookie[n_aaa]->fwd_req); diff --git a/tr/tr_trp.c b/tr/tr_trp.c index 7788a01..c525f54 100644 --- a/tr/tr_trp.c +++ b/tr/tr_trp.c @@ -703,11 +703,21 @@ 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 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, + size_t *n_routes) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); TR_APC *comm=NULL; @@ -736,7 +746,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("")); /* no next hop */ + trp_route_set_next_hop_port(new_entry, -1); /* no next hop */ trp_route_set_local(new_entry, 1); entries[ii]=new_entry; } @@ -816,14 +828,9 @@ 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, &n_routes); for (ii=0; ii 65535)) /* max valid port */ argp_usage(state); - arguments->port=(unsigned int) tmp_l; + arguments->port = (int) tmp_l; /* we already checked the range */ break; case 2: diff --git a/trp/test/ptbl_test.c b/trp/test/ptbl_test.c index 5853895..05c3997 100644 --- a/trp/test/ptbl_test.c +++ b/trp/test/ptbl_test.c @@ -48,7 +48,7 @@ struct peer_entry { char *server; char *gss_name; - unsigned int port; + int port; unsigned int linkcost; }; diff --git a/trp/trp_conn.c b/trp/trp_conn.c index 1cf326d..370d5b1 100644 --- a/trp/trp_conn.c +++ b/trp/trp_conn.c @@ -364,11 +364,11 @@ TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME * } /* Initiate connection */ -TRP_RC trp_connection_initiate(TRP_CONNECTION *conn, char *server, unsigned int port) +TRP_RC trp_connection_initiate(TRP_CONNECTION *conn, char *server, int port) { int err = 0; int fd=-1; - unsigned int use_port=0; + int use_port=0; if (0 == port) use_port = TRP_PORT; diff --git a/trp/trp_peer.c b/trp/trp_peer.c index c98cf47..34d4296 100644 --- a/trp/trp_peer.c +++ b/trp/trp_peer.c @@ -173,12 +173,12 @@ TR_NAME *trp_peer_dup_servicename(TRP_PEER *peer) return tr_dup_name(peer->servicename); } -unsigned int trp_peer_get_port(TRP_PEER *peer) +int trp_peer_get_port(TRP_PEER *peer) { return peer->port; } -void trp_peer_set_port(TRP_PEER *peer, unsigned int port) +void trp_peer_set_port(TRP_PEER *peer, int port) { peer->port=port; } diff --git a/trp/trp_peer_encoders.c b/trp/trp_peer_encoders.c index a1cc64f..48f74c5 100644 --- a/trp/trp_peer_encoders.c +++ b/trp/trp_peer_encoders.c @@ -51,7 +51,7 @@ char *trp_peer_to_str(TALLOC_CTX *memctx, TRP_PEER *peer, const char *sep) } /* helper for encoding to json */ -static json_t *server_to_json_string(const char *server, unsigned int port) +static json_t *server_to_json_string(const char *server, int port) { char *s = talloc_asprintf(NULL, "%s:%u", server, port); json_t *jstr = json_string(s); diff --git a/trp/trp_route.c b/trp/trp_route.c index 6178d97..d552e01 100644 --- a/trp/trp_route.c +++ b/trp/trp_route.c @@ -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; @@ -176,7 +176,6 @@ unsigned int trp_route_get_metric(TRP_ROUTE *entry) return entry->metric; } -/* TODO: set the hostname and port for the next hop. Currently assume default TID port. --jlr */ void trp_route_set_next_hop(TRP_ROUTE *entry, TR_NAME *next_hop) { if (entry->next_hop!=NULL) @@ -262,3 +261,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..ad913da 100644 --- a/trp/trp_route_encoders.c +++ b/trp/trp_route_encoders.c @@ -45,6 +45,7 @@ #include #include #include +#include /* Pretty print a route table entry to a newly allocated string. If sep is NULL, * returns comma+space separated string. */ @@ -62,13 +63,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 +109,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 +120,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..7feb777 100644 --- a/trp/trp_upd.c +++ b/trp/trp_upd.c @@ -211,27 +211,40 @@ 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: if (rec->data->route!=NULL) { rec->data->route->trust_router=trust_router; + rec->data->route->trust_router_port = port; return TRP_SUCCESS; } break; @@ -241,16 +254,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 +284,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 +302,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) { @@ -778,13 +803,13 @@ void trp_upd_set_peer(TRP_UPD *upd, TR_NAME *peer) upd->peer=peer; } -void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port) +void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, int port) { TRP_INFOREC *rec=NULL; 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/trpc.c b/trp/trpc.c index aef5f7b..04a8ca2 100644 --- a/trp/trpc.c +++ b/trp/trpc.c @@ -153,7 +153,7 @@ unsigned int trpc_get_port(TRPC_INSTANCE *trpc) return trpc->port; } -void trpc_set_port(TRPC_INSTANCE *trpc, unsigned int port) +void trpc_set_port(TRPC_INSTANCE *trpc, int port) { trpc->port=port; } diff --git a/trp/trps.c b/trp/trps.c index f663232..a489133 100644 --- a/trp/trps.c +++ b/trp/trps.c @@ -69,7 +69,7 @@ TRPS_INSTANCE *trps_new (TALLOC_CTX *mem_ctx) TRPS_INSTANCE *trps=talloc(mem_ctx, TRPS_INSTANCE); if (trps!=NULL) { trps->hostname=NULL; - trps->port=0; + trps->trps_port=0; trps->cookie=NULL; trps->conn=NULL; trps->trpc=NULL; @@ -196,7 +196,7 @@ TR_NAME *trps_dup_label(TRPS_INSTANCE *trps) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); TR_NAME *label=NULL; - char *s=talloc_asprintf(tmp_ctx, "%s:%u", trps->hostname, trps->port); + char *s=talloc_asprintf(tmp_ctx, "%s:%u", trps->hostname, trps->trps_port); if (s==NULL) goto cleanup; label=tr_new_name(s); @@ -362,7 +362,6 @@ static TRP_RC trps_read_message(TRPS_INSTANCE *trps, TRP_CONNECTION *conn, TR_MS 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; @@ -385,7 +384,7 @@ int trps_get_listener(TRPS_INSTANCE *trps, TRPS_MSG_FUNC msg_handler, TRP_AUTH_FUNC auth_handler, const char *hostname, - unsigned int port, + int port, void *cookie, int *fd_out, size_t max_fd) @@ -420,7 +419,7 @@ int trps_get_listener(TRPS_INSTANCE *trps, trps->msg_handler = msg_handler; trps->auth_handler = auth_handler; trps->hostname = talloc_strdup(trps, hostname); - trps->port = port; + trps->trps_port = port; trps->cookie = cookie; } @@ -502,12 +501,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 +607,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; @@ -612,8 +637,9 @@ static TRP_RC trps_accept_update(TRPS_INSTANCE *trps, TRP_UPD *upd, TRP_INFOREC trp_route_set_realm(entry, trp_upd_dup_realm(upd)); trp_route_set_peer(entry, trp_upd_dup_peer(upd)); trp_route_set_trust_router(entry, trp_inforec_dup_trust_router(rec)); + trp_route_set_trust_router_port(entry, trp_inforec_get_trust_router_port(rec)); trp_route_set_next_hop(entry, trp_inforec_dup_next_hop(rec)); - /* TODO: pass next hop port (now defaults to TID_PORT) --jlr */ + trp_route_set_next_hop_port(entry, trp_inforec_get_next_hop_port(rec)); if ((trp_route_get_comm(entry)==NULL) ||(trp_route_get_realm(entry)==NULL) ||(trp_route_get_peer(entry)==NULL) @@ -635,13 +661,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 +715,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); } @@ -1349,13 +1374,23 @@ static TRP_INFOREC *trps_route_to_inforec(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *tr trp_route_get_peer(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)) { + /* + * This is where we add the link cost (currently always 1) to the next peer. + * + * Here, set next_hop to our TID address/port rather than passing along our own + * next_hop. That is the one *we* use to forward requests. We are advertising + * ourselves as a hop for our peers. + */ + 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, + tr_new_name(trps->hostname), + trps->tids_port)) + ||(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;