/* n.b., conn is available here, but do not hold onto the reference
* because it may be cleaned up if the originating connection goes
* down before the message is processed */
- mq_msg=tr_mq_msg_new(tmp_ctx, TR_MQMSG_MSG_RECEIVED, TR_MQ_PRIO_NORMAL);
+ mq_msg= tr_mq_msg_new(tmp_ctx, TR_MQMSG_MSG_RECEIVED);
if (mq_msg==NULL) {
return TRP_NOMEM;
}
tr_debug("tr_trps_gss_handler()");
- if ((!client_name) || (!gss_name) || (!trps) || (!cfg_mgr)) {
+ if ((!client_name) || (!trps) || (!cfg_mgr)) {
tr_debug("tr_trps_gss_handler: Bad parameters.");
return -1;
}
if (trps_authorize_connection(trps, conn)!=TRP_SUCCESS)
goto cleanup;
- msg=tr_mq_msg_new(tmp_ctx, TR_MQMSG_TRPS_CONNECTED, TR_MQ_PRIO_HIGH);
+ msg= tr_mq_msg_new(tmp_ctx, TR_MQMSG_TRPS_CONNECTED);
tr_mq_msg_set_payload(msg, (void *)tr_dup_name(trp_connection_get_peer(conn)), tr_free_name_helper);
if (msg==NULL) {
tr_err("tr_trps_thread: error allocating TR_MQ_MSG");
trps_handle_connection(trps, conn);
cleanup:
- msg=tr_mq_msg_new(tmp_ctx, TR_MQMSG_TRPS_DISCONNECTED, TR_MQ_PRIO_HIGH);
+ msg= tr_mq_msg_new(tmp_ctx, TR_MQMSG_TRPS_DISCONNECTED);
tr_mq_msg_set_payload(msg, (void *)conn, NULL); /* do not pass a free routine */
if (msg==NULL)
tr_err("tr_trps_thread: error allocating TR_MQ_MSG");
name = talloc_asprintf(tmp_ctx, "trustrouter@%s", trps->hostname);
if (name == NULL)
goto cleanup;
- gssname=tr_new_name(name); /* name cleaned up with tmp_ctx */
+ gssname=tr_new_name(name); /* name cleaned up with tmp_ctx but need to handl gssname ourselves */
- conn=trp_connection_accept(tmp_ctx, listener, gssname);
- if (conn!=NULL) {
+ conn=trp_connection_accept(tmp_ctx, listener, gssname); /* steals gssname unless it fails */
+ if (conn == NULL) {
+ tr_free_name(gssname);
+ } else {
/* need to monitor this fd and trigger events when read becomes possible */
thread_data=talloc(conn, struct trps_thread_data);
if (thread_data==NULL) {
* a TR_MQMSG_ABORT message is received on trpc->mq, the thread sends a
* TR_MQMSG_TRPC_DISCONNECTED message to the trps thread, then cleans up and
* terminates.
+ *
+ * The trps may continue queueing messages for this client even when the
+ * connection is down. To prevent the queue from growing endlessly, this thread
+ * should clear its queue after failed connection attempts.
*/
static void *tr_trpc_thread(void *arg)
{
tr_notice("tr_trpc_thread: failed to initiate connection to %s:%d.",
trpc_get_server(trpc),
trpc_get_port(trpc));
+ trpc_mq_clear(trpc); /* clear the queue even though we did not connect */
} else {
/* Retrieve the GSS name used by the peer for authentication */
peer_gssname=trp_connection_get_peer(trpc_get_conn(trpc));
tr_debug("tr_trpc_thread: connected to peer %.*s",
peer_gssname->len, peer_gssname->buf);
- msg=tr_mq_msg_new(tmp_ctx, TR_MQMSG_TRPC_CONNECTED, TR_MQ_PRIO_HIGH);
+ msg= tr_mq_msg_new(tmp_ctx, TR_MQMSG_TRPC_CONNECTED);
tr_mq_msg_set_payload(msg, (void *)tr_dup_name(peer_gssname), tr_free_name_helper);
if (msg==NULL) {
tr_err("tr_trpc_thread: error allocating TR_MQ_MSG");
}
/* Send a DISCONNECTED message to the main thread */
- tr_debug("tr_trpc_thread: notifying main thread of disconnection.");
- msg=tr_mq_msg_new(tmp_ctx, TR_MQMSG_TRPC_DISCONNECTED, TR_MQ_PRIO_NORMAL);
+ msg= tr_mq_msg_new(tmp_ctx, TR_MQMSG_TRPC_DISCONNECTED);
tr_mq_msg_set_payload(msg, (void *)trpc, NULL); /* do not pass a free routine */
if (msg==NULL) {
/* can't notify main thread */
tr_debug("tr_config_changed: freeing tr->mons->authorized_gss_names");
tr_gss_names_free(tr->mons->authorized_gss_names);
}
- tr->mons->authorized_gss_names = tr_gss_names_dup(tr->mons, new_cfg->internal->monitoring_credentials);
+ if (new_cfg->internal->monitoring_credentials != NULL) {
+ tr->mons->authorized_gss_names = tr_gss_names_dup(tr->mons, new_cfg->internal->monitoring_credentials);
+ } else {
+ tr->mons->authorized_gss_names = tr_gss_names_new(tr->mons);
+ }
if (tr->mons->authorized_gss_names == NULL) {
tr_err("tr_config_changed: Error configuring monitoring credentials");
}