From 7e746e5a850b1c5ef87b8d8538e921f2051f5471 Mon Sep 17 00:00:00 2001 From: Alexandru Ardelean Date: Fri, 27 Jun 2014 19:11:39 +0300 Subject: [PATCH] libubus: refactor ubus_context msgbuf data to be dynamically allocated --- libubus-io.c | 20 +++++++++++++++----- libubus.c | 22 +++++++++++++++++----- libubus.h | 13 ++++++++----- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/libubus-io.c b/libubus-io.c index 9a6c7cd..c63a920 100644 --- a/libubus-io.c +++ b/libubus-io.c @@ -212,7 +212,7 @@ static int recv_retry(int fd, struct iovec *iov, bool wait, int *recv_fd) static bool ubus_validate_hdr(struct ubus_msghdr *hdr) { - struct blob_attr *data = ubus_msghdr_data(hdr); + struct blob_attr *data = (struct blob_attr *) (hdr + 1); if (hdr->version != 0) return false; @@ -228,11 +228,14 @@ static bool ubus_validate_hdr(struct ubus_msghdr *hdr) static bool get_next_msg(struct ubus_context *ctx, int *recv_fd) { - struct iovec iov = STATIC_IOV(ctx->msgbuf.hdr); + struct { + struct ubus_msghdr hdr; + struct blob_attr data; + } hdrbuf; + struct iovec iov = STATIC_IOV(hdrbuf); int r; /* receive header + start attribute */ - iov.iov_len += sizeof(struct blob_attr); r = recv_retry(ctx->sock.fd, &iov, false, recv_fd); if (r <= 0) { if (r < 0) @@ -241,11 +244,18 @@ static bool get_next_msg(struct ubus_context *ctx, int *recv_fd) return false; } - iov.iov_len = blob_len(ubus_msghdr_data(&ctx->msgbuf.hdr)); + if (!ubus_validate_hdr(&hdrbuf.hdr)) + return false; + + memcpy(&ctx->msgbuf.hdr, &hdrbuf.hdr, sizeof(hdrbuf.hdr)); + memcpy(ctx->msgbuf.data, &hdrbuf.data, sizeof(hdrbuf.data)); + + iov.iov_base = (char *)ctx->msgbuf.data + sizeof(hdrbuf.data); + iov.iov_len = blob_len(ctx->msgbuf.data); if (iov.iov_len > 0 && !recv_retry(ctx->sock.fd, &iov, true, NULL)) return false; - return ubus_validate_hdr(&ctx->msgbuf.hdr); + return true; } void __hidden ubus_handle_data(struct uloop_fd *u, unsigned int events) diff --git a/libubus.c b/libubus.c index 1a550c1..83a2c43 100644 --- a/libubus.c +++ b/libubus.c @@ -40,7 +40,7 @@ struct blob_buf b __hidden = {}; struct ubus_pending_msg { struct list_head list; - struct ubus_msghdr hdr; + struct ubus_msghdr_buf hdr; }; static int ubus_cmp_id(const void *k1, const void *k2, void *ptr) @@ -75,11 +75,15 @@ ubus_queue_msg(struct ubus_context *ctx, struct ubus_msghdr *hdr) { struct ubus_pending_msg *pending; - pending = calloc(1, sizeof(*pending) + blob_raw_len(ubus_msghdr_data(hdr))); + pending = calloc(1, sizeof(*pending)); if (!pending) return; + pending->hdr.data = calloc(1, blob_raw_len(ubus_msghdr_data(hdr))); + if (!pending->hdr.data) + return; - memcpy(&pending->hdr, hdr, sizeof(*hdr) + blob_raw_len(ubus_msghdr_data(hdr))); + memcpy(&pending->hdr.hdr, hdr, sizeof(*hdr)); + memcpy(pending->hdr.data, ubus_msghdr_data(hdr), blob_raw_len(ubus_msghdr_data(hdr))); list_add(&pending->list, &ctx->pending); if (ctx->sock.registered) uloop_timeout_set(&ctx->pending_timer, 1); @@ -116,7 +120,8 @@ static void ubus_process_pending_msg(struct uloop_timeout *timeout) while (!ctx->stack_depth && !list_empty(&ctx->pending)) { pending = list_first_entry(&ctx->pending, struct ubus_pending_msg, list); list_del(&pending->list); - ubus_process_msg(ctx, &pending->hdr, -1); + ubus_process_msg(ctx, &pending->hdr.hdr, -1); + free(pending->hdr.data); free(pending); } } @@ -275,11 +280,17 @@ static int _ubus_connect(struct ubus_context *ctx, const char *path) ctx->connection_lost = ubus_default_connection_lost; ctx->pending_timer.cb = ubus_process_pending_msg; + ctx->msgbuf.data = calloc(UBUS_MAX_MSGLEN, sizeof(char)); + if (!ctx->msgbuf.data) + return -1; + INIT_LIST_HEAD(&ctx->requests); INIT_LIST_HEAD(&ctx->pending); avl_init(&ctx->objects, ubus_cmp_id, false, NULL); - if (ubus_reconnect(ctx, path)) + if (ubus_reconnect(ctx, path)) { + free(ctx->msgbuf.data); return -1; + } return 0; } @@ -343,5 +354,6 @@ void ubus_free(struct ubus_context *ctx) { blob_buf_free(&b); close(ctx->sock.fd); + free(ctx->msgbuf.data); free(ctx); } diff --git a/libubus.h b/libubus.h index 6c560b4..33a99aa 100644 --- a/libubus.h +++ b/libubus.h @@ -34,10 +34,16 @@ struct ubus_event_handler; struct ubus_subscriber; struct ubus_notify_request; +struct ubus_msghdr_buf { + struct ubus_msghdr hdr; + struct blob_attr *data; +}; + static inline struct blob_attr * ubus_msghdr_data(struct ubus_msghdr *hdr) { - return (struct blob_attr *) (hdr + 1); + struct ubus_msghdr_buf *hdrbuf = container_of(hdr, typeof(*hdrbuf), hdr); + return hdrbuf->data; } typedef void (*ubus_lookup_handler_t)(struct ubus_context *ctx, @@ -148,10 +154,7 @@ struct ubus_context { void (*connection_lost)(struct ubus_context *ctx); - struct { - struct ubus_msghdr hdr; - char data[UBUS_MAX_MSGLEN]; - } msgbuf; + struct ubus_msghdr_buf msgbuf; }; struct ubus_object_data {