1
+ //! Traits for using UDP on embedded devices
2
+ //!
3
+ //! ## Notes for implementers
4
+ //!
5
+ //! * At several places, the APIs expect to provide a local address. Backends that can not obtain
6
+ //! it, such as some AT-command based stacks, <!-- should question whether they may really call
7
+ //! themselves UDP and --> may pretend to have performed some form of network address
8
+ //! translation, and present invalid addresses as the local address.
9
+ //!
10
+ //! * Implementing [`UdpStack::Bound`] and [`UdpStack::Unbound`] unconnected sockets separately
11
+ //! allows discarding the local addresses in the bound case. With LTO enabled, all the overhead
12
+ //! compared with a third trait variant between [ConnectedUdp] and [UnconnectedUdp] (in which the
13
+ //! local address is static but the remote address is flexible) should optimized out.
14
+ //! Implementing `Bound` and `Unbound` with the same type is expected to be a common choice.
15
+
1
16
use core:: future:: Future ;
2
17
use no_std_net:: SocketAddr ;
3
18
@@ -48,53 +63,17 @@ pub trait ConnectedUdp {
48
63
49
64
/// This trait is implemented by UDP sockets.
50
65
///
51
- /// The socket it represents is both bound (has a local IP address, port and interface) but not
52
- /// connected; its peer IP address is explicit in every call.
66
+ /// The socket it represents is not necessarily bound (may not have a single local IP address, port
67
+ /// and interface), and is typically not connected (has no remote IP address and port). Both are
68
+ /// addresses are explicitly given in every call.
53
69
///
54
- /// This is similar to a POSIX datagram socket that has been bound to a concrete address.
55
- pub trait BoundUdp {
70
+ /// If there were constraints in place at socket creation time (typically on the local side), the
71
+ /// caller MUST pass in the same (or compatible) values, MAY and pass in unspecified values where
72
+ /// applicable. The implementer MAY check them for compatibility, and SHOULD do that in debug mode.
73
+ pub trait UnconnectedUdp {
56
74
type Error : embedded_io:: Error ;
57
75
58
- /// Send the provided data to the connected peer
59
- fn send_to ( & mut self , remote : SocketAddr , data : & [ u8 ] ) -> Self :: SendToFuture < ' _ > ;
60
- type SendToFuture < ' a > : Future < Output = Result < ( ) , Self :: Error > >
61
- where
62
- Self : ' a ;
63
-
64
- /// Receive a datagram into the provided buffer.
65
- ///
66
- /// If the received datagram exceeds the buffer's length, it is received regardless, and the
67
- /// remaining bytes are discarded. The full datagram size is still indicated in the result,
68
- /// allowing the recipient to detect that truncation.
69
- ///
70
- /// The remote address is given in the result along with the number of bytes.
71
- ///
72
- /// ## Compatibility note
73
- ///
74
- /// This deviates from the sync/nb equivalent trait in that it describes the overflow behavior
75
- /// (a possibility not considered there). The name deviates from the original `receive()` to
76
- /// make room for a version that is more zero-copy friendly.
77
- fn receive_from_into ( & mut self , buffer : & mut [ u8 ] ) -> Self :: ReceiveFromIntoFuture < ' _ > ;
78
- type ReceiveFromIntoFuture < ' a > : Future < Output = Result < ( usize , SocketAddr ) , Self :: Error > >
79
- where
80
- Self : ' a ;
81
- }
82
-
83
- /// This trait is implemented by UDP sockets.
84
- ///
85
- /// The socket it represents is neither bound (has no single local IP address, port and interface)
86
- /// nor connected (has no remote IP address and port). Both are explicitly given in every call.
87
- ///
88
- /// There may be constraints placed on an unbound socket at creation time that limit the range of
89
- /// local addresses (further than the natural limitation of only using addresses assigned to the
90
- /// host).
91
- ///
92
- /// A typical example of this kind of socket is a POSIX datagram socket that has been bound to
93
- /// "any" address (`[::]` or `0.0.0.0`) but to a particular port.
94
- pub trait UnboundUdp {
95
- type Error : embedded_io:: Error ;
96
-
97
- /// Send the provided data to the connected peer
76
+ /// Send the provided data to a peer
98
77
///
99
78
/// ## Sending initial messages
100
79
///
@@ -110,6 +89,13 @@ pub trait UnboundUdp {
110
89
/// sending from the address to which the original datagram was addressed, or from an unbound
111
90
/// address. Both are valid choices in some situations, and the right choice depends on the
112
91
/// protocol used.
92
+ ///
93
+ /// Note that users of sockets created through [`UdpSocket::bind_single()`] should always pass
94
+ /// in that single address -- even though they've made their intention clear at construction.
95
+ /// They can pass either the one obtained at socket creation time, or the one obtained at
96
+ /// receive time; these should be equal. This allows implementations of the trait to use a
97
+ /// single kind of socket for both sockets bound to a single and sockets bound to multiple
98
+ /// addresses.
113
99
fn send ( & mut self , local : SocketAddr , remote : SocketAddr , data : & [ u8 ] ) -> Self :: SendFuture < ' _ > ;
114
100
type SendFuture < ' a > : Future < Output = Result < ( ) , Self :: Error > >
115
101
where
@@ -141,10 +127,10 @@ pub trait UdpStack {
141
127
type Connected < ' m > : ConnectedUdp
142
128
where
143
129
Self : ' m ;
144
- type Bound < ' m > : BoundUdp
130
+ type Bound < ' m > : UnconnectedUdp
145
131
where
146
132
Self : ' m ;
147
- type Unbound < ' m > : UnboundUdp
133
+ type Unbound < ' m > : UnconnectedUdp
148
134
where
149
135
Self : ' m ;
150
136
0 commit comments