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