smoltcp/iface/interface/
tcp.rs

1use super::*;
2
3use crate::socket::tcp::Socket;
4
5impl InterfaceInner {
6    pub(crate) fn process_tcp<'frame>(
7        &mut self,
8        sockets: &mut SocketSet,
9        ip_repr: IpRepr,
10        ip_payload: &'frame [u8],
11    ) -> Option<Packet<'frame>> {
12        let (src_addr, dst_addr) = (ip_repr.src_addr(), ip_repr.dst_addr());
13        let tcp_packet = check!(TcpPacket::new_checked(ip_payload));
14        let tcp_repr = check!(TcpRepr::parse(
15            &tcp_packet,
16            &src_addr,
17            &dst_addr,
18            &self.caps.checksum
19        ));
20
21        for tcp_socket in sockets
22            .items_mut()
23            .filter_map(|i| Socket::downcast_mut(&mut i.socket))
24        {
25            if tcp_socket.accepts(self, &ip_repr, &tcp_repr) {
26                return tcp_socket
27                    .process(self, &ip_repr, &tcp_repr)
28                    .map(|(ip, tcp)| Packet::new(ip, IpPayload::Tcp(tcp)));
29            }
30        }
31
32        if tcp_repr.control == TcpControl::Rst
33            || ip_repr.dst_addr().is_unspecified()
34            || ip_repr.src_addr().is_unspecified()
35        {
36            // Never reply to a TCP RST packet with another TCP RST packet. We also never want to
37            // send a TCP RST packet with unspecified addresses.
38            None
39        } else {
40            // The packet wasn't handled by a socket, send a TCP RST packet.
41            let (ip, tcp) = tcp::Socket::rst_reply(&ip_repr, &tcp_repr);
42            Some(Packet::new(ip, IpPayload::Tcp(tcp)))
43        }
44    }
45}