X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=mon%2Fmons.c;h=82495ee3b2c60df951bc0495ab5bdbf97d020fa0;hb=1a106110e5e7f214ea60e7787d02c5565e7193f0;hp=29f405b5ba4c9a50be85a5b117dc86ac829da96d;hpb=1a3ad555c6b58de28efb85e7ab07c2f35208ab0d;p=trust_router.git diff --git a/mon/mons.c b/mon/mons.c index 29f405b..82495ee 100644 --- a/mon/mons.c +++ b/mon/mons.c @@ -42,6 +42,18 @@ #include #include #include +#include + +#include "mons_handlers.h" + +static int mons_destructor(void *object) +{ + MONS_INSTANCE *mons = talloc_get_type_abort(object, MONS_INSTANCE); + if (mons->handlers) { + g_ptr_array_unref(mons->handlers); + } + return 0; +} /** * Allocate a new MONS_INSTANCE @@ -54,20 +66,89 @@ MONS_INSTANCE *mons_new(TALLOC_CTX *mem_ctx) MONS_INSTANCE *mons = talloc(mem_ctx, MONS_INSTANCE); if (mons) { + mons->hostname = NULL; mons->port = 0; + mons->tids = NULL; + mons->trps = NULL; mons->req_handler = NULL; mons->auth_handler = NULL; mons->cookie = NULL; + + /* Before any steps that may fail, install the destructor */ + talloc_set_destructor((void *)mons, mons_destructor); + mons->authorized_gss_names = tr_gss_names_new(mons); if (mons->authorized_gss_names == NULL) { talloc_free(mons); - mons = NULL; + return NULL; + } + + mons->handlers = g_ptr_array_new(); + if (mons->handlers == NULL) { + talloc_free(mons); + return NULL; } } return mons; } /** + * Callback to process a request and produce a response + * + * @param req_str JSON-encoded request + * @param data pointer to a MONS_INSTANCE + * @return pointer to the response string or null to send no response + */ +static TR_MSG *mons_req_cb(TALLOC_CTX *mem_ctx, TR_MSG *req_msg, void *data) +{ + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + MONS_INSTANCE *mons = talloc_get_type_abort(data, MONS_INSTANCE); + MON_REQ *req = NULL; + MON_RESP *resp = NULL; + TR_MSG *resp_msg = NULL; /* This is the response value */ + + /* Validate inputs */ + if (req_msg == NULL) + goto cleanup; + + req = tr_msg_get_mon_req(req_msg); + if (req == NULL) { + /* this is an internal error */ + tr_err("mons_req_cb: Received incorrect message type (was %d, expected %d)", + tr_msg_get_msg_type(req_msg), + MON_REQUEST); + /* TODO send an error response */ + goto cleanup; + } + + /* Allocate a response message */ + resp_msg = talloc(tmp_ctx, TR_MSG); + if (resp_msg == NULL) { + /* can't return a message, just emit an error */ + tr_crit("mons_req_cb: Error allocating response message."); + goto cleanup; + } + + /* Handle the request */ + resp = mons_handle_request(resp_msg, mons, req); + if (resp == NULL) { + /* error processing the request */ + /* TODO send back an error */ + goto cleanup; + } + + /* Set the response message payload */ + tr_msg_set_mon_resp(resp_msg, resp); + + /* Put the response message in the caller's context so it does not get freed when we exit */ + talloc_steal(mem_ctx, resp_msg); + +cleanup: + talloc_free(tmp_ctx); + return resp_msg; +} + +/** * Create a listener for monitoring requests * * Accept connections with mons_accept() @@ -82,13 +163,8 @@ MONS_INSTANCE *mons_new(TALLOC_CTX *mem_ctx) * @param max_fd * @return */ -int mons_get_listener(MONS_INSTANCE *mons, - MONS_REQ_FUNC *req_handler, - MONS_AUTH_FUNC *auth_handler, - 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, + unsigned int port, void *cookie, int *fd_out, size_t max_fd) { size_t n_fd=0; size_t ii=0; @@ -119,6 +195,7 @@ int mons_get_listener(MONS_INSTANCE *mons, /* store the caller's request handler & cookie */ mons->req_handler = req_handler; mons->auth_handler = auth_handler; + mons->hostname = hostname; mons->cookie = cookie; } @@ -149,7 +226,11 @@ int mons_accept(MONS_INSTANCE *mons, int listen) if (pid == 0) { close(listen); - mons_handle_connection(mons, conn); + tr_gss_handle_connection(conn, + "trustmonitor", mons->hostname, /* acceptor name */ + mons->auth_handler, mons->cookie, /* auth callback and cookie */ + mons_req_cb, mons /* req callback and cookie */ + ); close(conn); exit(0); /* exit to kill forked child process */ } else { @@ -157,7 +238,7 @@ int mons_accept(MONS_INSTANCE *mons, int listen) } /* clean up any processes that have completed */ - while (waitpid(-1, 0, WNOHANG) > 0); + //while (waitpid(-1, 0, WNOHANG) > 0); TODO: only clean up our own pids return 0; }