trp/trp_rtable.c \
trp/trp_req.c \
trp/trp_upd.c \
-tid/tid_resp.c \
-tid/tid_req.c \
-common/tr_gss.c \
common/tr_config.c \
-common/tr_idp.c \
-common/tr_apc.c \
-common/tr_comm.c \
-common/tr_filter.c \
-common/tr_rp.c \
-common/tr_msg.c \
-common/tr_constraint.c \
-common/tr_name.c \
common/tr_mq.c
check_PROGRAMS = common/t_constraint
TESTS = common/t_constraint
-lib_LTLIBRARIES = libtr_tid.la
+#lib_LTLIBRARIES = libtr_tid.la
-libtr_tid_la_SOURCES = $(tid_srcs) \
-$(common_srcs) \
-trp/trp_req.c \
-trp/trp_upd.c
-
-libtr_tid_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
-libtr_tid_la_LIBADD = gsscon/libgsscon.la $(GLIB_LIBS)
-libtr_tid_la_LDFLAGS = $(AM_LDFLAGS) -version-info 2 -no-undefined
+# libtr_tid_la_SOURCES = $(tid_srcs) \
+# $(common_srcs) \
+# trp/trp_req.c \
+# trp/trp_upd.c
+#
+# libtr_tid_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
+# libtr_tid_la_LIBADD = gsscon/libgsscon.la $(GLIB_LIBS)
+# libtr_tid_la_LDFLAGS = $(AM_LDFLAGS) -version-info 2 -no-undefined
common_t_constraint_SOURCES = common/t_constraint.c \
common/tr_debug.c \
tr/tr_cfgwatch.c \
tr/tr_tid.c \
tr/tr_trp.c \
-$(trp_srcs)
+$(tid_srcs) \
+$(trp_srcs) \
+$(common_srcs)
tr_trust_router_CFLAGS = $(AM_CFLAGS) -pthread
tr_trust_router_LDFLAGS = $(AM_LDFLAGS) -levent_pthreads -pthread
-tr_trust_router_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS)
+#tr_trust_router_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS)
+tr_trust_router_LDADD = gsscon/libgsscon.la $(GLIB_LIBS)
tr_trpc_SOURCES =tr/trpc_main.c \
tr/tr_trp.c \
common_tests_thread_test_CFLAGS = -pthread
common_tests_thread_test_LDFLAGS = $(AM_LDFLAGS) -ltalloc
-common_tests_commtest_SOURCES = common/tests/commtest.c \
-$(trp_srcs)
-common_tests_commtest_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS)
-common_tests_commtest_CFLAGS = -pthread
-common_test_commtest_LDFLAGS = $(AM_LDFLAGS) -ltalloc
+# common_tests_commtest_SOURCES = common/tests/commtest.c \
+# $(trp_srcs)
+# common_tests_commtest_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS)
+# common_tests_commtest_CFLAGS = -pthread
+# common_test_commtest_LDFLAGS = $(AM_LDFLAGS) -ltalloc
pkginclude_HEADERS = include/trust_router/tid.h include/trust_router/tr_name.h \
include/tr_debug.h \
return TR_ROLE_UNKNOWN;
}
+static void tr_comm_table_print_provenance(FILE *f, json_t *prov)
+{
+ const char *s=NULL;
+ size_t ii=0;
+
+ for (ii=0; ii<json_array_size(prov); ii++) {
+ s=json_string_value(json_array_get(prov, ii));
+ if (s!=NULL)
+ fprintf(f, "%s%s", s, ((ii+1)==json_array_size(prov))?"":", ");
+ }
+}
+
void tr_comm_table_print(FILE *f, TR_COMM_TABLE *ctab)
{
TR_COMM_MEMB *p1=NULL; /* for walking the main list */
fprintf(f, ">> Membership table start <<\n");
for (p1=ctab->memberships; p1!=NULL; p1=p1->next) {
- fprintf(f, "* %s %s/%s\n %s (%p)\n",
+ fprintf(f, "* %s %s/%s\n %s (%p) - prov: ",
tr_realm_role_to_str(tr_comm_memb_get_role(p1)),
tr_comm_memb_get_realm_id(p1)->buf,
tr_comm_get_id(tr_comm_memb_get_comm(p1))->buf,
(tr_comm_memb_get_origin(p1)==NULL)?"null origin":(tr_comm_memb_get_origin(p1)->buf),
p1);
+ tr_comm_table_print_provenance(f, p1->provenance);
+ fprintf(f, "\n");
for (p2=p1->origin_next; p2!=NULL; p2=p2->origin_next) {
- fprintf(f, " %s (%p)\n",
+ fprintf(f, " %s (%p) - prov: ",
(tr_comm_memb_get_origin(p2)==NULL)?"null origin":(tr_comm_memb_get_origin(p2)->buf),
p2);
+ tr_comm_table_print_provenance(f, p2->provenance);
+ fprintf(f, "\n");
}
fprintf(f, "\n");
}
{
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);
}
typedef struct trp_peer TRP_PEER;
struct trp_peer {
TRP_PEER *next; /* for making a linked list */
+ TR_NAME *label; /* often null, set on first call to trp_peer_get_label or dup_label */
char *server;
TR_GSS_NAMES *gss_names;
TR_NAME *servicename;
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_add_to_provenance(TRP_UPD *upd, TR_NAME *name);
/* Functions for TRP_REQ structures */
TR_EXPORT TRP_REQ *trp_req_new(TALLOC_CTX *mem_ctx);
.ai_protocol=IPPROTO_TCP};
char *port_str=NULL;
size_t n_opened=0;
-
+
+ tr_debug("tids_listen: started!");
port_str=talloc_asprintf(NULL, "%d", port);
if (port_str==NULL) {
tr_debug("tids_listen: unable to allocate port.");
return -1;
}
- getaddrinfo(NULL, port_str, &hints, &ai_head);
+ tr_debug("getaddrinfo()=%d", getaddrinfo(NULL, port_str, &hints, &ai_head));
talloc_free(port_str);
+ tr_debug("tids_listen: got address info");
/* TODO: listen on all ports */
for (ai=ai_head,n_opened=0; (ai!=NULL)&&(n_opened<max_fd); ai=ai->ai_next) {
/*tr_status_event_init();*/ /* install status reporting events */
/* install TID server events */
+ tr_debug("Initializing TID server events.");
if (0 != tr_tids_event_init(ev_base,
tr->tids,
tr->cfg_mgr,
}
/* install TRP handler events */
+ tr_debug("Initializing Dynamic Trust Router Protocol events.");
if (TRP_SUCCESS != tr_trps_event_init(ev_base, tr)) {
tr_crit("Error initializing Trust Path Query Server instance.");
return 1;
}
+ tr_debug("Starting event loop.");
tr_event_loop_run(ev_base); /* does not return until we are done */
tr_destroy(tr); /* thanks to talloc, should destroy everything */
{
TR_RESP_COOKIE *cookie=talloc_get_type_abort(resp_cookie, TR_RESP_COOKIE);
- tr_debug("tr_tidc_resp_handler: Response received! Realm = %s, Community = %s.",
+ tr_debug("tr_tidc_resp_handler: Response received! Realm = %s, Community = %s, result = %s.",
resp->realm->buf,
- resp->comm->buf);
-
+ resp->comm->buf,
+ (TID_SUCCESS==resp->result)?"success":"error");
+
+ if (resp->error_path!=NULL)
+ tr_debug("tr_tids_resp_handler: error_path is set.");
cookie->resp=tid_resp_dup(cookie, resp);
}
goto cleanup;
}
cookie->thread_id=args->thread_id;
+ tr_debug("tr_tids_req_fwd_thread: thread %d started.", cookie->thread_id);
/* Create a TID client instance */
if (tidc==NULL) {
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);
/* Send a TID request. */
if (0 > (rc = tidc_fwd_request(tidc, args->fwd_req, tr_tidc_resp_handler, (void *)cookie))) {
}
/* cookie->resp should now contain our copy of the response */
success=1;
+ tr_debug("tr_tids_req_fwd_thread: thread %d received response.");
cleanup:
/* Notify parent thread of the response, if it's still listening. */
if (0!=tr_tids_fwd_get_mutex(args)) {
- tr_notice("tr_tids_req_fwd_thread: Error acquiring mutex.");
+ tr_notice("tr_tids_req_fwd_thread: thread %d unable to acquire mutex.", cookie->thread_id);
} else if (NULL!=args->mq) {
/* mq is still valid, so we can queue our response */
+ tr_debug("tr_tids_req_fwd_thread: thread %d using valid msg queue.", cookie->thread_id);
if (success)
msg=tr_mq_msg_new(tmp_ctx, TR_TID_MQMSG_SUCCESS, TR_MQ_PRIO_NORMAL);
else
msg=tr_mq_msg_new(tmp_ctx, TR_TID_MQMSG_FAILURE, TR_MQ_PRIO_NORMAL);
if (msg==NULL)
- tr_notice("tr_tids_req_fwd_thread: unable to allocate response msg.");
+ tr_notice("tr_tids_req_fwd_thread: thread %d unable to allocate response msg.", cookie->thread_id);
tr_mq_msg_set_payload(msg, (void *)cookie, NULL);
if (NULL!=cookie)
talloc_steal(msg, cookie); /* attach this to the msg so we can forget about it */
tr_mq_add(args->mq, msg);
talloc_steal(NULL, args); /* take out of our tmp_ctx; master thread now responsible for freeing */
+ tr_debug("tr_tids_req_fwd_thread: thread %d queued response message.", cookie->thread_id);
if (0!=tr_tids_fwd_release_mutex(args))
tr_notice("tr_tids_req_fwd_thread: Error releasing mutex.");
}
}
/* send a TID request to the AAA server(s), and get the answer(s) */
+ tr_debug("tr_tids_req_handler: sending TID request(s).");
if (cfg_apc)
expiration_interval = cfg_apc->expiration_interval;
else expiration_interval = cfg_comm->expiration_interval;
retval=-1;
goto cleanup;
}
+ tr_debug("tr_tids_req_handler: message queue allocated.");
/* start threads */
aaa_iter=tr_aaa_server_iter_new(tmp_ctx);
for (n_aaa=0, this_aaa=tr_aaa_server_iter_first(aaa_iter, aaa_servers);
this_aaa!=NULL;
n_aaa++, this_aaa=tr_aaa_server_iter_next(aaa_iter)) {
+ tr_debug("tr_tids_req_handler: Preparing to start thread %d.", n_aaa);
+
aaa_cookie[n_aaa]=talloc(tmp_ctx, struct tr_tids_fwd_cookie);
if (aaa_cookie[n_aaa]==NULL) {
tr_notice("tr_tids_req_handler: unable to allocate cookie for AAA thread %d.", n_aaa);
aaa_cookie[n_aaa]->aaa_hostname=tr_dup_name(this_aaa->hostname);
aaa_cookie[n_aaa]->dh_params=tr_dh_dup(orig_req->tidc_dh);
aaa_cookie[n_aaa]->fwd_req=tid_dup_req(aaa_cookie[n_aaa], fwd_req);
+ tr_debug("tr_tids_req_handler: cookie %d initialized.", n_aaa);
/* Take the cookie out of tmp_ctx before starting thread. If thread starts, it becomes
- * responsible for freeing it until it queues a response. */
+ * responsible for freeing it until it queues a response. If we did not do this, the possibility
+ * exists that this function exits, freeing the cookie, before the thread takes the cookie
+ * out of our tmp_ctx. This would cause a segfault or talloc error in the thread. */
talloc_steal(NULL, aaa_cookie[n_aaa]);
if (0!=pthread_create(&(aaa_thread[n_aaa]), NULL, tr_tids_req_fwd_thread, aaa_cookie[n_aaa])) {
talloc_steal(tmp_ctx, aaa_cookie[n_aaa]); /* thread start failed; steal this back */
retval=-1;
goto cleanup;
}
+ tr_debug("tr_tids_req_handler: thread %d started.", n_aaa);
}
-
+
/* determine expiration time */
if (0!=tr_mq_pop_timeout(cfg_mgr->active->internal->tid_req_timeout, &ts_abort)) {
tr_notice("tr_tids_req_handler: unable to read clock for timeout.");
}
/* wait for responses */
+ tr_debug("tr_tids_req_handler: waiting for response(s).");
n_responses=0;
n_failed=0;
while (((n_responses+n_failed)<n_aaa) &&
/* process message */
if (0==strcmp(tr_mq_msg_get_message(msg), TR_TID_MQMSG_SUCCESS)) {
payload=talloc_get_type_abort(tr_mq_msg_get_payload(msg), TR_RESP_COOKIE);
+ talloc_steal(tmp_ctx, payload); /* put this back in our context */
aaa_resp[payload->thread_id]=payload->resp; /* save pointers to these */
if (payload->resp->result==TID_SUCCESS) {
/* failure */
n_failed++;
payload=talloc_get_type(tr_mq_msg_get_payload(msg), TR_RESP_COOKIE);
- if (payload==NULL) {
+ if (payload!=NULL)
+ talloc_steal(tmp_ctx, payload); /* put this back in our context */
+ else {
/* this means the thread was unable to allocate a response cookie, and we thus cannot determine which thread it was. This is bad and should never happen in a working system.. Give up. */
tr_notice("tr_tids_req_handler: TID request thread sent invalid reply. Aborting!");
retval=-1;
goto cleanup;
}
- /* Now free the cookie for this thread. Null it so we know we've dealt with it. */
- talloc_free(aaa_cookie[payload->thread_id]);
+ /* Set the cookie pointer to NULL so we know we've dealt with this one. The
+ * cookie itself is in our tmp_ctx, which we'll free before exiting. Let it hang
+ * around in case we are still using pointers to elements of the cookie. */
aaa_cookie[payload->thread_id]=NULL;
tr_mq_msg_free(msg);
break;
}
+ tr_debug("tr_tids_req_handler: done waiting for responses. %d responses, %d failures.",
+ n_responses, n_failed);
/* Inform any remaining threads that we will no longer handle their responses. */
for (ii=0; ii<n_aaa; ii++) {
if (aaa_cookie[ii]!=NULL) {
* reply (by setting their mq pointer to null). However, some may have responded by placing
* a message on the mq after we last checked but before we set their mq pointer to null. These
* will not know that we gave up on them, so we must free their cookies for them. We can just
- * go through any remaining messages on the mq to identify these threads. */
+ * go through any remaining messages on the mq to identify these threads. By putting them in
+ * our context instead of freeing them directly, we ensure we don't accidentally invalidate
+ * any of our own pointers into the structure before this function exits. */
while (NULL!=(msg=tr_mq_pop(mq, NULL))) {
payload=(TR_RESP_COOKIE *)tr_mq_msg_get_payload(msg);
if (aaa_cookie[payload->thread_id]!=NULL)
- talloc_free(aaa_cookie[payload->thread_id]);
+ talloc_steal(tmp_ctx, aaa_cookie[payload->thread_id]);
tr_mq_msg_free(msg);
}
static int trp_peer_destructor(void *object)
{
TRP_PEER *peer=talloc_get_type_abort(object, TRP_PEER);
+ if (peer->label!=NULL)
+ tr_free_name(peer->label);
if (peer->servicename!=NULL)
tr_free_name(peer->servicename);
return 0;
TRP_PEER *peer=talloc(memctx, TRP_PEER);
if (peer!=NULL) {
peer->next=NULL;
+ peer->label=NULL;
peer->server=NULL;
peer->servicename=NULL;
peer->gss_names=NULL;
* Do not modify or free the label. */
TR_NAME *trp_peer_get_label(TRP_PEER *peer)
{
- TR_GSS_NAMES_ITER *iter=tr_gss_names_iter_new(NULL);
- TR_NAME *name=NULL;
+ char *s=NULL;
- /* for now, use the first gss name */
- if (iter!=NULL) {
- name=tr_gss_names_iter_first(iter, peer->gss_names);
- talloc_free(iter);
+ if (peer->label==NULL) {
+ s=talloc_asprintf(NULL, "%s:%u", peer->server, peer->port);
+ if (s!=NULL) {
+ peer->label=tr_new_name(s);
+ talloc_free(s);
+ }
}
- return name;
+ return peer->label;
}
/* Get a name that identifies this peer for display to the user, etc.
return TRP_ERROR;
}
-static TRP_RC trp_inforec_add_to_provenance(TRP_INFOREC *rec, TR_NAME *peer)
+static TRP_RC trp_inforec_add_to_provenance(TRP_INFOREC *rec, TR_NAME *name)
{
- json_t *jpeer=NULL;
+ json_t *jname=NULL;
switch (rec->type) {
case TRP_INFOREC_TYPE_ROUTE:
/* no provenance list */
break;
case TRP_INFOREC_TYPE_COMMUNITY:
- jpeer=tr_name_to_json_string(peer);
- if (jpeer==NULL)
+ jname=tr_name_to_json_string(name);
+ if (jname==NULL)
return TRP_ERROR;
if (rec->data->comm->provenance==NULL) {
rec->data->comm->provenance=json_array();
if (rec->data->comm->provenance==NULL) {
- json_decref(jpeer);
+ json_decref(jname);
return TRP_ERROR;
}
}
- if (0!=json_array_append_new(rec->data->comm->provenance, jpeer)) {
- json_decref(jpeer);
+ if (0!=json_array_append_new(rec->data->comm->provenance, jname)) {
+ json_decref(jname);
return TRP_ERROR;
}
break;
void trp_upd_set_peer(TRP_UPD *upd, TR_NAME *peer)
{
- TRP_INFOREC *rec=NULL;
- TR_NAME *cpy=NULL;
-
upd->peer=peer;
-
- /* add to provenance list of any records that need it */
- for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
- if (trp_inforec_add_to_provenance(rec, cpy=tr_dup_name(peer)) != TRP_SUCCESS) {
- tr_err("trp_upd_set_peer: error adding peer to provenance list.");
- tr_free_name(cpy);
- }
- }
}
void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port)
}
}
+void trp_upd_add_to_provenance(TRP_UPD *upd, TR_NAME *name)
+{
+ TRP_INFOREC *rec=NULL;
+
+ /* add it to all inforecs */
+ for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
+ if (TRP_SUCCESS!=trp_inforec_add_to_provenance(rec, name))
+ tr_err("trp_upd_set_peer: error adding peer to provenance list.");
+ }
+}
+
/* pretty print */
static void trp_inforec_route_print(TRP_INFOREC_DATA *data)
{
void trps_set_ptable(TRPS_INSTANCE *trps, TRP_PTABLE *ptable)
{
+ if (trps->ptable!=NULL)
+ trp_ptable_free(trps->ptable);
trps->ptable=ptable;
}
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;
case TRP_REQUEST:
tr_debug("trps_handle_update: handling community inforec.");
if (TRP_SUCCESS!=trps_handle_inforec_comm(trps, upd, rec))
tr_notice("trps_handle_update: error handling community inforec.");
+ else
+ tr_comm_table_print(stdout, trps->ctable); /* for debugging TODO remove */
+
break;
default:
tr_notice("trps_handle_update: unsupported inforec in TRP update.");