net/SocketDescriptor: add Send()/Receive() overloads with iovec
This commit is contained in:
parent
974ed0166c
commit
6f6cbeba80
62
src/net/MsgHdr.hxx
Normal file
62
src/net/MsgHdr.hxx
Normal 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;
|
||||
}
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user