udp.rs 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. use core::cmp::min;
  2. #[cfg(feature = "async")]
  3. use core::task::Waker;
  4. use crate::iface::Context;
  5. use crate::phy::PacketMeta;
  6. use crate::socket::PollAt;
  7. #[cfg(feature = "async")]
  8. use crate::socket::WakerRegistration;
  9. use crate::storage::Empty;
  10. use crate::wire::{IpEndpoint, IpListenEndpoint, IpProtocol, IpRepr, UdpRepr};
  11. /// Metadata for a sent or received UDP packet.
  12. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  13. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  14. pub struct UdpMetadata {
  15. pub endpoint: IpEndpoint,
  16. pub meta: PacketMeta,
  17. }
  18. impl<T: Into<IpEndpoint>> From<T> for UdpMetadata {
  19. fn from(value: T) -> Self {
  20. Self {
  21. endpoint: value.into(),
  22. meta: PacketMeta::default(),
  23. }
  24. }
  25. }
  26. impl core::fmt::Display for UdpMetadata {
  27. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  28. #[cfg(feature = "packetmeta-id")]
  29. return write!(f, "{}, PacketID: {:?}", self.endpoint, self.meta);
  30. #[cfg(not(feature = "packetmeta-id"))]
  31. write!(f, "{}", self.endpoint)
  32. }
  33. }
  34. /// A UDP packet metadata.
  35. pub type PacketMetadata = crate::storage::PacketMetadata<UdpMetadata>;
  36. /// A UDP packet ring buffer.
  37. pub type PacketBuffer<'a> = crate::storage::PacketBuffer<'a, UdpMetadata>;
  38. /// Error returned by [`Socket::bind`]
  39. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  40. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  41. pub enum BindError {
  42. InvalidState,
  43. Unaddressable,
  44. }
  45. impl core::fmt::Display for BindError {
  46. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  47. match self {
  48. BindError::InvalidState => write!(f, "invalid state"),
  49. BindError::Unaddressable => write!(f, "unaddressable"),
  50. }
  51. }
  52. }
  53. #[cfg(feature = "std")]
  54. impl std::error::Error for BindError {}
  55. /// Error returned by [`Socket::send`]
  56. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  57. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  58. pub enum SendError {
  59. Unaddressable,
  60. BufferFull,
  61. }
  62. impl core::fmt::Display for SendError {
  63. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  64. match self {
  65. SendError::Unaddressable => write!(f, "unaddressable"),
  66. SendError::BufferFull => write!(f, "buffer full"),
  67. }
  68. }
  69. }
  70. #[cfg(feature = "std")]
  71. impl std::error::Error for SendError {}
  72. /// Error returned by [`Socket::recv`]
  73. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  74. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  75. pub enum RecvError {
  76. Exhausted,
  77. }
  78. impl core::fmt::Display for RecvError {
  79. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  80. match self {
  81. RecvError::Exhausted => write!(f, "exhausted"),
  82. }
  83. }
  84. }
  85. #[cfg(feature = "std")]
  86. impl std::error::Error for RecvError {}
  87. /// A User Datagram Protocol socket.
  88. ///
  89. /// A UDP socket is bound to a specific endpoint, and owns transmit and receive
  90. /// packet buffers.
  91. #[derive(Debug)]
  92. pub struct Socket<'a> {
  93. endpoint: IpListenEndpoint,
  94. rx_buffer: PacketBuffer<'a>,
  95. tx_buffer: PacketBuffer<'a>,
  96. /// The time-to-live (IPv4) or hop limit (IPv6) value used in outgoing packets.
  97. hop_limit: Option<u8>,
  98. #[cfg(feature = "async")]
  99. rx_waker: WakerRegistration,
  100. #[cfg(feature = "async")]
  101. tx_waker: WakerRegistration,
  102. }
  103. impl<'a> Socket<'a> {
  104. /// Create an UDP socket with the given buffers.
  105. pub fn new(rx_buffer: PacketBuffer<'a>, tx_buffer: PacketBuffer<'a>) -> Socket<'a> {
  106. Socket {
  107. endpoint: IpListenEndpoint::default(),
  108. rx_buffer,
  109. tx_buffer,
  110. hop_limit: None,
  111. #[cfg(feature = "async")]
  112. rx_waker: WakerRegistration::new(),
  113. #[cfg(feature = "async")]
  114. tx_waker: WakerRegistration::new(),
  115. }
  116. }
  117. /// Register a waker for receive operations.
  118. ///
  119. /// The waker is woken on state changes that might affect the return value
  120. /// of `recv` method calls, such as receiving data, or the socket closing.
  121. ///
  122. /// Notes:
  123. ///
  124. /// - Only one waker can be registered at a time. If another waker was previously registered,
  125. /// it is overwritten and will no longer be woken.
  126. /// - The Waker is woken only once. Once woken, you must register it again to receive more wakes.
  127. /// - "Spurious wakes" are allowed: a wake doesn't guarantee the result of `recv` has
  128. /// necessarily changed.
  129. #[cfg(feature = "async")]
  130. pub fn register_recv_waker(&mut self, waker: &Waker) {
  131. self.rx_waker.register(waker)
  132. }
  133. /// Register a waker for send operations.
  134. ///
  135. /// The waker is woken on state changes that might affect the return value
  136. /// of `send` method calls, such as space becoming available in the transmit
  137. /// buffer, or the socket closing.
  138. ///
  139. /// Notes:
  140. ///
  141. /// - Only one waker can be registered at a time. If another waker was previously registered,
  142. /// it is overwritten and will no longer be woken.
  143. /// - The Waker is woken only once. Once woken, you must register it again to receive more wakes.
  144. /// - "Spurious wakes" are allowed: a wake doesn't guarantee the result of `send` has
  145. /// necessarily changed.
  146. #[cfg(feature = "async")]
  147. pub fn register_send_waker(&mut self, waker: &Waker) {
  148. self.tx_waker.register(waker)
  149. }
  150. /// Return the bound endpoint.
  151. #[inline]
  152. pub fn endpoint(&self) -> IpListenEndpoint {
  153. self.endpoint
  154. }
  155. /// Return the time-to-live (IPv4) or hop limit (IPv6) value used in outgoing packets.
  156. ///
  157. /// See also the [set_hop_limit](#method.set_hop_limit) method
  158. pub fn hop_limit(&self) -> Option<u8> {
  159. self.hop_limit
  160. }
  161. /// Set the time-to-live (IPv4) or hop limit (IPv6) value used in outgoing packets.
  162. ///
  163. /// A socket without an explicitly set hop limit value uses the default [IANA recommended]
  164. /// value (64).
  165. ///
  166. /// # Panics
  167. ///
  168. /// This function panics if a hop limit value of 0 is given. See [RFC 1122 § 3.2.1.7].
  169. ///
  170. /// [IANA recommended]: https://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml
  171. /// [RFC 1122 § 3.2.1.7]: https://tools.ietf.org/html/rfc1122#section-3.2.1.7
  172. pub fn set_hop_limit(&mut self, hop_limit: Option<u8>) {
  173. // A host MUST NOT send a datagram with a hop limit value of 0
  174. if let Some(0) = hop_limit {
  175. panic!("the time-to-live value of a packet must not be zero")
  176. }
  177. self.hop_limit = hop_limit
  178. }
  179. /// Bind the socket to the given endpoint.
  180. ///
  181. /// This function returns `Err(Error::Illegal)` if the socket was open
  182. /// (see [is_open](#method.is_open)), and `Err(Error::Unaddressable)`
  183. /// if the port in the given endpoint is zero.
  184. pub fn bind<T: Into<IpListenEndpoint>>(&mut self, endpoint: T) -> Result<(), BindError> {
  185. let endpoint = endpoint.into();
  186. if endpoint.port == 0 {
  187. return Err(BindError::Unaddressable);
  188. }
  189. if self.is_open() {
  190. return Err(BindError::InvalidState);
  191. }
  192. self.endpoint = endpoint;
  193. #[cfg(feature = "async")]
  194. {
  195. self.rx_waker.wake();
  196. self.tx_waker.wake();
  197. }
  198. Ok(())
  199. }
  200. /// Close the socket.
  201. pub fn close(&mut self) {
  202. // Clear the bound endpoint of the socket.
  203. self.endpoint = IpListenEndpoint::default();
  204. // Reset the RX and TX buffers of the socket.
  205. self.tx_buffer.reset();
  206. self.rx_buffer.reset();
  207. #[cfg(feature = "async")]
  208. {
  209. self.rx_waker.wake();
  210. self.tx_waker.wake();
  211. }
  212. }
  213. /// Check whether the socket is open.
  214. #[inline]
  215. pub fn is_open(&self) -> bool {
  216. self.endpoint.port != 0
  217. }
  218. /// Check whether the transmit buffer is full.
  219. #[inline]
  220. pub fn can_send(&self) -> bool {
  221. !self.tx_buffer.is_full()
  222. }
  223. /// Check whether the receive buffer is not empty.
  224. #[inline]
  225. pub fn can_recv(&self) -> bool {
  226. !self.rx_buffer.is_empty()
  227. }
  228. /// Return the maximum number packets the socket can receive.
  229. #[inline]
  230. pub fn packet_recv_capacity(&self) -> usize {
  231. self.rx_buffer.packet_capacity()
  232. }
  233. /// Return the maximum number packets the socket can transmit.
  234. #[inline]
  235. pub fn packet_send_capacity(&self) -> usize {
  236. self.tx_buffer.packet_capacity()
  237. }
  238. /// Return the maximum number of bytes inside the recv buffer.
  239. #[inline]
  240. pub fn payload_recv_capacity(&self) -> usize {
  241. self.rx_buffer.payload_capacity()
  242. }
  243. /// Return the maximum number of bytes inside the transmit buffer.
  244. #[inline]
  245. pub fn payload_send_capacity(&self) -> usize {
  246. self.tx_buffer.payload_capacity()
  247. }
  248. /// Enqueue a packet to be sent to a given remote endpoint, and return a pointer
  249. /// to its payload.
  250. ///
  251. /// This function returns `Err(Error::Exhausted)` if the transmit buffer is full,
  252. /// `Err(Error::Unaddressable)` if local or remote port, or remote address are unspecified,
  253. /// and `Err(Error::Truncated)` if there is not enough transmit buffer capacity
  254. /// to ever send this packet.
  255. pub fn send(
  256. &mut self,
  257. size: usize,
  258. meta: impl Into<UdpMetadata>,
  259. ) -> Result<&mut [u8], SendError> {
  260. let meta = meta.into();
  261. if self.endpoint.port == 0 {
  262. return Err(SendError::Unaddressable);
  263. }
  264. if meta.endpoint.addr.is_unspecified() {
  265. return Err(SendError::Unaddressable);
  266. }
  267. if meta.endpoint.port == 0 {
  268. return Err(SendError::Unaddressable);
  269. }
  270. let payload_buf = self
  271. .tx_buffer
  272. .enqueue(size, meta)
  273. .map_err(|_| SendError::BufferFull)?;
  274. net_trace!(
  275. "udp:{}:{}: buffer to send {} octets",
  276. self.endpoint,
  277. meta.endpoint,
  278. size
  279. );
  280. Ok(payload_buf)
  281. }
  282. /// Enqueue a packet to be send to a given remote endpoint and pass the buffer
  283. /// to the provided closure. The closure then returns the size of the data written
  284. /// into the buffer.
  285. ///
  286. /// Also see [send](#method.send).
  287. pub fn send_with<F>(
  288. &mut self,
  289. max_size: usize,
  290. meta: impl Into<UdpMetadata>,
  291. f: F,
  292. ) -> Result<usize, SendError>
  293. where
  294. F: FnOnce(&mut [u8]) -> usize,
  295. {
  296. let meta = meta.into();
  297. if self.endpoint.port == 0 {
  298. return Err(SendError::Unaddressable);
  299. }
  300. if meta.endpoint.addr.is_unspecified() {
  301. return Err(SendError::Unaddressable);
  302. }
  303. if meta.endpoint.port == 0 {
  304. return Err(SendError::Unaddressable);
  305. }
  306. let size = self
  307. .tx_buffer
  308. .enqueue_with_infallible(max_size, meta, f)
  309. .map_err(|_| SendError::BufferFull)?;
  310. net_trace!(
  311. "udp:{}:{}: buffer to send {} octets",
  312. self.endpoint,
  313. meta.endpoint,
  314. size
  315. );
  316. Ok(size)
  317. }
  318. /// Enqueue a packet to be sent to a given remote endpoint, and fill it from a slice.
  319. ///
  320. /// See also [send](#method.send).
  321. pub fn send_slice(
  322. &mut self,
  323. data: &[u8],
  324. meta: impl Into<UdpMetadata>,
  325. ) -> Result<(), SendError> {
  326. self.send(data.len(), meta)?.copy_from_slice(data);
  327. Ok(())
  328. }
  329. /// Dequeue a packet received from a remote endpoint, and return the endpoint as well
  330. /// as a pointer to the payload.
  331. ///
  332. /// This function returns `Err(Error::Exhausted)` if the receive buffer is empty.
  333. pub fn recv(&mut self) -> Result<(&[u8], UdpMetadata), RecvError> {
  334. let (remote_endpoint, payload_buf) =
  335. self.rx_buffer.dequeue().map_err(|_| RecvError::Exhausted)?;
  336. net_trace!(
  337. "udp:{}:{}: receive {} buffered octets",
  338. self.endpoint,
  339. remote_endpoint.endpoint,
  340. payload_buf.len()
  341. );
  342. Ok((payload_buf, remote_endpoint))
  343. }
  344. /// Dequeue a packet received from a remote endpoint, copy the payload into the given slice,
  345. /// and return the amount of octets copied as well as the endpoint.
  346. ///
  347. /// See also [recv](#method.recv).
  348. pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<(usize, UdpMetadata), RecvError> {
  349. let (buffer, endpoint) = self.recv().map_err(|_| RecvError::Exhausted)?;
  350. let length = min(data.len(), buffer.len());
  351. data[..length].copy_from_slice(&buffer[..length]);
  352. Ok((length, endpoint))
  353. }
  354. /// Peek at a packet received from a remote endpoint, and return the endpoint as well
  355. /// as a pointer to the payload without removing the packet from the receive buffer.
  356. /// This function otherwise behaves identically to [recv](#method.recv).
  357. ///
  358. /// It returns `Err(Error::Exhausted)` if the receive buffer is empty.
  359. pub fn peek(&mut self) -> Result<(&[u8], &UdpMetadata), RecvError> {
  360. let endpoint = self.endpoint;
  361. self.rx_buffer.peek().map_err(|_| RecvError::Exhausted).map(
  362. |(remote_endpoint, payload_buf)| {
  363. net_trace!(
  364. "udp:{}:{}: peek {} buffered octets",
  365. endpoint,
  366. remote_endpoint.endpoint,
  367. payload_buf.len()
  368. );
  369. (payload_buf, remote_endpoint)
  370. },
  371. )
  372. }
  373. /// Peek at a packet received from a remote endpoint, copy the payload into the given slice,
  374. /// and return the amount of octets copied as well as the endpoint without removing the
  375. /// packet from the receive buffer.
  376. /// This function otherwise behaves identically to [recv_slice](#method.recv_slice).
  377. ///
  378. /// See also [peek](#method.peek).
  379. pub fn peek_slice(&mut self, data: &mut [u8]) -> Result<(usize, &UdpMetadata), RecvError> {
  380. let (buffer, endpoint) = self.peek()?;
  381. let length = min(data.len(), buffer.len());
  382. data[..length].copy_from_slice(&buffer[..length]);
  383. Ok((length, endpoint))
  384. }
  385. pub(crate) fn accepts(&self, cx: &mut Context, ip_repr: &IpRepr, repr: &UdpRepr) -> bool {
  386. if self.endpoint.port != repr.dst_port {
  387. return false;
  388. }
  389. if self.endpoint.addr.is_some()
  390. && self.endpoint.addr != Some(ip_repr.dst_addr())
  391. && !cx.is_broadcast(&ip_repr.dst_addr())
  392. && !ip_repr.dst_addr().is_multicast()
  393. {
  394. return false;
  395. }
  396. true
  397. }
  398. pub(crate) fn process(
  399. &mut self,
  400. cx: &mut Context,
  401. meta: PacketMeta,
  402. ip_repr: &IpRepr,
  403. repr: &UdpRepr,
  404. payload: &[u8],
  405. ) {
  406. debug_assert!(self.accepts(cx, ip_repr, repr));
  407. let size = payload.len();
  408. let remote_endpoint = IpEndpoint {
  409. addr: ip_repr.src_addr(),
  410. port: repr.src_port,
  411. };
  412. net_trace!(
  413. "udp:{}:{}: receiving {} octets",
  414. self.endpoint,
  415. remote_endpoint,
  416. size
  417. );
  418. let metadata = UdpMetadata {
  419. endpoint: remote_endpoint,
  420. meta,
  421. };
  422. match self.rx_buffer.enqueue(size, metadata) {
  423. Ok(buf) => buf.copy_from_slice(payload),
  424. Err(_) => net_trace!(
  425. "udp:{}:{}: buffer full, dropped incoming packet",
  426. self.endpoint,
  427. remote_endpoint
  428. ),
  429. }
  430. #[cfg(feature = "async")]
  431. self.rx_waker.wake();
  432. }
  433. pub(crate) fn dispatch<F, E>(&mut self, cx: &mut Context, emit: F) -> Result<(), E>
  434. where
  435. F: FnOnce(&mut Context, PacketMeta, (IpRepr, UdpRepr, &[u8])) -> Result<(), E>,
  436. {
  437. let endpoint = self.endpoint;
  438. let hop_limit = self.hop_limit.unwrap_or(64);
  439. let res = self.tx_buffer.dequeue_with(|packet_meta, payload_buf| {
  440. let src_addr = match endpoint.addr {
  441. Some(addr) => addr,
  442. None => match cx.get_source_address(packet_meta.endpoint.addr) {
  443. Some(addr) => addr,
  444. None => {
  445. net_trace!(
  446. "udp:{}:{}: cannot find suitable source address, dropping.",
  447. endpoint,
  448. packet_meta.endpoint
  449. );
  450. return Ok(());
  451. }
  452. },
  453. };
  454. net_trace!(
  455. "udp:{}:{}: sending {} octets",
  456. endpoint,
  457. packet_meta.endpoint,
  458. payload_buf.len()
  459. );
  460. let repr = UdpRepr {
  461. src_port: endpoint.port,
  462. dst_port: packet_meta.endpoint.port,
  463. };
  464. let ip_repr = IpRepr::new(
  465. src_addr,
  466. packet_meta.endpoint.addr,
  467. IpProtocol::Udp,
  468. repr.header_len() + payload_buf.len(),
  469. hop_limit,
  470. );
  471. emit(cx, packet_meta.meta, (ip_repr, repr, payload_buf))
  472. });
  473. match res {
  474. Err(Empty) => Ok(()),
  475. Ok(Err(e)) => Err(e),
  476. Ok(Ok(())) => {
  477. #[cfg(feature = "async")]
  478. self.tx_waker.wake();
  479. Ok(())
  480. }
  481. }
  482. }
  483. pub(crate) fn poll_at(&self, _cx: &mut Context) -> PollAt {
  484. if self.tx_buffer.is_empty() {
  485. PollAt::Ingress
  486. } else {
  487. PollAt::Now
  488. }
  489. }
  490. }
  491. #[cfg(test)]
  492. mod test {
  493. use super::*;
  494. use crate::wire::{IpRepr, UdpRepr};
  495. use crate::phy::Medium;
  496. use crate::tests::setup;
  497. use rstest::*;
  498. fn buffer(packets: usize) -> PacketBuffer<'static> {
  499. PacketBuffer::new(
  500. (0..packets)
  501. .map(|_| PacketMetadata::EMPTY)
  502. .collect::<Vec<_>>(),
  503. vec![0; 16 * packets],
  504. )
  505. }
  506. fn socket(
  507. rx_buffer: PacketBuffer<'static>,
  508. tx_buffer: PacketBuffer<'static>,
  509. ) -> Socket<'static> {
  510. Socket::new(rx_buffer, tx_buffer)
  511. }
  512. const LOCAL_PORT: u16 = 53;
  513. const REMOTE_PORT: u16 = 49500;
  514. cfg_if::cfg_if! {
  515. if #[cfg(feature = "proto-ipv4")] {
  516. use crate::wire::Ipv4Address as IpvXAddress;
  517. use crate::wire::Ipv4Repr as IpvXRepr;
  518. use IpRepr::Ipv4 as IpReprIpvX;
  519. const LOCAL_ADDR: IpvXAddress = IpvXAddress([192, 168, 1, 1]);
  520. const REMOTE_ADDR: IpvXAddress = IpvXAddress([192, 168, 1, 2]);
  521. const OTHER_ADDR: IpvXAddress = IpvXAddress([192, 168, 1, 3]);
  522. } else {
  523. use crate::wire::Ipv6Address as IpvXAddress;
  524. use crate::wire::Ipv6Repr as IpvXRepr;
  525. use IpRepr::Ipv6 as IpReprIpvX;
  526. const LOCAL_ADDR: IpvXAddress = IpvXAddress([
  527. 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  528. ]);
  529. const REMOTE_ADDR: IpvXAddress = IpvXAddress([
  530. 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
  531. ]);
  532. const OTHER_ADDR: IpvXAddress = IpvXAddress([
  533. 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
  534. ]);
  535. }
  536. }
  537. pub const LOCAL_END: IpEndpoint = IpEndpoint {
  538. addr: LOCAL_ADDR.into_address(),
  539. port: LOCAL_PORT,
  540. };
  541. pub const REMOTE_END: IpEndpoint = IpEndpoint {
  542. addr: REMOTE_ADDR.into_address(),
  543. port: REMOTE_PORT,
  544. };
  545. pub const LOCAL_IP_REPR: IpRepr = IpReprIpvX(IpvXRepr {
  546. src_addr: LOCAL_ADDR,
  547. dst_addr: REMOTE_ADDR,
  548. next_header: IpProtocol::Udp,
  549. payload_len: 8 + 6,
  550. hop_limit: 64,
  551. });
  552. pub const REMOTE_IP_REPR: IpRepr = IpReprIpvX(IpvXRepr {
  553. src_addr: REMOTE_ADDR,
  554. dst_addr: LOCAL_ADDR,
  555. next_header: IpProtocol::Udp,
  556. payload_len: 8 + 6,
  557. hop_limit: 64,
  558. });
  559. pub const BAD_IP_REPR: IpRepr = IpReprIpvX(IpvXRepr {
  560. src_addr: REMOTE_ADDR,
  561. dst_addr: OTHER_ADDR,
  562. next_header: IpProtocol::Udp,
  563. payload_len: 8 + 6,
  564. hop_limit: 64,
  565. });
  566. const LOCAL_UDP_REPR: UdpRepr = UdpRepr {
  567. src_port: LOCAL_PORT,
  568. dst_port: REMOTE_PORT,
  569. };
  570. const REMOTE_UDP_REPR: UdpRepr = UdpRepr {
  571. src_port: REMOTE_PORT,
  572. dst_port: LOCAL_PORT,
  573. };
  574. const PAYLOAD: &[u8] = b"abcdef";
  575. #[test]
  576. fn test_bind_unaddressable() {
  577. let mut socket = socket(buffer(0), buffer(0));
  578. assert_eq!(socket.bind(0), Err(BindError::Unaddressable));
  579. }
  580. #[test]
  581. fn test_bind_twice() {
  582. let mut socket = socket(buffer(0), buffer(0));
  583. assert_eq!(socket.bind(1), Ok(()));
  584. assert_eq!(socket.bind(2), Err(BindError::InvalidState));
  585. }
  586. #[test]
  587. #[should_panic(expected = "the time-to-live value of a packet must not be zero")]
  588. fn test_set_hop_limit_zero() {
  589. let mut s = socket(buffer(0), buffer(1));
  590. s.set_hop_limit(Some(0));
  591. }
  592. #[test]
  593. fn test_send_unaddressable() {
  594. let mut socket = socket(buffer(0), buffer(1));
  595. assert_eq!(
  596. socket.send_slice(b"abcdef", REMOTE_END),
  597. Err(SendError::Unaddressable)
  598. );
  599. assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
  600. assert_eq!(
  601. socket.send_slice(
  602. b"abcdef",
  603. IpEndpoint {
  604. addr: IpvXAddress::UNSPECIFIED.into(),
  605. ..REMOTE_END
  606. }
  607. ),
  608. Err(SendError::Unaddressable)
  609. );
  610. assert_eq!(
  611. socket.send_slice(
  612. b"abcdef",
  613. IpEndpoint {
  614. port: 0,
  615. ..REMOTE_END
  616. }
  617. ),
  618. Err(SendError::Unaddressable)
  619. );
  620. assert_eq!(socket.send_slice(b"abcdef", REMOTE_END), Ok(()));
  621. }
  622. #[rstest]
  623. #[case::ip(Medium::Ip)]
  624. #[cfg(feature = "medium-ip")]
  625. #[case::ethernet(Medium::Ethernet)]
  626. #[cfg(feature = "medium-ethernet")]
  627. #[case::ieee802154(Medium::Ieee802154)]
  628. #[cfg(feature = "medium-ieee802154")]
  629. fn test_send_dispatch(#[case] medium: Medium) {
  630. let (mut iface, _, _) = setup(medium);
  631. let cx = iface.context();
  632. let mut socket = socket(buffer(0), buffer(1));
  633. assert_eq!(socket.bind(LOCAL_END), Ok(()));
  634. assert!(socket.can_send());
  635. assert_eq!(
  636. socket.dispatch(cx, |_, _, _| unreachable!()),
  637. Ok::<_, ()>(())
  638. );
  639. assert_eq!(socket.send_slice(b"abcdef", REMOTE_END), Ok(()));
  640. assert_eq!(
  641. socket.send_slice(b"123456", REMOTE_END),
  642. Err(SendError::BufferFull)
  643. );
  644. assert!(!socket.can_send());
  645. assert_eq!(
  646. socket.dispatch(cx, |_, _, (ip_repr, udp_repr, payload)| {
  647. assert_eq!(ip_repr, LOCAL_IP_REPR);
  648. assert_eq!(udp_repr, LOCAL_UDP_REPR);
  649. assert_eq!(payload, PAYLOAD);
  650. Err(())
  651. }),
  652. Err(())
  653. );
  654. assert!(!socket.can_send());
  655. assert_eq!(
  656. socket.dispatch(cx, |_, _, (ip_repr, udp_repr, payload)| {
  657. assert_eq!(ip_repr, LOCAL_IP_REPR);
  658. assert_eq!(udp_repr, LOCAL_UDP_REPR);
  659. assert_eq!(payload, PAYLOAD);
  660. Ok::<_, ()>(())
  661. }),
  662. Ok(())
  663. );
  664. assert!(socket.can_send());
  665. }
  666. #[rstest]
  667. #[case::ip(Medium::Ip)]
  668. #[cfg(feature = "medium-ip")]
  669. #[case::ethernet(Medium::Ethernet)]
  670. #[cfg(feature = "medium-ethernet")]
  671. #[case::ieee802154(Medium::Ieee802154)]
  672. #[cfg(feature = "medium-ieee802154")]
  673. fn test_recv_process(#[case] medium: Medium) {
  674. let (mut iface, _, _) = setup(medium);
  675. let cx = iface.context();
  676. let mut socket = socket(buffer(1), buffer(0));
  677. assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
  678. assert!(!socket.can_recv());
  679. assert_eq!(socket.recv(), Err(RecvError::Exhausted));
  680. assert!(socket.accepts(cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR));
  681. socket.process(
  682. cx,
  683. PacketMeta::default(),
  684. &REMOTE_IP_REPR,
  685. &REMOTE_UDP_REPR,
  686. PAYLOAD,
  687. );
  688. assert!(socket.can_recv());
  689. assert!(socket.accepts(cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR));
  690. socket.process(
  691. cx,
  692. PacketMeta::default(),
  693. &REMOTE_IP_REPR,
  694. &REMOTE_UDP_REPR,
  695. PAYLOAD,
  696. );
  697. assert_eq!(socket.recv(), Ok((&b"abcdef"[..], REMOTE_END.into())));
  698. assert!(!socket.can_recv());
  699. }
  700. #[rstest]
  701. #[case::ip(Medium::Ip)]
  702. #[cfg(feature = "medium-ip")]
  703. #[case::ethernet(Medium::Ethernet)]
  704. #[cfg(feature = "medium-ethernet")]
  705. #[case::ieee802154(Medium::Ieee802154)]
  706. #[cfg(feature = "medium-ieee802154")]
  707. fn test_peek_process(#[case] medium: Medium) {
  708. let (mut iface, _, _) = setup(medium);
  709. let cx = iface.context();
  710. let mut socket = socket(buffer(1), buffer(0));
  711. assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
  712. assert_eq!(socket.peek(), Err(RecvError::Exhausted));
  713. socket.process(
  714. cx,
  715. PacketMeta::default(),
  716. &REMOTE_IP_REPR,
  717. &REMOTE_UDP_REPR,
  718. PAYLOAD,
  719. );
  720. assert_eq!(socket.peek(), Ok((&b"abcdef"[..], &REMOTE_END.into(),)));
  721. assert_eq!(socket.recv(), Ok((&b"abcdef"[..], REMOTE_END.into(),)));
  722. assert_eq!(socket.peek(), Err(RecvError::Exhausted));
  723. }
  724. #[rstest]
  725. #[case::ip(Medium::Ip)]
  726. #[cfg(feature = "medium-ip")]
  727. #[case::ethernet(Medium::Ethernet)]
  728. #[cfg(feature = "medium-ethernet")]
  729. #[case::ieee802154(Medium::Ieee802154)]
  730. #[cfg(feature = "medium-ieee802154")]
  731. fn test_recv_truncated_slice(#[case] medium: Medium) {
  732. let (mut iface, _, _) = setup(medium);
  733. let cx = iface.context();
  734. let mut socket = socket(buffer(1), buffer(0));
  735. assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
  736. assert!(socket.accepts(cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR));
  737. socket.process(
  738. cx,
  739. PacketMeta::default(),
  740. &REMOTE_IP_REPR,
  741. &REMOTE_UDP_REPR,
  742. PAYLOAD,
  743. );
  744. let mut slice = [0; 4];
  745. assert_eq!(
  746. socket.recv_slice(&mut slice[..]),
  747. Ok((4, REMOTE_END.into()))
  748. );
  749. assert_eq!(&slice, b"abcd");
  750. }
  751. #[rstest]
  752. #[case::ip(Medium::Ip)]
  753. #[cfg(feature = "medium-ip")]
  754. #[case::ethernet(Medium::Ethernet)]
  755. #[cfg(feature = "medium-ethernet")]
  756. #[case::ieee802154(Medium::Ieee802154)]
  757. #[cfg(feature = "medium-ieee802154")]
  758. fn test_peek_truncated_slice(#[case] medium: Medium) {
  759. let (mut iface, _, _) = setup(medium);
  760. let cx = iface.context();
  761. let mut socket = socket(buffer(1), buffer(0));
  762. assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
  763. socket.process(
  764. cx,
  765. PacketMeta::default(),
  766. &REMOTE_IP_REPR,
  767. &REMOTE_UDP_REPR,
  768. PAYLOAD,
  769. );
  770. let mut slice = [0; 4];
  771. assert_eq!(
  772. socket.peek_slice(&mut slice[..]),
  773. Ok((4, &REMOTE_END.into()))
  774. );
  775. assert_eq!(&slice, b"abcd");
  776. assert_eq!(
  777. socket.recv_slice(&mut slice[..]),
  778. Ok((4, REMOTE_END.into()))
  779. );
  780. assert_eq!(&slice, b"abcd");
  781. assert_eq!(socket.peek_slice(&mut slice[..]), Err(RecvError::Exhausted));
  782. }
  783. #[rstest]
  784. #[case::ip(Medium::Ip)]
  785. #[cfg(feature = "medium-ip")]
  786. #[case::ethernet(Medium::Ethernet)]
  787. #[cfg(feature = "medium-ethernet")]
  788. #[case::ieee802154(Medium::Ieee802154)]
  789. #[cfg(feature = "medium-ieee802154")]
  790. fn test_set_hop_limit(#[case] medium: Medium) {
  791. let (mut iface, _, _) = setup(medium);
  792. let cx = iface.context();
  793. let mut s = socket(buffer(0), buffer(1));
  794. assert_eq!(s.bind(LOCAL_END), Ok(()));
  795. s.set_hop_limit(Some(0x2a));
  796. assert_eq!(s.send_slice(b"abcdef", REMOTE_END), Ok(()));
  797. assert_eq!(
  798. s.dispatch(cx, |_, _, (ip_repr, _, _)| {
  799. assert_eq!(
  800. ip_repr,
  801. IpReprIpvX(IpvXRepr {
  802. src_addr: LOCAL_ADDR,
  803. dst_addr: REMOTE_ADDR,
  804. next_header: IpProtocol::Udp,
  805. payload_len: 8 + 6,
  806. hop_limit: 0x2a,
  807. })
  808. );
  809. Ok::<_, ()>(())
  810. }),
  811. Ok(())
  812. );
  813. }
  814. #[rstest]
  815. #[case::ip(Medium::Ip)]
  816. #[cfg(feature = "medium-ip")]
  817. #[case::ethernet(Medium::Ethernet)]
  818. #[cfg(feature = "medium-ethernet")]
  819. #[case::ieee802154(Medium::Ieee802154)]
  820. #[cfg(feature = "medium-ieee802154")]
  821. fn test_doesnt_accept_wrong_port(#[case] medium: Medium) {
  822. let (mut iface, _, _) = setup(medium);
  823. let cx = iface.context();
  824. let mut socket = socket(buffer(1), buffer(0));
  825. assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
  826. let mut udp_repr = REMOTE_UDP_REPR;
  827. assert!(socket.accepts(cx, &REMOTE_IP_REPR, &udp_repr));
  828. udp_repr.dst_port += 1;
  829. assert!(!socket.accepts(cx, &REMOTE_IP_REPR, &udp_repr));
  830. }
  831. #[rstest]
  832. #[case::ip(Medium::Ip)]
  833. #[cfg(feature = "medium-ip")]
  834. #[case::ethernet(Medium::Ethernet)]
  835. #[cfg(feature = "medium-ethernet")]
  836. #[case::ieee802154(Medium::Ieee802154)]
  837. #[cfg(feature = "medium-ieee802154")]
  838. fn test_doesnt_accept_wrong_ip(#[case] medium: Medium) {
  839. let (mut iface, _, _) = setup(medium);
  840. let cx = iface.context();
  841. let mut port_bound_socket = socket(buffer(1), buffer(0));
  842. assert_eq!(port_bound_socket.bind(LOCAL_PORT), Ok(()));
  843. assert!(port_bound_socket.accepts(cx, &BAD_IP_REPR, &REMOTE_UDP_REPR));
  844. let mut ip_bound_socket = socket(buffer(1), buffer(0));
  845. assert_eq!(ip_bound_socket.bind(LOCAL_END), Ok(()));
  846. assert!(!ip_bound_socket.accepts(cx, &BAD_IP_REPR, &REMOTE_UDP_REPR));
  847. }
  848. #[test]
  849. fn test_send_large_packet() {
  850. // buffer(4) creates a payload buffer of size 16*4
  851. let mut socket = socket(buffer(0), buffer(4));
  852. assert_eq!(socket.bind(LOCAL_END), Ok(()));
  853. let too_large = b"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdefx";
  854. assert_eq!(
  855. socket.send_slice(too_large, REMOTE_END),
  856. Err(SendError::BufferFull)
  857. );
  858. assert_eq!(socket.send_slice(&too_large[..16 * 4], REMOTE_END), Ok(()));
  859. }
  860. #[rstest]
  861. #[case::ip(Medium::Ip)]
  862. #[cfg(feature = "medium-ip")]
  863. #[case::ethernet(Medium::Ethernet)]
  864. #[cfg(feature = "medium-ethernet")]
  865. #[case::ieee802154(Medium::Ieee802154)]
  866. #[cfg(feature = "medium-ieee802154")]
  867. fn test_process_empty_payload(#[case] medium: Medium) {
  868. let meta = Box::leak(Box::new([PacketMetadata::EMPTY]));
  869. let recv_buffer = PacketBuffer::new(&mut meta[..], vec![]);
  870. let mut socket = socket(recv_buffer, buffer(0));
  871. let (mut iface, _, _) = setup(medium);
  872. let cx = iface.context();
  873. assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
  874. let repr = UdpRepr {
  875. src_port: REMOTE_PORT,
  876. dst_port: LOCAL_PORT,
  877. };
  878. socket.process(cx, PacketMeta::default(), &REMOTE_IP_REPR, &repr, &[]);
  879. assert_eq!(socket.recv(), Ok((&[][..], REMOTE_END.into())));
  880. }
  881. #[test]
  882. fn test_closing() {
  883. let meta = Box::leak(Box::new([PacketMetadata::EMPTY]));
  884. let recv_buffer = PacketBuffer::new(&mut meta[..], vec![]);
  885. let mut socket = socket(recv_buffer, buffer(0));
  886. assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
  887. assert!(socket.is_open());
  888. socket.close();
  889. assert!(!socket.is_open());
  890. }
  891. }