s4-messaging: fixed a memory leak in messaging_path()
[ira/wip.git] / source4 / lib / messaging / messaging.c
index 19284461ee4d11649ca2d6cbd57e0773cbbbab8e..d4dfff7c8ccc23e8118b6b0570b56c0a608ec8cd 100644 (file)
 #include "lib/events/events.h"
 #include "system/filesys.h"
 #include "messaging/messaging.h"
-#include "lib/util/dlinklist.h"
+#include "../lib/util/dlinklist.h"
 #include "lib/socket/socket.h"
 #include "librpc/gen_ndr/ndr_irpc.h"
 #include "lib/messaging/irpc.h"
 #include "tdb_wrap.h"
-#include "lib/util/unix_privs.h"
+#include "../lib/util/unix_privs.h"
 #include "librpc/rpc/dcerpc.h"
-#include "lib/tdb/include/tdb.h"
-#include "lib/util/util_tdb.h"
-#include "lib/util/util_tdb.h"
+#include "../tdb/include/tdb.h"
+#include "../lib/util/util_tdb.h"
 #include "cluster/cluster.h"
-#include "param/param.h"
 
 /* change the message version with any incompatible changes in the protocol */
 #define MESSAGING_VERSION 1
@@ -54,10 +52,10 @@ struct messaging_context {
        struct idr_context *idr;
        const char **names;
        struct timeval start_time;
-       struct timed_event *retry_te;
+       struct tevent_timer *retry_te;
        struct {
-               struct event_context *ev;
-               struct fd_event *fde;
+               struct tevent_context *ev;
+               struct tevent_fd *fde;
        } event;
 };
 
@@ -66,7 +64,7 @@ struct messaging_context {
 struct dispatch_fn {
        struct dispatch_fn *next, *prev;
        uint32_t msg_type;
-       void *private;
+       void *private_data;
        msg_callback_t fn;
 };
 
@@ -96,7 +94,7 @@ static void irpc_handler(struct messaging_context *, void *,
 /*
  A useful function for testing the message system.
 */
-static void ping_message(struct messaging_context *msg, void *private
+static void ping_message(struct messaging_context *msg, void *private_data,
                         uint32_t msg_type, struct server_id src, DATA_BLOB *data)
 {
        DEBUG(1,("INFO: Received PING message from server %u.%u [%.*s]\n",
@@ -111,7 +109,7 @@ static void ping_message(struct messaging_context *msg, void *private,
 static NTSTATUS irpc_uptime(struct irpc_message *msg, 
                            struct irpc_uptime *r)
 {
-       struct messaging_context *ctx = talloc_get_type(msg->private, struct messaging_context);
+       struct messaging_context *ctx = talloc_get_type(msg->private_data, struct messaging_context);
        *r->out.start_time = timeval_to_nttime(&ctx->start_time);
        return NT_STATUS_OK;
 }
@@ -121,8 +119,15 @@ static NTSTATUS irpc_uptime(struct irpc_message *msg,
 */
 static char *messaging_path(struct messaging_context *msg, struct server_id server_id)
 {
-       return talloc_asprintf(msg, "%s/msg.%s", msg->base_path, 
-                              cluster_id_string(msg, server_id));
+       TALLOC_CTX *tmp_ctx = talloc_new(msg);
+       const char *id = cluster_id_string(tmp_ctx, server_id);
+       char *s;
+       if (id == NULL) {
+               return NULL;
+       }
+       s = talloc_asprintf(msg, "%s/msg.%s", msg->base_path, id);
+       talloc_steal(s, tmp_ctx);
+       return s;
 }
 
 /*
@@ -151,7 +156,7 @@ static void messaging_dispatch(struct messaging_context *msg, struct messaging_r
                next = d->next;
                data.data = rec->packet.data + sizeof(*rec->header);
                data.length = rec->header->length;
-               d->fn(msg, d->private, d->msg_type, rec->header->from, &data);
+               d->fn(msg, d->private_data, d->msg_type, rec->header->from, &data);
        }
        rec->header->length = 0;
 }
@@ -218,10 +223,10 @@ static NTSTATUS try_send(struct messaging_rec *rec)
 /*
   retry backed off messages
 */
-static void msg_retry_timer(struct event_context *ev, struct timed_event *te, 
-                           struct timeval t, void *private)
+static void msg_retry_timer(struct tevent_context *ev, struct tevent_timer *te, 
+                           struct timeval t, void *private_data)
 {
-       struct messaging_context *msg = talloc_get_type(private
+       struct messaging_context *msg = talloc_get_type(private_data,
                                                        struct messaging_context);
        msg->retry_te = NULL;
 
@@ -340,10 +345,10 @@ static void messaging_recv_handler(struct messaging_context *msg)
 /*
   handle a socket event
 */
-static void messaging_handler(struct event_context *ev, struct fd_event *fde, 
-                             uint16_t flags, void *private)
+static void messaging_handler(struct tevent_context *ev, struct tevent_fd *fde, 
+                             uint16_t flags, void *private_data)
 {
-       struct messaging_context *msg = talloc_get_type(private
+       struct messaging_context *msg = talloc_get_type(private_data,
                                                        struct messaging_context);
        if (flags & EVENT_FD_WRITE) {
                messaging_send_handler(msg);
@@ -357,7 +362,7 @@ static void messaging_handler(struct event_context *ev, struct fd_event *fde,
 /*
   Register a dispatch function for a particular message type.
 */
-NTSTATUS messaging_register(struct messaging_context *msg, void *private,
+NTSTATUS messaging_register(struct messaging_context *msg, void *private_data,
                            uint32_t msg_type, msg_callback_t fn)
 {
        struct dispatch_fn *d;
@@ -378,7 +383,7 @@ NTSTATUS messaging_register(struct messaging_context *msg, void *private,
        d = talloc_zero(msg->dispatch, struct dispatch_fn);
        NT_STATUS_HAVE_NO_MEMORY(d);
        d->msg_type = msg_type;
-       d->private = private;
+       d->private_data = private_data;
        d->fn = fn;
 
        DLIST_ADD(msg->dispatch[msg_type], d);
@@ -390,7 +395,7 @@ NTSTATUS messaging_register(struct messaging_context *msg, void *private,
   register a temporary message handler. The msg_type is allocated
   above MSG_TMP_BASE
 */
-NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private,
+NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private_data,
                                msg_callback_t fn, uint32_t *msg_type)
 {
        struct dispatch_fn *d;
@@ -398,7 +403,7 @@ NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private,
 
        d = talloc_zero(msg->dispatch, struct dispatch_fn);
        NT_STATUS_HAVE_NO_MEMORY(d);
-       d->private = private;
+       d->private_data = private_data;
        d->fn = fn;
 
        id = idr_get_new_above(msg->dispatch_tree, d, MSG_TMP_BASE, UINT16_MAX);
@@ -416,7 +421,7 @@ NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private,
 /*
   De-register the function for a particular message type.
 */
-void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void *private)
+void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void *private_data)
 {
        struct dispatch_fn *d, *next;
 
@@ -431,7 +436,7 @@ void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void
 
        for (d = msg->dispatch[msg_type]; d; d = next) {
                next = d->next;
-               if (d->private == private) {
+               if (d->private_data == private_data) {
                        DLIST_REMOVE(msg->dispatch[msg_type], d);
                        talloc_free(d);
                }
@@ -538,7 +543,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
                                         const char *dir,
                                         struct server_id server_id, 
                                         struct smb_iconv_convenience *iconv_convenience,
-                                        struct event_context *ev)
+                                        struct tevent_context *ev)
 {
        struct messaging_context *msg;
        NTSTATUS status;
@@ -598,7 +603,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
        /* it needs to be non blocking for sends */
        set_blocking(socket_get_fd(msg->sock), false);
 
-       msg->event.ev   = talloc_reference(msg, ev);
+       msg->event.ev   = ev;
        msg->event.fde  = event_add_fd(ev, msg, socket_get_fd(msg->sock), 
                                       EVENT_FD_READ, messaging_handler, msg);
 
@@ -617,7 +622,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
 struct messaging_context *messaging_client_init(TALLOC_CTX *mem_ctx, 
                                                const char *dir,
                                                struct smb_iconv_convenience *iconv_convenience,
-                                               struct event_context *ev)
+                                               struct tevent_context *ev)
 {
        struct server_id id;
        ZERO_STRUCT(id);
@@ -633,7 +638,7 @@ struct irpc_list {
        const struct ndr_interface_table *table;
        int callnum;
        irpc_function_t fn;
-       void *private;
+       void *private_data;
 };
 
 
@@ -642,7 +647,7 @@ struct irpc_list {
 */
 NTSTATUS irpc_register(struct messaging_context *msg_ctx, 
                       const struct ndr_interface_table *table, 
-                      int callnum, irpc_function_t fn, void *private)
+                      int callnum, irpc_function_t fn, void *private_data)
 {
        struct irpc_list *irpc;
 
@@ -661,7 +666,7 @@ NTSTATUS irpc_register(struct messaging_context *msg_ctx,
        irpc->table   = table;
        irpc->callnum = callnum;
        irpc->fn      = fn;
-       irpc->private = private;
+       irpc->private_data = private_data;
        irpc->uuid = irpc->table->syntax_id.uuid;
 
        return NT_STATUS_OK;
@@ -770,7 +775,7 @@ static void irpc_handler_request(struct messaging_context *msg_ctx,
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) goto failed;
 
        /* make the call */
-       m->private     = i->private;
+       m->private_data= i->private_data;
        m->defer_reply = false;
        m->msg_ctx     = msg_ctx;
        m->irpc        = i;
@@ -795,7 +800,7 @@ failed:
 /*
   handle an incoming irpc message
 */
-static void irpc_handler(struct messaging_context *msg_ctx, void *private
+static void irpc_handler(struct messaging_context *msg_ctx, void *private_data,
                         uint32_t msg_type, struct server_id src, DATA_BLOB *packet)
 {
        struct irpc_message *m;
@@ -845,10 +850,10 @@ static int irpc_destructor(struct irpc_request *irpc)
 /*
   timeout a irpc request
 */
-static void irpc_timeout(struct event_context *ev, struct timed_event *te, 
-                        struct timeval t, void *private)
+static void irpc_timeout(struct tevent_context *ev, struct tevent_timer *te, 
+                        struct timeval t, void *private_data)
 {
-       struct irpc_request *irpc = talloc_get_type(private, struct irpc_request);
+       struct irpc_request *irpc = talloc_get_type(private_data, struct irpc_request);
        irpc->status = NT_STATUS_IO_TIMEOUT;
        irpc->done = true;
        if (irpc->async.fn) {
@@ -1085,8 +1090,14 @@ void irpc_remove_name(struct messaging_context *msg_ctx, const char *name)
                return;
        }
        rec = tdb_fetch_bystring(t->tdb, name);
+       if (rec.dptr == NULL) {
+               tdb_unlock_bystring(t->tdb, name);
+               talloc_free(t);
+               return;
+       }
        count = rec.dsize / sizeof(struct server_id);
        if (count == 0) {
+               free(rec.dptr);
                tdb_unlock_bystring(t->tdb, name);
                talloc_free(t);
                return;
@@ -1107,3 +1118,8 @@ void irpc_remove_name(struct messaging_context *msg_ctx, const char *name)
        tdb_unlock_bystring(t->tdb, name);
        talloc_free(t);
 }
+
+struct server_id messaging_get_server_id(struct messaging_context *msg_ctx)
+{
+       return msg_ctx->server_id;
+}