update imsg

This commit is contained in:
Omar Polo 2023-07-02 08:55:38 +00:00
parent 71b02f6390
commit c9c44c6571
3 changed files with 275 additions and 46 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: imsg-buffer.c,v 1.13 2021/03/31 17:42:24 eric Exp $ */
/* $OpenBSD: imsg-buffer.c,v 1.16 2023/06/19 17:19:50 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -33,15 +33,20 @@
static int ibuf_realloc(struct ibuf *, size_t);
static void ibuf_enqueue(struct msgbuf *, struct ibuf *);
static void ibuf_dequeue(struct msgbuf *, struct ibuf *);
static void msgbuf_drain(struct msgbuf *, size_t);
struct ibuf *
ibuf_open(size_t len)
{
struct ibuf *buf;
if (len == 0) {
errno = EINVAL;
return (NULL);
}
if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
return (NULL);
if ((buf->buf = malloc(len)) == NULL) {
if ((buf->buf = calloc(len, 1)) == NULL) {
free(buf);
return (NULL);
}
@ -56,14 +61,22 @@ ibuf_dynamic(size_t len, size_t max)
{
struct ibuf *buf;
if (max < len)
if (max < len) {
errno = EINVAL;
return (NULL);
}
if ((buf = ibuf_open(len)) == NULL)
if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
return (NULL);
if (max > 0)
buf->max = max;
if (len > 0) {
if ((buf->buf = calloc(len, 1)) == NULL) {
free(buf);
return (NULL);
}
}
buf->size = len;
buf->max = max;
buf->fd = -1;
return (buf);
}
@ -74,7 +87,7 @@ ibuf_realloc(struct ibuf *buf, size_t len)
unsigned char *b;
/* on static buffers max is eq size and so the following fails */
if (buf->wpos + len > buf->max) {
if (len > SIZE_MAX - buf->wpos || buf->wpos + len > buf->max) {
errno = ERANGE;
return (-1);
}
@ -88,42 +101,176 @@ ibuf_realloc(struct ibuf *buf, size_t len)
return (0);
}
int
ibuf_add(struct ibuf *buf, const void *data, size_t len)
{
if (buf->wpos + len > buf->size)
if (ibuf_realloc(buf, len) == -1)
return (-1);
memcpy(buf->buf + buf->wpos, data, len);
buf->wpos += len;
return (0);
}
void *
ibuf_reserve(struct ibuf *buf, size_t len)
{
void *b;
if (len > SIZE_MAX - buf->wpos) {
errno = ERANGE;
return (NULL);
}
if (buf->wpos + len > buf->size)
if (ibuf_realloc(buf, len) == -1)
return (NULL);
b = buf->buf + buf->wpos;
buf->wpos += len;
memset(b, 0, len);
return (b);
}
int
ibuf_add(struct ibuf *buf, const void *data, size_t len)
{
void *b;
if ((b = ibuf_reserve(buf, len)) == NULL)
return (-1);
memcpy(b, data, len);
return (0);
}
int
ibuf_add_buf(struct ibuf *buf, const struct ibuf *from)
{
return ibuf_add(buf, from->buf, from->wpos);
}
int
ibuf_add_n8(struct ibuf *buf, uint64_t value)
{
uint8_t v;
if (value > UINT8_MAX) {
errno = EINVAL;
return (-1);
}
v = value;
return ibuf_add(buf, &v, sizeof(v));
}
int
ibuf_add_n16(struct ibuf *buf, uint64_t value)
{
uint16_t v;
if (value > UINT16_MAX) {
errno = EINVAL;
return (-1);
}
v = htobe16(value);
return ibuf_add(buf, &v, sizeof(v));
}
int
ibuf_add_n32(struct ibuf *buf, uint64_t value)
{
uint32_t v;
if (value > UINT32_MAX) {
errno = EINVAL;
return (-1);
}
v = htobe32(value);
return ibuf_add(buf, &v, sizeof(v));
}
int
ibuf_add_n64(struct ibuf *buf, uint64_t value)
{
value = htobe64(value);
return ibuf_add(buf, &value, sizeof(value));
}
int
ibuf_add_zero(struct ibuf *buf, size_t len)
{
void *b;
if ((b = ibuf_reserve(buf, len)) == NULL)
return (-1);
return (0);
}
void *
ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
{
/* only allowed to seek in already written parts */
if (pos + len > buf->wpos)
if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
errno = ERANGE;
return (NULL);
}
return (buf->buf + pos);
}
int
ibuf_set(struct ibuf *buf, size_t pos, const void *data, size_t len)
{
void *b;
if ((b = ibuf_seek(buf, pos, len)) == NULL)
return (-1);
memcpy(b, data, len);
return (0);
}
int
ibuf_set_n8(struct ibuf *buf, size_t pos, uint64_t value)
{
uint8_t v;
if (value > UINT8_MAX) {
errno = EINVAL;
return (-1);
}
v = value;
return (ibuf_set(buf, pos, &v, sizeof(v)));
}
int
ibuf_set_n16(struct ibuf *buf, size_t pos, uint64_t value)
{
uint16_t v;
if (value > UINT16_MAX) {
errno = EINVAL;
return (-1);
}
v = htobe16(value);
return (ibuf_set(buf, pos, &v, sizeof(v)));
}
int
ibuf_set_n32(struct ibuf *buf, size_t pos, uint64_t value)
{
uint32_t v;
if (value > UINT32_MAX) {
errno = EINVAL;
return (-1);
}
v = htobe32(value);
return (ibuf_set(buf, pos, &v, sizeof(v)));
}
int
ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value)
{
value = htobe64(value);
return (ibuf_set(buf, pos, &value, sizeof(value)));
}
void *
ibuf_data(struct ibuf *buf)
{
return (buf->buf);
}
size_t
ibuf_size(struct ibuf *buf)
{
@ -142,6 +289,45 @@ ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
ibuf_enqueue(msgbuf, buf);
}
void
ibuf_free(struct ibuf *buf)
{
if (buf == NULL)
return;
#ifdef NOTYET
if (buf->fd != -1)
close(buf->fd);
#endif
freezero(buf->buf, buf->size);
free(buf);
}
int
ibuf_fd_avail(struct ibuf *buf)
{
return (buf->fd != -1);
}
int
ibuf_fd_get(struct ibuf *buf)
{
int fd;
fd = buf->fd;
#ifdef NOTYET
buf->fd = -1;
#endif
return (fd);
}
void
ibuf_fd_set(struct ibuf *buf, int fd)
{
if (buf->fd != -1)
close(buf->fd);
buf->fd = fd;
}
int
ibuf_write(struct msgbuf *msgbuf)
{
@ -178,15 +364,6 @@ again:
return (1);
}
void
ibuf_free(struct ibuf *buf)
{
if (buf == NULL)
return;
freezero(buf->buf, buf->size);
free(buf);
}
void
msgbuf_init(struct msgbuf *msgbuf)
{
@ -195,7 +372,7 @@ msgbuf_init(struct msgbuf *msgbuf)
TAILQ_INIT(&msgbuf->bufs);
}
void
static void
msgbuf_drain(struct msgbuf *msgbuf, size_t n)
{
struct ibuf *buf, *next;
@ -203,7 +380,7 @@ msgbuf_drain(struct msgbuf *msgbuf, size_t n)
for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
buf = next) {
next = TAILQ_NEXT(buf, entry);
if (buf->rpos + n >= buf->wpos) {
if (n >= buf->wpos - buf->rpos) {
n -= buf->wpos - buf->rpos;
ibuf_dequeue(msgbuf, buf);
} else {
@ -304,8 +481,10 @@ ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
{
TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
if (buf->fd != -1)
if (buf->fd != -1) {
close(buf->fd);
buf->fd = -1;
}
msgbuf->queued--;
ibuf_free(buf);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: imsg.c,v 1.17 2022/01/28 10:41:44 claudio Exp $ */
/* $OpenBSD: imsg.c,v 1.19 2023/06/19 17:19:50 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -176,8 +176,7 @@ imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
if (imsg_add(wbuf, data, datalen) == -1)
return (-1);
wbuf->fd = fd;
ibuf_fd_set(wbuf, fd);
imsg_close(ibuf, wbuf);
return (1);
@ -200,14 +199,49 @@ imsg_composev(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
return (-1);
wbuf->fd = fd;
ibuf_fd_set(wbuf, fd);
imsg_close(ibuf, wbuf);
return (1);
}
/* ARGSUSED */
int
imsg_compose_ibuf(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid,
pid_t pid, struct ibuf *buf)
{
struct ibuf *wbuf = NULL;
struct imsg_hdr hdr;
int save_errno;
if (ibuf_size(buf) + IMSG_HEADER_SIZE > MAX_IMSGSIZE) {
errno = ERANGE;
goto fail;
}
hdr.type = type;
hdr.len = ibuf_size(buf) + IMSG_HEADER_SIZE;
hdr.flags = 0;
hdr.peerid = peerid;
if ((hdr.pid = pid) == 0)
hdr.pid = ibuf->pid;
if ((wbuf = ibuf_open(IMSG_HEADER_SIZE)) == NULL)
goto fail;
if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
goto fail;
ibuf_close(&ibuf->w, wbuf);
ibuf_close(&ibuf->w, buf);
return (1);
fail:
save_errno = errno;
ibuf_free(buf);
ibuf_free(wbuf);
errno = save_errno;
return (-1);
}
struct ibuf *
imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
uint16_t datalen)
@ -254,10 +288,9 @@ imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
hdr = (struct imsg_hdr *)msg->buf;
hdr->flags &= ~IMSGF_HASFD;
if (msg->fd != -1)
if (ibuf_fd_avail(msg))
hdr->flags |= IMSGF_HASFD;
hdr->len = (uint16_t)msg->wpos;
hdr->len = ibuf_size(msg);
ibuf_close(&ibuf->w, msg);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: imsg.h,v 1.5 2019/01/20 02:50:03 bcook Exp $ */
/* $OpenBSD: imsg.h,v 1.7 2023/06/19 17:19:50 claudio Exp $ */
/*
* Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
@ -78,22 +78,37 @@ struct imsg {
void *data;
};
struct iovec;
/* buffer.c */
/* imsg-buffer.c */
struct ibuf *ibuf_open(size_t);
struct ibuf *ibuf_dynamic(size_t, size_t);
int ibuf_add(struct ibuf *, const void *, size_t);
int ibuf_add_buf(struct ibuf *, const struct ibuf *);
int ibuf_add_zero(struct ibuf *, size_t);
int ibuf_add_n8(struct ibuf *, uint64_t);
int ibuf_add_n16(struct ibuf *, uint64_t);
int ibuf_add_n32(struct ibuf *, uint64_t);
int ibuf_add_n64(struct ibuf *, uint64_t);
void *ibuf_reserve(struct ibuf *, size_t);
void *ibuf_seek(struct ibuf *, size_t, size_t);
int ibuf_set(struct ibuf *, size_t, const void *, size_t);
int ibuf_set_n8(struct ibuf *, size_t, uint64_t);
int ibuf_set_n16(struct ibuf *, size_t, uint64_t);
int ibuf_set_n32(struct ibuf *, size_t, uint64_t);
int ibuf_set_n64(struct ibuf *, size_t, uint64_t);
void *ibuf_data(struct ibuf *);
size_t ibuf_size(struct ibuf *);
size_t ibuf_left(struct ibuf *);
void ibuf_close(struct msgbuf *, struct ibuf *);
int ibuf_write(struct msgbuf *);
void ibuf_free(struct ibuf *);
int ibuf_fd_avail(struct ibuf *);
int ibuf_fd_get(struct ibuf *);
void ibuf_fd_set(struct ibuf *, int);
int ibuf_write(struct msgbuf *);
void msgbuf_init(struct msgbuf *);
void msgbuf_clear(struct msgbuf *);
int msgbuf_write(struct msgbuf *);
void msgbuf_drain(struct msgbuf *, size_t);
/* imsg.c */
void imsg_init(struct imsgbuf *, int);
@ -103,6 +118,8 @@ int imsg_compose(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
const void *, uint16_t);
int imsg_composev(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
const struct iovec *, int);
int imsg_compose_ibuf(struct imsgbuf *, uint32_t, uint32_t, pid_t,
struct ibuf *);
struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, uint16_t);
int imsg_add(struct ibuf *, const void *, uint16_t);
void imsg_close(struct imsgbuf *, struct ibuf *);