@@ -21,17 +21,19 @@ pub enum BindError {
2121 NoRoute ,
2222}
2323
24- /// Error returned by [`UdpSocket::recv_from`] and [`UdpSocket:: send_to`].
24+ /// Error returned by [`UdpSocket::send_to`].
2525#[ derive( PartialEq , Eq , Clone , Copy , Debug ) ]
2626#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
2727pub enum SendError {
2828 /// No route to host.
2929 NoRoute ,
3030 /// Socket not bound to an outgoing port.
3131 SocketNotBound ,
32+ /// There is not enough transmit buffer capacity to ever send this packet.
33+ Truncated ,
3234}
3335
34- /// Error returned by [`UdpSocket::recv_from`] and [`UdpSocket::send_to`] .
36+ /// Error returned by [`UdpSocket::recv_from`].
3537#[ derive( PartialEq , Eq , Clone , Copy , Debug ) ]
3638#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
3739pub enum RecvError {
@@ -224,6 +226,8 @@ impl<'a> UdpSocket<'a> {
224226 ///
225227 /// This method will wait until the datagram has been sent.
226228 ///
229+ /// If the socket's send buffer is too small to fit `buf`, this method will return `Poll::Ready(Err(SendError::Truncated))`
230+ ///
227231 /// When the remote endpoint is not reachable, this method will return `Err(SendError::NoRoute)`
228232 pub async fn send_to < T > ( & self , buf : & [ u8 ] , remote_endpoint : T ) -> Result < ( ) , SendError >
229233 where
@@ -240,11 +244,21 @@ impl<'a> UdpSocket<'a> {
240244 /// When the socket's send buffer is full, this method will return `Poll::Pending`
241245 /// and register the current task to be notified when the buffer has space available.
242246 ///
247+ /// If the socket's send buffer is too small to fit `buf`, this method will return `Poll::Ready(Err(SendError::Truncated))`
248+ ///
243249 /// When the remote endpoint is not reachable, this method will return `Poll::Ready(Err(Error::NoRoute))`.
244250 pub fn poll_send_to < T > ( & self , buf : & [ u8 ] , remote_endpoint : T , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , SendError > >
245251 where
246252 T : Into < UdpMetadata > ,
247253 {
254+ // Don't need to wake waker in `with_mut` if the buffer will never fit the udp tx_buffer.
255+ let send_capacity_too_small = self
256+ . stack
257+ . with ( |i| i. sockets . get :: < udp:: Socket > ( self . handle ) . payload_send_capacity ( ) < buf. len ( ) ) ;
258+ if send_capacity_too_small {
259+ return Poll :: Ready ( Err ( SendError :: Truncated ) ) ;
260+ }
261+
248262 self . with_mut ( |s, _| match s. send_slice ( buf, remote_endpoint) {
249263 // Entire datagram has been sent
250264 Ok ( ( ) ) => Poll :: Ready ( Ok ( ( ) ) ) ,
@@ -268,12 +282,22 @@ impl<'a> UdpSocket<'a> {
268282 /// This method will wait until the buffer can fit the requested size before
269283 /// calling the function to fill its contents.
270284 ///
285+ /// If the socket's send buffer is too small to fit `size`, this method will return `Poll::Ready(Err(SendError::Truncated))`
286+ ///
271287 /// When the remote endpoint is not reachable, this method will return `Err(SendError::NoRoute)`
272288 pub async fn send_to_with < T , F , R > ( & mut self , size : usize , remote_endpoint : T , f : F ) -> Result < R , SendError >
273289 where
274290 T : Into < UdpMetadata > + Copy ,
275291 F : FnOnce ( & mut [ u8 ] ) -> R ,
276292 {
293+ // Don't need to wake waker in `with_mut` if the buffer will never fit the udp tx_buffer.
294+ let send_capacity_too_small = self
295+ . stack
296+ . with ( |i| i. sockets . get :: < udp:: Socket > ( self . handle ) . payload_send_capacity ( ) < size) ;
297+ if send_capacity_too_small {
298+ return Err ( SendError :: Truncated ) ;
299+ }
300+
277301 let mut f = Some ( f) ;
278302 poll_fn ( move |cx| {
279303 self . with_mut ( |s, _| {
0 commit comments