1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! [](https://blog.rust-lang.org/2021/10/21/Rust-1.60.0.html)
//!
//! Traits for receiving datagrams reliably, without truncation.
//!
//! # Problem
//! Unlike a byte stream interface, datagram sockets (most notably UDP) and other packet-based APIs
//! preserve boundaries between different write calls, which is what "message boundary" essentially
//! means. Extracting messages by partial reads is an error-prone task, which is why no such
//! interface is exposed by any OS – instead, all messages received from message IPC channels are
//! full messages rather than chunks of messages, which simplifies things to a great degree and is
//! arguably the only proper way of implementing datagram support.
//!
//! There is one pecularity related to this design: you can't just use a buffer with arbitrary
//! length to successfully receive a message. With byte streams, that always works – there either is
//! some data which can be written into that buffer or end of file has been reached, aside from the
//! implied error case which is always a possibility for any kind of I/O. With datagrams,
//! however, **there might not always be enough space in a buffer to fetch a whole message**. If the
//! buffer is too small to fetch part of a message, it is truncated and the message ends up
//! essentially malformed.
//!
//! # Solution
//! The [`RecvMsg`] trait (together with its async counterpart, [`AsyncRecvMsg`]) provides an
//! interface that completely prevents truncation.
//!
//! With the help of [`MsgBuf`], a borrowed buffer can be provided, which can also be subsequently
//! transitioned into an owned buffer as needed. Alternatively, [`MsgBuf`] can start off with an
//! already-owned buffer. The inner `Vec` will then be resized as necessary, with an optional quota
//! preventing a connection from exhausting all memory.
//!
//! # Implementation
//! There are three features a standard truncating message reception can provide to allow programs
//! to solve the truncation problem: peeking, truncation reporting and exact length querying. The
//! former two are represented by the [`TruncatingRecvMsg`] trait, while the last one can be seen as
//! an extension of those and is thus available as [`TruncatingRecvMsgWithFullSize`]. Both of those
//! have async counterparts.
//!
//! [`RecvMsg`] or [`AsyncRecvMsg`] are then to be implemented in terms of either of those traits
//! using the appropriate helper function from the corresponding module.
//!
//! # Feature flags
//! - *`std`* – `std::error::Error` on [`QuotaExceeded`]. Precludes `#![no_std]`.
//! - *`std_net`* – implementations of traits on types from `std::net` and `std::os::unix::net`
//! (Unix domain sockets) on Unix.
extern crate alloc;
// TODO vectored
// TODO async-std
// TODO from_fns
// ya can't stop me
/// OS-specific functionality, in particular that which has public APIs that go beyond trait
/// implementations.
///
/// Only available when the standard library is enabled. Items from foreign platforms are not
/// visible in Rustdoc.
pub use ;
!
/// The type of `AddrBuf` associated types on implementations of traits from this crate for types
/// that do not support receiving the address of the peer together with received messages.
pub type NoAddrBuf = Infallible;
/// Result type for `.recv_msg()` methods.
/// Result type for `.try_recv_msg()` and `.recv_trunc_with_full_size()` methods.