capsules_extra/net/udp/
udp_recv.rs
1use crate::net::ipv6::ip_utils::IPAddr;
16use crate::net::ipv6::ipv6_recv::IP6RecvClient;
17use crate::net::ipv6::IP6Header;
18use crate::net::udp::driver::UDPDriver;
19use crate::net::udp::udp_port_table::{PortQuery, UdpPortBindingRx};
20use crate::net::udp::UDPHeader;
21
22use kernel::collections::list::{List, ListLink, ListNode};
23use kernel::debug;
24use kernel::utilities::cells::{MapCell, OptionalCell};
25
26pub struct MuxUdpReceiver<'a> {
27 rcvr_list: List<'a, UDPReceiver<'a>>,
28 driver: OptionalCell<&'static UDPDriver<'static>>,
29}
30
31impl<'a> MuxUdpReceiver<'a> {
32 pub fn new() -> MuxUdpReceiver<'a> {
33 MuxUdpReceiver {
34 rcvr_list: List::new(),
35 driver: OptionalCell::empty(),
36 }
37 }
38
39 pub fn add_client(&self, rcvr: &'a UDPReceiver<'a>) {
40 self.rcvr_list.push_tail(rcvr);
41 }
42
43 pub fn set_driver(&self, driver_ref: &'static UDPDriver) {
44 self.driver.replace(driver_ref);
45 }
46}
47
48impl IP6RecvClient for MuxUdpReceiver<'_> {
49 fn receive(&self, ip_header: IP6Header, payload: &[u8]) {
50 match UDPHeader::decode(payload).done() {
51 Some((offset, udp_header)) => {
52 let len = udp_header.get_len() as usize;
53 let dst_port = udp_header.get_dst_port();
54 if len > payload.len() {
55 debug!("[UDP_RECV] Error: Received UDP length too long");
56 return;
57 }
58 for rcvr in self.rcvr_list.iter() {
59 match rcvr.binding.take() {
60 Some(binding) => {
61 if binding.get_port() == dst_port {
62 rcvr.client.map(|client| {
63 client.receive(
64 ip_header.get_src_addr(),
65 ip_header.get_dst_addr(),
66 udp_header.get_src_port(),
67 udp_header.get_dst_port(),
68 &payload[offset..],
69 );
70 });
71 rcvr.binding.replace(binding);
72 break;
73 }
74 rcvr.binding.replace(binding);
75 }
76 None => match self.driver.take() {
78 Some(driver) => {
79 if driver.is_bound(dst_port) {
80 driver.receive(
81 ip_header.get_src_addr(),
82 ip_header.get_dst_addr(),
83 udp_header.get_src_port(),
84 udp_header.get_dst_port(),
85 &payload[offset..],
86 );
87 self.driver.replace(driver);
88 break;
89 }
90 self.driver.replace(driver);
91 }
92 None => {}
93 },
94 }
95 }
96 }
97 None => {}
98 }
99 }
100}
101
102pub trait UDPRecvClient {
109 fn receive(
110 &self,
111 src_addr: IPAddr,
112 dst_addr: IPAddr,
113 src_port: u16,
114 dst_port: u16,
115 payload: &[u8],
116 );
117}
118
119pub struct UDPReceiver<'a> {
123 client: OptionalCell<&'a dyn UDPRecvClient>,
124 binding: MapCell<UdpPortBindingRx>,
125 next: ListLink<'a, UDPReceiver<'a>>,
126}
127
128impl<'a> ListNode<'a, UDPReceiver<'a>> for UDPReceiver<'a> {
129 fn next(&'a self) -> &'a ListLink<'a, UDPReceiver<'a>> {
130 &self.next
131 }
132}
133
134impl<'a> UDPReceiver<'a> {
135 pub fn new() -> UDPReceiver<'a> {
136 UDPReceiver {
137 client: OptionalCell::empty(),
138 binding: MapCell::empty(),
139 next: ListLink::empty(),
140 }
141 }
142
143 pub fn set_client(&self, client: &'a dyn UDPRecvClient) {
144 self.client.set(client);
145 }
146
147 pub fn get_binding(&self) -> Option<UdpPortBindingRx> {
148 self.binding.take()
149 }
150
151 pub fn is_bound(&self) -> bool {
152 self.binding.is_some()
153 }
154
155 pub fn set_binding(&self, binding: UdpPortBindingRx) -> Option<UdpPortBindingRx> {
156 self.binding.replace(binding)
157 }
158}