]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
dco-freebsd: dynamically re-allocate buffer if it's too small
authorKristof Provost <kp@FreeBSD.org>
Wed, 24 Jan 2024 15:27:39 +0000 (16:27 +0100)
committerGert Doering <gert@greenie.muc.de>
Wed, 7 Feb 2024 07:45:03 +0000 (08:45 +0100)
It's possible for the buffer we provide for OVPN_GET_PEER_STATS to be
too small. Handle the error, re-allocate a larger buffer and try again
rather than failing.

Signed-off-by: Kristof Provost <kprovost@netgate.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20240124152739.28248-1-kprovost@netgate.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28128.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
src/openvpn/dco_freebsd.c

index 3ba1c81741fb937fdbf89c81686d3d2971e5eeb0..577c65f879c5d62503b9bee38d7b306d4bfd1127 100644 (file)
@@ -698,7 +698,8 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m)
 {
 
     struct ifdrv drv;
-    uint8_t buf[4096];
+    uint8_t *buf = NULL;
+    size_t buf_size = 4096;
     nvlist_t *nvl;
     const nvlist_t *const *nvpeers;
     size_t npeers;
@@ -712,17 +713,28 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m)
     CLEAR(drv);
     snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
     drv.ifd_cmd = OVPN_GET_PEER_STATS;
-    drv.ifd_len = sizeof(buf);
+
+retry:
+    buf = realloc(buf, buf_size);
+    drv.ifd_len = buf_size;
     drv.ifd_data = buf;
 
     ret = ioctl(dco->fd, SIOCGDRVSPEC, &drv);
+    if (ret && errno == ENOSPC)
+    {
+        buf_size *= 2;
+        goto retry;
+    }
+
     if (ret)
     {
+        free(buf);
         msg(M_WARN | M_ERRNO, "Failed to get peer stats");
         return -EINVAL;
     }
 
     nvl = nvlist_unpack(buf, drv.ifd_len, 0);
+    free(buf);
     if (!nvl)
     {
         msg(M_WARN, "Failed to unpack nvlist");