18#include <netinet/in.h>
19#include <sys/socket.h>
32struct DatagramSubscription {
64 [[nodiscard]]
bool ok() const noexcept {
return err == 0; }
70class KernelDatagramSource {
81 void close() noexcept;
86 std::
size_t poll(H&& handler) noexcept {
87 static_assert(std::is_nothrow_invocable_v<H&, std::span<const std::byte>,
const RxMeta&>,
88 "fastmm: DatagramSource handler must be void(std::span<const std::byte>, "
89 "const RxMeta&) noexcept");
90 std::size_t delivered = 0;
91 for (std::size_t line = 0; line < lines_.size(); ++line) {
92 const std::size_t n = receive(line);
93 const std::size_t base = line * batch_;
94 for (std::size_t i = base; i < base + n; ++i) {
95 if (lens_[i] == kDropped)
continue;
96 handler(std::span<const std::byte>(payload_.data() + i * max_datagram_, lens_[i]),
104 [[nodiscard]]
const DatagramSourceStats&
stats() const noexcept {
return stats_; }
105 [[nodiscard]] std::size_t
line_count() const noexcept {
return lines_.size(); }
106 [[nodiscard]]
int fd(std::size_t line)
const noexcept {
107 return line < lines_.size() ? lines_[line].sock.fd() : -1;
109 [[nodiscard]]
bool is_open() const noexcept {
return !lines_.empty(); }
112 static constexpr std::uint32_t kDropped = 0xFFFF'FFFFU;
116 std::uint32_t group_be = 0;
117 std::uint16_t port = 0;
122 std::size_t receive(std::size_t line)
noexcept;
124 std::vector<Line> lines_;
125 std::size_t batch_ = 0;
126 std::size_t max_datagram_ = 0;
127 std::size_t cmsg_space_ = 0;
128 std::vector<mmsghdr> msgs_;
129 std::vector<iovec> iovs_;
130 std::vector<sockaddr_in> names_;
131 std::vector<std::byte> cmsgs_;
132 std::vector<std::byte> payload_;
133 std::vector<std::uint32_t> lens_;
134 std::vector<RxMeta> metas_;
138static_assert(DatagramSource<KernelDatagramSource>);
Definition kernel_datagram_source.hpp:72
bool is_open() const noexcept
Definition kernel_datagram_source.hpp:110
std::size_t poll(H &&handler) noexcept
handler(std::span<const std::byte> payload, const RxMeta& meta) noexcept, once per datagram.
Definition kernel_datagram_source.hpp:87
const DatagramSourceStats & stats() const noexcept
Definition kernel_datagram_source.hpp:105
KernelDatagramSource(const KernelDatagramSource &)=delete
int fd(std::size_t line) const noexcept
Definition kernel_datagram_source.hpp:107
~KernelDatagramSource()=default
KernelSourceOpen open(const KernelSourceConfig &cfg)
Closes any previous sockets, then opens one per subscription. On failure nothing stays open.
KernelDatagramSource()=default
KernelDatagramSource & operator=(const KernelDatagramSource &)=delete
std::size_t line_count() const noexcept
Definition kernel_datagram_source.hpp:106
Definition udp_socket.hpp:44
Datagram receive interface for multicast market data (ADR-0015, section 1).
Definition reactor.hpp:37
Definition datagram_source.hpp:33
std::uint16_t port
Definition kernel_datagram_source.hpp:37
std::string interface
name ("eth1") or IPv4 address; "" = routing table
Definition kernel_datagram_source.hpp:35
std::string group
IPv4 multicast group, or a local unicast address.
Definition kernel_datagram_source.hpp:36
std::string source
"" = any source; otherwise a source-specific join (multicast only)
Definition kernel_datagram_source.hpp:38
Definition kernel_datagram_source.hpp:41
int busy_poll_usec
Definition kernel_datagram_source.hpp:50
std::uint32_t batch
datagrams per recvmmsg, 1..1024
Definition kernel_datagram_source.hpp:44
std::vector< DatagramSubscription > subscriptions
line = index, at most 256
Definition kernel_datagram_source.hpp:42
bool timestamps
SO_TIMESTAMPING.
Definition kernel_datagram_source.hpp:46
int rcvbuf_bytes
0 keeps the system default
Definition kernel_datagram_source.hpp:43
bool busy_poll
SO_BUSY_POLL / SO_PREFER_BUSY_POLL / SO_BUSY_POLL_BUDGET on every socket.
Definition kernel_datagram_source.hpp:49
int busy_poll_budget
0 keeps the kernel default (8)
Definition kernel_datagram_source.hpp:51
std::uint32_t max_datagram
larger datagrams are dropped (truncated)
Definition kernel_datagram_source.hpp:45
Outcome of open(). err is 0 or -errno of the step that failed, for subscription line.
Definition kernel_datagram_source.hpp:55
int busy_poll
Busy-poll options: 0 when applied to every socket, else the first -errno (-EPERM without CAP_NET_ADMI...
Definition kernel_datagram_source.hpp:61
int busy_poll_budget
Definition kernel_datagram_source.hpp:63
std::size_t line
Definition kernel_datagram_source.hpp:57
bool ok() const noexcept
Definition kernel_datagram_source.hpp:66
bool busy_poll_applied() const noexcept
Definition kernel_datagram_source.hpp:67
int prefer_busy_poll
Definition kernel_datagram_source.hpp:62
int err
Definition kernel_datagram_source.hpp:56
int rcvbuf
SO_RCVBUF granted on line 0, as getsockopt reports it.
Definition kernel_datagram_source.hpp:64
std::string_view step
"config", "interface", "group", "source", "socket", "bind", ...
Definition kernel_datagram_source.hpp:58
Non-blocking IPv4 UDP socket with RAII fd ownership: multicast membership, batch receive (recvmmsg) a...