tr_tr_SOURCES = tr/tr_main.c \
common/tr_config.c \
+common/tr_idp.c \
tr/tr.c
tr_tr_LDADD = gsscon/libgsscon.la libtr_tid.la
-
Eventually this document may go away or hold README information for
the trust router. Right now, it serves as a to-do list for work that
needs to be done on the trust router code before various releases:
-TO-DO FOR BETA
-==============
-DONE - Eliminate bulk of info/debug messages
-DONE - Java encode/decode of full requests/responses
-DONE - Generate a real random number for DH code (in common/tr_dh.c)
-DONE - DH server-side code (in TIDS)
-IN PROGRESS - Read TR router config from file at start-up (non-dynamic)
-IN PROGRESS - Look-up code to find correct AAA Server for a Comm/Realm
-JUST STARTED - TIDC and TIDS integration with freeradius proxy and server
-- Code to map a COI to an APC in TR
-- Code to check rp_realm COI membership in TR
-- Code to check gss_name in TR
+TO-DO FOR BETA RELEASE (originally due Jan 2013)
+======================
+DONE - GSS connection API (based on MIT example code)
+DONE - DH implementation and test code (based on openssl)
+DONE - TID server and client implementation (API & example code)
+DONE - Add DH server-side code to TIDS
+DONE - JSON encode/decode of TID requests/responses (jansson)
+DONE - Eliminate bulk of info/debug messages (mostly from GSS code)
+DONE - Generate a real random number for DH (in common/tr_dh.c)
+DONE - Read TR portal/manual config from files at start-up (non-dynamic)
+DONE - Look-up code to find correct AAA Server for a Comm/Realm
+IN PROGRESS - TR TID request & response handlers
+IN PROGRESS - TIDS integration with freeradius server (Sam)
+IN PROGRESS - TIDC integration with freeradius proxy (incl default comm config)
+- Handle community configuration in AAA proxy (per-request config)
+- Map a COI to an APC in TR (incl config & lookup code)
+- Check rp_realm COI membership in TR
+- Check idp_realm APC membership in TR
+- Check gss_name in TR
+- Resolve TBDs for error handling and memory deallocation
-TO-DO FOR PILOT
-===============
+TO-DO FOR FULL PILOT VERSION (~2 months after beta release)
+============================
+- Move to better tasking model for TR (needed for dyn cfg and TR protocol)
- Dynamically re-read TR configuration file at runtime
-- Move to longer-term tasking model for TR
-- Normalize/configure logging for info msgs, warnings and errors (log4c?)
-- Clean-up gsscon API/messages
-- Hand IPv6 addresses in TID req/resp
-- Filtering and Constraints
+- Keep single connection open between AAA proxy & TR for TID requests
+- Normalize/configure logging for info msgs, warnings and errors (log4c)
+- Clean-up gsscon API and messages
+- Handle IPv6 addresses in TID req/resp (use getaddrinfo())
+- Implement rp_permitted filters (incl. general filtering mechanism)
+- Add constraints to TID req in TR, store and use them in AAA Server
+- Use valgrind to check for memory leaks, other issues
+- Full functional testing
-TO-DO FOR PRODUCTION
-====================
-- Multiple Trust Router support including TR protocol
-- Consider standard encoding of DH info (from ?? WG)
-- Update json parsers to use "format strings" for better error handling
-- Algorithm agility in TID protocol?
\ No newline at end of file
+TO-DO FOR PRODUCTION VERSION (August 2013)
+============================
+- Multiple Trust Router support including implementation of TR protocol
+- Consider standard encoding of DH info (from jose WG)
+- Algorithm agility in TID protocol?
#include <tr.h>
void tr_print_config (FILE *stream, TR_CFG *cfg) {
- fprintf(stream, "tr_print_config(): Not yet implemented.\n");
+ fprintf(stream, "tr_print_config: Not yet implemented.\n");
return;
}
}
TR_CFG_RC tr_apply_new_config (TR_INSTANCE *tr) {
- TR_CFG_RC rc = TR_CFG_SUCCESS;
if (!tr)
return TR_CFG_BAD_PARAMS;
+ if (tr->active_cfg)
+ tr_cfg_free(tr->active_cfg);
+
tr->active_cfg = tr->new_cfg;
+ return TR_CFG_SUCCESS;
+}
+
+static TR_CFG_RC tr_cfg_parse_internal (TR_INSTANCE *tr, json_t *jcfg) {
+ json_t *jint = NULL;
+ json_t *jmtd = NULL;
+
+ if ((!tr) || (!tr->new_cfg) || (!jcfg))
+ return TR_CFG_BAD_PARAMS;
+
+ if (NULL == (tr->new_cfg->internal = malloc(sizeof(TR_CFG_INTERNAL))))
+ return TR_CFG_NOMEM;
+
+ memset(tr->new_cfg->internal, 0, sizeof(TR_CFG_INTERNAL));
+
+ if ((NULL != (jint = json_object_get(jcfg, "tr_internal"))) &&
+ (NULL != (jmtd = json_object_get(jint, "max_tree_depth")))) {
+ if (json_is_number(jmtd)) {
+ tr->new_cfg->internal->max_tree_depth = json_integer_value(jmtd);
+ } else {
+ fprintf(stderr,"tr_cfg_parse_internal: Parsing error, max_tree_depth is not a number.\n");
+ return TR_CFG_NOPARSE;
+ }
+ } else {
+ /* If not configured, use the default */
+ tr->new_cfg->internal->max_tree_depth = TR_DEFAULT_MAX_TREE_DEPTH;
+ }
+ fprintf(stderr, "tr_cfg_parse_internal: Internal config parsed.\n");
+ return TR_CFG_SUCCESS;
+}
+
+static TR_CFG_RC tr_cfg_parse_rp_clients (TR_INSTANCE *tr, json_t *jcfg) {
+ // json_t *jrpr = NULL;
+
+ return TR_CFG_SUCCESS;
+}
+
+static TR_AAA_SERVER *tr_cfg_parse_one_aaa_server (TR_INSTANCE *tr, json_t *jaddr, TR_CFG_RC *rc) {
+ TR_AAA_SERVER *aaa = NULL;
+
+ if ((!tr) || (!tr->new_cfg) || (!jaddr) || (!json_is_string(jaddr))) {
+ fprintf(stderr, "tr_cfg_parse_one_aaa_server: Bad parameters.\n");
+ *rc = TR_CFG_BAD_PARAMS;
+ return NULL;
+ }
+
+ if (NULL == (aaa = malloc(sizeof(TR_AAA_SERVER)))) {
+ fprintf(stderr, "tr_config_parse_one_aaa_server: Out of memory.\n");
+ *rc = TR_CFG_NOMEM;
+ return NULL;
+ }
+
+ memset(aaa, 0, sizeof(TR_AAA_SERVER));
+
+ /* TBD -- Handle IPv6 addresses */
+ inet_aton(json_string_value(jaddr), &(aaa->aaa_server_addr));
+
+ return aaa;
+}
+
+
+static TR_AAA_SERVER *tr_cfg_parse_aaa_servers (TR_INSTANCE *tr, json_t *jaaas, TR_CFG_RC *rc)
+{
+ TR_AAA_SERVER *aaa = NULL;
+ TR_AAA_SERVER *temp_aaa = NULL;
+ int i = 0;
+
+ for (i = 0; i < json_array_size(jaaas); i++) {
+ if (NULL == (temp_aaa = tr_cfg_parse_one_aaa_server(tr, json_array_get(jaaas, i), rc))) {
+ return NULL;
+ }
+ /* TBD -- IPv6 addresses */
+ // fprintf(stderr, "tr_cfg_parse_aaa_servers: Configuring AAA Server: ip_addr = %s.\n", inet_ntoa(temp_aaa->aaa_server_addr));
+ temp_aaa->next = aaa;
+ aaa = temp_aaa;
+ }
+ return aaa;
+}
+
+static TR_APC *tr_cfg_parse_apcs (TR_INSTANCE *tr, json_t *apcs, TR_CFG_RC *rc)
+{
+ TR_APC *apc;
+
+ return (apc = malloc(sizeof(TR_APC)));
+}
+
+static TR_IDP_REALM *tr_cfg_parse_one_idp_realm (TR_INSTANCE *tr, json_t *jidp, TR_CFG_RC *rc) {
+ TR_IDP_REALM *idp = NULL;
+ json_t *jrid = NULL;
+ json_t *jscfg = NULL;
+ json_t *jsrvrs = NULL;
+ json_t *japcs = NULL;
+
+ if ((!tr) || (!tr->new_cfg) || (!jidp)) {
+ fprintf(stderr, "tr_cfg_parse_one_idp_realm: Bad parameters.\n");
+ *rc = TR_CFG_BAD_PARAMS;
+ return NULL;
+ }
+
+ if (NULL == (idp = malloc(sizeof(TR_IDP_REALM)))) {
+ fprintf(stderr, "tr_config_parse_one_idp_realm: Our of memory.\n");
+ *rc = TR_CFG_NOMEM;
+ return NULL;
+ }
+
+ memset(idp, 0, sizeof(TR_IDP_REALM));
+
+ if ((NULL == (jrid = json_object_get(jidp, "realm_id"))) ||
+ (!json_is_string(jrid)) ||
+ (NULL == (jscfg = json_object_get(jidp, "shared_config"))) ||
+ (!json_is_string(jscfg)) ||
+ (NULL == (jsrvrs = json_object_get(jidp, "aaa_servers"))) ||
+ (!json_is_array(jsrvrs)) ||
+ (NULL == (japcs = json_object_get(jidp, "apcs"))) ||
+ (!json_is_array(japcs))) {
+ fprintf(stderr, "tr_cfg_parse_one_realm: Error parsing IDP realm configuration.\n");
+ free(idp);
+ *rc = TR_CFG_NOPARSE;
+ return NULL;
+ }
+
+ if (0 == strcmp(json_string_value(jscfg), "no")) {
+ idp->shared_config = 0;
+ } else {
+ idp->shared_config = 1;
+ }
+
+ if (NULL == (idp->realm_id = tr_new_name((char *)json_string_value(jrid)))) {
+ free(idp);
+ fprintf(stderr, "tr_cfg_parse_one_idp_realm: No memory for realm id.\n");
+ *rc = TR_CFG_NOMEM;
+ return NULL;
+ }
+
+ if (NULL == (idp->aaa_servers = tr_cfg_parse_aaa_servers(tr, jsrvrs, rc))) {
+ fprintf(stderr, "tr_cfg_parse_one_idp_realm: Can't parse AAA servers for realm %s.\n", idp->realm_id->buf);
+ tr_free_name(idp->realm_id);
+ free(idp);
+ return NULL;
+ }
+ if (NULL == (idp->apcs = tr_cfg_parse_apcs(tr, japcs, rc))) {
+ fprintf(stderr, "tr_cfg_parse_one_idp_realm: Can't parse APCs for realm %s .\n", idp->realm_id->buf);
+ tr_free_name(idp->realm_id);
+ /* TBD -- free aaa_servers */;
+ free(idp);
+ return NULL;
+ }
+
+return idp;
+}
+
+static TR_CFG_RC tr_cfg_parse_idp_realms (TR_INSTANCE *tr, json_t *jcfg)
+{
+ json_t *jidps = NULL;
+ TR_CFG_RC rc = TR_CFG_SUCCESS;
+ TR_IDP_REALM *idp = NULL;
+ int i = 0;
+
+ if ((!tr) || (!tr->new_cfg) || (!jcfg))
+ return TR_CFG_BAD_PARAMS;
+
+ if ((NULL == (jidps = json_object_get(jcfg, "idp_realms"))) ||
+ (!json_is_array(jidps))) {
+ return TR_CFG_NOPARSE;
+ }
+
+ for (i = 0; i < json_array_size(jidps); i++) {
+ if (NULL == (idp = tr_cfg_parse_one_idp_realm(tr, json_array_get(jidps, i), &rc))) {
+ return rc;
+ }
+ fprintf(stderr, "tr_cfg_parse_idp_realms: IDP realm configured: realm_id = %s.\n", idp->realm_id->buf);
+ idp->next = tr->new_cfg->idp_realms;
+ tr->new_cfg->idp_realms = idp;
+ }
return rc;
}
+static TR_CFG_RC tr_cfg_parse_comms (TR_INSTANCE *tr, json_t *jcfg) {
+
+
+ return TR_CFG_SUCCESS;
+}
+
TR_CFG_RC tr_parse_config (TR_INSTANCE *tr, json_t *jcfg) {
+ /* If there is a partial/abandoned config lying around, free it */
if (tr->new_cfg) {
tr_cfg_free(tr->new_cfg);
- tr->new_cfg = NULL;
}
+
+ if (NULL == (tr->new_cfg = malloc(sizeof(TR_CFG))))
+ return TR_CFG_NOMEM;
+
+ memset(tr->new_cfg, 0, sizeof(TR_CFG));
- // if ((TR_CFG_SUCCESS != tr_cfg_parse_internal(tr, jcfg)) ||
- // (TR_CFG_SUCCESS != tr_cfg_parse_rp_realms(tr, jcfg)) ||
- // (TR_CFG_SUCCESS != tr_cfg_parse_idp_realms(tr, jcfg)) ||
- // (TR_CFG_SUCCESS != tr_cfg_parse_comms(tr, jcfg))) {
- // if (tr->new_cfg)
- // tr_cfg_free(tr->new_cfg);
- // return TR_CFG_ERROR;
- // }
+ if ((TR_CFG_SUCCESS != tr_cfg_parse_internal(tr, jcfg)) ||
+ (TR_CFG_SUCCESS != tr_cfg_parse_rp_clients(tr, jcfg)) ||
+ (TR_CFG_SUCCESS != tr_cfg_parse_idp_realms(tr, jcfg)) ||
+ (TR_CFG_SUCCESS != tr_cfg_parse_comms(tr, jcfg))) {
+ tr_cfg_free(tr->new_cfg);
+ return TR_CFG_ERROR;
+ }
return TR_CFG_SUCCESS;
}
}
}
- fprintf(stderr, "tr_read_config: Merged configuration complete:\n%s\n", json_dumps(jcfg, 0));
+ // fprintf(stderr, "tr_read_config: Merged configuration complete:\n%s\n", json_dumps(jcfg, 0));
return jcfg;
}
if (n < 0) {
perror("scandir");
- fprintf(stderr, "tr_find_config(): scandir error.\n");
+ fprintf(stderr, "tr_find_config: scandir error.\n");
return 0;
}
if (n == 0) {
- fprintf (stderr, "tr_find_config(): No config files found.\n");
+ fprintf (stderr, "tr_find_config: No config files found.\n");
return 0;
}
i = n;
while(i--) {
- fprintf(stderr, "tr_find_config(): Config file found (%s).\n", (*cfg_files)[i]->d_name);
+ fprintf(stderr, "tr_find_config: Config file found (%s).\n", (*cfg_files)[i]->d_name);
}
return n;
--- /dev/null
+/*
+ * Copyright (c) 2012, 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 <trust_router/tr_name.h>
+#include <tr_idp.h>
+#include <tr.h>
+#include <tr_config.h>
+
+TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_INSTANCE *tr, TR_NAME *idp_realm, TR_NAME *comm)
+{
+ TR_IDP_REALM *idp = NULL;
+
+ for (idp = tr->active_cfg->idp_realms; idp != NULL; idp = idp->next) {
+ if (!tr_name_cmp(idp_realm, idp->realm_id)) {
+ /* TBD -- check that the community is one of the APCs for the IDP */
+ break;
+ }
+ }
+ if (idp)
+ return idp->aaa_servers;
+ else
+ return NULL;
+}
#include <trust_router/tr_name.h>
+void tr_free_name (TR_NAME *name)
+{
+ if (name->buf) {
+ free (name->buf);
+ name->buf = NULL;
+ }
+
+ free(name);
+}
+
TR_NAME *tr_new_name (char *name)
{
TR_NAME *new;
return to;
}
+
+int tr_name_cmp(TR_NAME *one, TR_NAME *two)
+{
+ if (one->len != two->len)
+ return 1;
+ else
+ /* TBD -- should really do a length-based comparison */
+ return strcmp(one->buf, two->buf);
+}
--- /dev/null
+/*
+ * Copyright (c) 2012, 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 TR_COMM_H
+#define TR_COMM_H
+
+#include <tr_idp.h>
+#include <tr_rp.h>
+
+typedef enum tr_comm_type {
+ TR_COMM_UNKNOWN,
+ TR_COMM_APC,
+ TR_COMM_COI
+} TR_COMM_TYPE;
+
+typedef struct tr_comm {
+ struct tr_comm *next;
+ TR_COMM_TYPE type;
+ char *id;
+ TR_IDP_REALM *idp_realms;
+ TR_RP_CLIENT *rp_clients;
+} TR_COMM;
+
+#endif
#include <jansson.h>
#include <tr.h>
+#include <tr_rp.h>
+#include <tr_idp.h>
+#include <tr_comm.h>
+
+#define TR_DEFAULT_MAX_TREE_DEPTH 12
typedef enum tr_cfg_rc {
TR_CFG_SUCCESS = 0, /* No error */
TR_CFG_ERROR, /* General processing error */
- TR_CFG_BAD_PARAMS /* Bad parameters passed to tr_config function */
+ TR_CFG_BAD_PARAMS, /* Bad parameters passed to tr_config function */
+ TR_CFG_NOPARSE, /* Parsing error */
+ TR_CFG_NOMEM /* Memory allocation error */
} TR_CFG_RC;
-
-typedef struct tr_cfg_file {
- struct tr_cfg_file *next;
- FILE *cfg_file;
-} TR_CFG_FILE;
-
typedef struct tr_cfg_internal {
- unsigned int tr_max_tree_depth;
+ unsigned int max_tree_depth;
} TR_CFG_INTERNAL;
typedef struct tr_cfg {
TR_CFG_INTERNAL *internal; /* internal trust router config */
+ TR_IDP_REALM *idp_realms; /* locally associated IDP Realms */
+ TR_RP_CLIENT *rp_clients; /* locally associated RP Clients */
// TR_COMM *comms; /* locally-known communities */
- // TR_IDP_REALM *idp_realms; /* locally associated IDP Realms */
- // TR_RP_CLIENT *rp_clients; /* locally associated RP Clients */
/* TBD -- Global Filters */
/* TBD -- Trust Router Peers */
/* TBD -- Trust Links */
--- /dev/null
+/*
+ * Copyright (c) 2012, 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 TR_RP_H
+#define TR_RP_H
+
+#define TR_MAX_GSS_NAMES 5
+
+typedef struct tr_rp_client {
+ struct tr_rp_client *next;
+ // TR_FILTER *filters;
+ TR_NAME gss_name[TR_MAX_GSS_NAMES];
+} TR_RP_CLIENT;
+
+#endif
TR_EXPORT TR_NAME *tr_new_name (char *name);
TR_EXPORT TR_NAME *tr_dup_name (TR_NAME *from);
-
+TR_EXPORT void tr_free_name (TR_NAME *name);
+TR_EXPORT int tr_name_cmp (TR_NAME *one, TR_NAME *two);
#endif
exit(1);
}
+ // printf("Trust Router Configured, max_tree_depth = %d.\n", tr->active_cfg->internal->max_tree_depth);
+
/* initialize the trust path query server instance */
if (0 == (tids = tids_create ())) {
printf ("Error initializing Trust Path Query Server instance.\n");