net/SocketDescriptor: add Send()/Receive() overloads with iovec

This commit is contained in:
Max Kellermann 2024-01-12 12:09:41 +01:00 committed by Max Kellermann
parent 974ed0166c
commit 6f6cbeba80
4 changed files with 94 additions and 8 deletions

62
src/net/MsgHdr.hxx Normal file
View File

@ -0,0 +1,62 @@
// SPDX-License-Identifier: BSD-2-Clause
// Copyright CM4all GmbH
// author: Max Kellermann <mk@cm4all.com>
#pragma once
#include "SocketAddress.hxx"
#include "StaticSocketAddress.hxx"
#include <span>
#include <sys/socket.h>
inline constexpr struct msghdr
MakeMsgHdr(std::span<const struct iovec> iov) noexcept
{
struct msghdr mh{};
mh.msg_iov = const_cast<struct iovec *>(iov.data());
mh.msg_iovlen = iov.size();
return mh;
}
/**
* Construct a struct msghdr. The parameters are `const` because that
* is needed for sending; but for receiving, these buffers must
* actually be writable.
*/
inline constexpr struct msghdr
MakeMsgHdr(SocketAddress name, std::span<const struct iovec> iov,
std::span<const std::byte> control) noexcept
{
auto mh = MakeMsgHdr(iov);
mh.msg_name = const_cast<struct sockaddr *>(name.GetAddress());
mh.msg_namelen = name.GetSize();
mh.msg_control = const_cast<std::byte *>(control.data());
mh.msg_controllen = control.size();
return mh;
}
inline constexpr struct msghdr
MakeMsgHdr(StaticSocketAddress &name, std::span<const struct iovec> iov,
std::span<const std::byte> control) noexcept
{
auto mh = MakeMsgHdr(iov);
mh.msg_name = name;
mh.msg_namelen = name.GetCapacity();
mh.msg_control = const_cast<std::byte *>(control.data());
mh.msg_controllen = control.size();
return mh;
}
inline constexpr struct msghdr
MakeMsgHdr(struct sockaddr_storage &name, std::span<const struct iovec> iov,
std::span<const std::byte> control) noexcept
{
auto mh = MakeMsgHdr(iov);
mh.msg_name = static_cast<struct sockaddr *>(static_cast<void *>(&name));
mh.msg_namelen = sizeof(name);
mh.msg_control = const_cast<std::byte *>(control.data());
mh.msg_controllen = control.size();
return mh;
}

View File

@ -6,6 +6,7 @@
#include "StaticSocketAddress.hxx"
#include "IPv4Address.hxx"
#include "IPv6Address.hxx"
#include "MsgHdr.hxx"
#ifdef _WIN32
#include <ws2tcpip.h>
@ -423,6 +424,13 @@ SocketDescriptor::Receive(struct msghdr &msg, int flags) const noexcept
return ::recvmsg(Get(), &msg, flags);
}
ssize_t
SocketDescriptor::Receive(std::span<const struct iovec> v, int flags) const noexcept
{
auto msg = MakeMsgHdr(v);
return Receive(msg, flags);
}
ssize_t
SocketDescriptor::Send(std::span<const std::byte> src, int flags) const noexcept
{
@ -443,6 +451,12 @@ SocketDescriptor::Send(const struct msghdr &msg, int flags) const noexcept
return ::sendmsg(Get(), &msg, flags);
}
ssize_t
SocketDescriptor::Send(std::span<const struct iovec> v, int flags) const noexcept
{
return Send(MakeMsgHdr(v), flags);
}
ssize_t
SocketDescriptor::ReadNoWait(std::span<std::byte> dest) const noexcept
{

View File

@ -1,8 +1,7 @@
// SPDX-License-Identifier: BSD-2-Clause
// author: Max Kellermann <max.kellermann@gmail.com>
#ifndef SOCKET_DESCRIPTOR_HXX
#define SOCKET_DESCRIPTOR_HXX
#pragma once
#include "Features.hxx"
@ -19,6 +18,8 @@
#include <winsock2.h> // for SOCKET, INVALID_SOCKET
#endif
struct msghdr;
struct iovec;
class SocketAddress;
class StaticSocketAddress;
class IPv4Address;
@ -309,6 +310,12 @@ public:
[[nodiscard]]
ssize_t Receive(struct msghdr &msg, int flags=0) const noexcept;
/**
* Wrapper for recvmsg().
*/
[[nodiscard]]
ssize_t Receive(std::span<const struct iovec> v, int flags=0) const noexcept;
/**
* Wrapper for send().
*
@ -325,6 +332,14 @@ public:
[[nodiscard]]
ssize_t Send(const struct msghdr &msg, int flags=0) const noexcept;
/**
* Wrapper for sendmsg().
*
* MSG_NOSIGNAL is implicitly added (if available).
*/
[[nodiscard]]
ssize_t Send(std::span<const struct iovec> v, int flags=0) const noexcept;
[[nodiscard]]
ssize_t Read(std::span<std::byte> dest) const noexcept {
return Receive(dest);
@ -383,5 +398,3 @@ public:
};
static_assert(std::is_trivial<SocketDescriptor>::value, "type is not trivial");
#endif

View File

@ -1,8 +1,7 @@
// SPDX-License-Identifier: BSD-2-Clause
// author: Max Kellermann <max.kellermann@gmail.com>
#ifndef UNIQUE_SOCKET_DESCRIPTOR_SOCKET_HXX
#define UNIQUE_SOCKET_DESCRIPTOR_SOCKET_HXX
#pragma once
#include "SocketDescriptor.hxx"
@ -90,5 +89,3 @@ public:
}
#endif
};
#endif