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 "StaticSocketAddress.hxx"
|
||||||
#include "IPv4Address.hxx"
|
#include "IPv4Address.hxx"
|
||||||
#include "IPv6Address.hxx"
|
#include "IPv6Address.hxx"
|
||||||
|
#include "MsgHdr.hxx"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
@ -423,6 +424,13 @@ SocketDescriptor::Receive(struct msghdr &msg, int flags) const noexcept
|
|||||||
return ::recvmsg(Get(), &msg, flags);
|
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
|
ssize_t
|
||||||
SocketDescriptor::Send(std::span<const std::byte> src, int flags) const noexcept
|
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);
|
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
|
ssize_t
|
||||||
SocketDescriptor::ReadNoWait(std::span<std::byte> dest) const noexcept
|
SocketDescriptor::ReadNoWait(std::span<std::byte> dest) const noexcept
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
// SPDX-License-Identifier: BSD-2-Clause
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
// author: Max Kellermann <max.kellermann@gmail.com>
|
// author: Max Kellermann <max.kellermann@gmail.com>
|
||||||
|
|
||||||
#ifndef SOCKET_DESCRIPTOR_HXX
|
#pragma once
|
||||||
#define SOCKET_DESCRIPTOR_HXX
|
|
||||||
|
|
||||||
#include "Features.hxx"
|
#include "Features.hxx"
|
||||||
|
|
||||||
@ -19,6 +18,8 @@
|
|||||||
#include <winsock2.h> // for SOCKET, INVALID_SOCKET
|
#include <winsock2.h> // for SOCKET, INVALID_SOCKET
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct msghdr;
|
||||||
|
struct iovec;
|
||||||
class SocketAddress;
|
class SocketAddress;
|
||||||
class StaticSocketAddress;
|
class StaticSocketAddress;
|
||||||
class IPv4Address;
|
class IPv4Address;
|
||||||
@ -309,6 +310,12 @@ public:
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
ssize_t Receive(struct msghdr &msg, int flags=0) const noexcept;
|
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().
|
* Wrapper for send().
|
||||||
*
|
*
|
||||||
@ -325,6 +332,14 @@ public:
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
ssize_t Send(const struct msghdr &msg, int flags=0) const noexcept;
|
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]]
|
[[nodiscard]]
|
||||||
ssize_t Read(std::span<std::byte> dest) const noexcept {
|
ssize_t Read(std::span<std::byte> dest) const noexcept {
|
||||||
return Receive(dest);
|
return Receive(dest);
|
||||||
@ -383,5 +398,3 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static_assert(std::is_trivial<SocketDescriptor>::value, "type is not trivial");
|
static_assert(std::is_trivial<SocketDescriptor>::value, "type is not trivial");
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
// SPDX-License-Identifier: BSD-2-Clause
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
// author: Max Kellermann <max.kellermann@gmail.com>
|
// author: Max Kellermann <max.kellermann@gmail.com>
|
||||||
|
|
||||||
#ifndef UNIQUE_SOCKET_DESCRIPTOR_SOCKET_HXX
|
#pragma once
|
||||||
#define UNIQUE_SOCKET_DESCRIPTOR_SOCKET_HXX
|
|
||||||
|
|
||||||
#include "SocketDescriptor.hxx"
|
#include "SocketDescriptor.hxx"
|
||||||
|
|
||||||
@ -90,5 +89,3 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
Loading…
Reference in New Issue
Block a user