You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ma...@apache.org on 2023/02/07 19:58:18 UTC

[trafficserver] branch master updated: Use IOBufferBlock instead of alloc to avoid stackoverflow (#9385)

This is an automated email from the ASF dual-hosted git repository.

maskit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new f46a72675e Use IOBufferBlock instead of alloc to avoid stackoverflow (#9385)
f46a72675e is described below

commit f46a72675ec4c9cb2cae6c788f23944ea23ac329
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Tue Feb 7 12:58:09 2023 -0700

    Use IOBufferBlock instead of alloc to avoid stackoverflow (#9385)
---
 iocore/net/UnixUDPNet.cc | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/iocore/net/UnixUDPNet.cc b/iocore/net/UnixUDPNet.cc
index daca6c2b88..8f37f21592 100644
--- a/iocore/net/UnixUDPNet.cc
+++ b/iocore/net/UnixUDPNet.cc
@@ -1167,9 +1167,20 @@ UDPQueue::SendMultipleUDPPackets(UDPPacketInternal **p, uint16_t n)
 #else
   msgvec_size = sizeof(struct mmsghdr) * n * 64;
 #endif
-  msgvec = static_cast<struct mmsghdr *>(alloca(msgvec_size));
+  // The sizeof(struct msghdr) is 56 bytes or so. It can be too big to stack (alloca).
+  IOBufferBlock *tmp = new_IOBufferBlock();
+  tmp->alloc(iobuffer_size_to_index(msgvec_size, BUFFER_SIZE_INDEX_1M));
+  msgvec = reinterpret_cast<struct mmsghdr *>(tmp->buf());
   memset(msgvec, 0, msgvec_size);
 
+  // The sizeof(struct iove) is 16 bytes or so. It can be too big to stack (alloca).
+  int iovec_size      = sizeof(struct iovec) * n * 64;
+  IOBufferBlock *tmp2 = new_IOBufferBlock();
+  tmp2->alloc(iobuffer_size_to_index(iovec_size, BUFFER_SIZE_INDEX_1M));
+  struct iovec *iovec = reinterpret_cast<struct iovec *>(tmp2->buf());
+  memset(iovec, 0, iovec_size);
+  int iovec_used = 0;
+
   int vlen = 0;
   int fd   = p[0]->conn->getFd();
   for (int i = 0; i < n; ++i) {
@@ -1194,7 +1205,7 @@ UDPQueue::SendMultipleUDPPackets(UDPPacketInternal **p, uint16_t n)
         u                   = static_cast<union udp_segment_hdr *>(alloca(sizeof(union udp_segment_hdr)));
         msg->msg_control    = u->buf;
         msg->msg_controllen = sizeof(u->buf);
-        iov                 = static_cast<struct iovec *>(alloca(sizeof(struct iovec)));
+        iov                 = &iovec[iovec_used++];
         iov_len             = 1;
         iov->iov_base       = packet->chain.get()->start();
         iov->iov_len        = packet->chain.get()->size();
@@ -1216,7 +1227,7 @@ UDPQueue::SendMultipleUDPPackets(UDPPacketInternal **p, uint16_t n)
           msg              = &msgvec[vlen].msg_hdr;
           msg->msg_name    = reinterpret_cast<caddr_t>(&packet->to.sa);
           msg->msg_namelen = ats_ip_size(packet->to);
-          iov              = static_cast<struct iovec *>(alloca(sizeof(struct iovec)));
+          iov              = &iovec[iovec_used++];
           iov_len          = 1;
           iov->iov_base    = packet->chain.get()->start() + offset;
           iov->iov_len =
@@ -1235,7 +1246,7 @@ UDPQueue::SendMultipleUDPPackets(UDPPacketInternal **p, uint16_t n)
       msg              = &msgvec[vlen].msg_hdr;
       msg->msg_name    = reinterpret_cast<caddr_t>(&packet->to.sa);
       msg->msg_namelen = ats_ip_size(packet->to);
-      iov              = static_cast<struct iovec *>(alloca(sizeof(struct iovec) * 64));
+      iov              = &iovec[iovec_used++];
       iov_len          = 0;
       for (IOBufferBlock *b = packet->chain.get(); b != nullptr; b = b->next.get()) {
         iov[iov_len].iov_base = static_cast<caddr_t>(b->start());
@@ -1291,6 +1302,8 @@ UDPQueue::SendMultipleUDPPackets(UDPPacketInternal **p, uint16_t n)
     }
 #endif
   }
+  tmp->free();
+  tmp2->free();
 
   return res;
 #else