8#include <cosmos/dso_export.h>
9#include <cosmos/error/RuntimeError.hxx>
10#include <cosmos/io/iovector.hxx>
11#include <cosmos/net/SocketAddress.hxx>
12#include <cosmos/net/types.hxx>
38 socklen_t msg_namelen;
39 const struct iovec *msg_iov;
41 const void *msg_control;
42 size_t msg_controllen;
55template <
typename MSGHDR>
96 template <
typename IOVEC>
153 template <OptLevel,
typename MSG_TYPE>
182 const uint8_t*
data()
const {
188 return data() -
reinterpret_cast<const uint8_t*
>(
raw());
232 return reinterpret_cast<const struct msghdr*
>(&
m_header);
257 template <OptLevel,
typename MSG_TYPE>
263 return m_header.cmsg_type;
268 return m_header.cmsg_len;
279 return OptLevel{m_header.cmsg_level};
284 if (level() == OptLevel::SOCKET) {
291 std::optional<IP4Message> asIP4Message()
const {
292 if (level() == OptLevel::IP) {
299 std::optional<IP6Message> asIP6Message()
const {
300 if (level() == OptLevel::IPV6) {
315 return CMSG_DATA(&m_header);
320 return length() -
sizeof(m_header);
326 struct cmsghdr m_header;
342 m_pos{CMSG_FIRSTHDR(&header.m_header)},
349 const msghdr *hdr = m_header->rawHeader();
350 const cmsghdr *chdr = m_pos;
351 m_pos = CMSG_NXTHDR(
const_cast<msghdr*
>(hdr),
const_cast<cmsghdr*
>(chdr));
353 cosmos_throw (
RuntimeError(
"Attempt to increment ControlMessageIterator past the end"));
360 return m_pos == other.m_pos;
363 bool operator!=(
const ControlMessageIterator &other)
const {
364 return !(*
this == other);
370 cosmos_throw (
RuntimeError(
"Attempt to dereference an invalid ControlMessageIterator"));
378 const cmsghdr *m_pos =
nullptr;
409 void setControlBufferSize(
const size_t bytes);
413 setControlBufferSize(0);
416 ControlMessageIterator begin() {
417 return ControlMessageIterator{*
this};
420 ControlMessageIterator end() {
421 return ControlMessageIterator{};
427 void prepareReceive(SocketAddress *addr);
437 struct msghdr* rawHeader() {
441 const struct msghdr* rawHeader()
const {
458template <OptLevel level,
typename MSG_TYPE>
467 if (msg.
level() != level || type != MSG_TYPE(msg.
type())) {
468 cosmos_throw(
RuntimeError(
"ancillary message type mismatch"));
Base class for types that deal with (de)serializing ancillary socket messages.
bool update(size_t processed_bytes)
Update the vector given the number of bytes processed by a system call.
Exception type for generic runtime errors.
Base class for all types of socket addresses.
Base class for Socket types with ownership of a FileDescriptor.
IP6Message
Ancillary message types available for IPv6 based sockets.
OptLevel
Representation of socket option levels.
UnixMessage
Ancillary message types available for UNIX domain sockets.
IP4Message
Ancillary message types available for IPv4 based sockets.
Remodelling of struct msghdr with const semantics.