libubus: refactor ubus_context msgbuf data to be dynamically allocated
This commit is contained in:
parent
3869e0ca07
commit
7e746e5a85
3 changed files with 40 additions and 15 deletions
20
libubus-io.c
20
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)
|
||||
|
|
22
libubus.c
22
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);
|
||||
}
|
||||
|
|
13
libubus.h
13
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 {
|
||||
|
|
Loading…
Reference in a new issue