ubusd: add per-client tx queue limit
authorArnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Thu, 25 Mar 2021 21:45:02 +0000 (22:45 +0100)
committerFelix Fietkau <nbd@nbd.name>
Mon, 31 May 2021 16:39:31 +0000 (18:39 +0200)
No new message can be enqueued if this brings the total queue length of
that client over UBUS_CLIENT_MAX_TXQ_LEN.

Set UBUS_CLIENT_MAX_TXQ_LEN to UBUS_MAX_MSGLEN, i.e. 1MB. This limit
should be plenty for any practical use case.

Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
ubusd.c
ubusd.h
ubusd_main.c

diff --git a/ubusd.c b/ubusd.c
index c324c704a74f7494407f1240f3a8ccfbc2f084cb..0e1b0c961b0688b565fda9272ae93d1a378e26fb 100644 (file)
--- a/ubusd.c
+++ b/ubusd.c
@@ -144,6 +144,9 @@ static void ubus_msg_enqueue(struct ubus_client *cl, struct ubus_msg_buf *ub)
 {
        struct ubus_msg_buf_list *ubl;
 
+       if (cl->txq_len + ub->len > UBUS_CLIENT_MAX_TXQ_LEN)
+               return;
+
        ubl = calloc(1, sizeof(struct ubus_msg_buf_list));
        if (!ubl)
                return;
@@ -152,6 +155,7 @@ static void ubus_msg_enqueue(struct ubus_client *cl, struct ubus_msg_buf *ub)
        ubl->msg = ubus_msg_ref(ub);
 
        list_add_tail(&cl->tx_queue, &ubl->list);
+       cl->txq_len += ub->len;
 }
 
 /* takes the msgbuf reference */
@@ -172,6 +176,7 @@ void ubus_msg_send(struct ubus_client *cl, struct ubus_msg_buf *ub)
                        return;
 
                cl->txq_ofs = written;
+               cl->txq_len = -written;
 
                /* get an event once we can write to the socket again */
                uloop_fd_add(&cl->sock, ULOOP_READ | ULOOP_WRITE | ULOOP_EDGE_TRIGGER);
diff --git a/ubusd.h b/ubusd.h
index f34cba118745a7988e2db0754dd5222556a64044..c5d6d2a49e4162b55679a315e1c243cde8e513c0 100644 (file)
--- a/ubusd.h
+++ b/ubusd.h
@@ -24,6 +24,7 @@
 #include "ubusd_acl.h"
 
 #define UBUS_OBJ_HASH_BITS     4
+#define UBUS_CLIENT_MAX_TXQ_LEN        UBUS_MAX_MSGLEN
 
 extern struct blob_buf b;
 
@@ -54,6 +55,7 @@ struct ubus_client {
 
        struct list_head tx_queue;
        unsigned int txq_ofs;
+       unsigned int txq_len;
 
        struct ubus_msg_buf *pending_msg;
        struct ubus_msg_buf *retmsg;
index 3728a4279238f1c8dba36491b37c8b9bd0f44488..d298b51db17b5ccd35255a5f89877a6db781d67f 100644 (file)
@@ -74,6 +74,7 @@ static void client_cb(struct uloop_fd *sock, unsigned int events)
                }
 
                cl->txq_ofs += written;
+               cl->txq_len -= written;
                if (cl->txq_ofs < ub->len + sizeof(ub->hdr))
                        break;