1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use super::*;
use crate::socket::tcp::Socket;
impl InterfaceInner {
pub(crate) fn process_tcp<'frame>(
&mut self,
sockets: &mut SocketSet,
handled_by_raw_socket: bool,
ip_repr: IpRepr,
ip_payload: &'frame [u8],
) -> Option<Packet<'frame>> {
let (src_addr, dst_addr) = (ip_repr.src_addr(), ip_repr.dst_addr());
// Per RFC 1122 ยง3.2.1.3, the unspecified address must never appear as a source
// or destination in any IP datagram. Drop such TCP segments early to avoid
// creating sockets with unspecified peers (which would later panic on egress).
// This is not done at the iface level because it might be useful with
// UDP or raw sockets, but it's definitely not useful for TCP.
if src_addr.is_unspecified() || dst_addr.is_unspecified() {
return None;
}
let tcp_packet = check!(TcpPacket::new_checked(ip_payload));
let tcp_repr = check!(TcpRepr::parse(
&tcp_packet,
&src_addr,
&dst_addr,
&self.caps.checksum
));
for tcp_socket in sockets
.items_mut()
.filter_map(|i| Socket::downcast_mut(&mut i.socket))
{
if tcp_socket.accepts(self, &ip_repr, &tcp_repr) {
return tcp_socket
.process(self, &ip_repr, &tcp_repr)
.map(|(ip, tcp)| Packet::new(ip, IpPayload::Tcp(tcp)));
}
}
if tcp_repr.control == TcpControl::Rst
|| ip_repr.dst_addr().is_unspecified()
|| ip_repr.src_addr().is_unspecified()
|| handled_by_raw_socket
{
// Never reply to a TCP RST packet with another TCP RST packet.
// Never send a TCP RST packet with unspecified addresses.
// Never send a TCP RST when packet has been handled by raw socket.
None
} else {
// The packet wasn't handled by a socket, send a TCP RST packet.
let (ip, tcp) = tcp::Socket::rst_reply(&ip_repr, &tcp_repr);
Some(Packet::new(ip, IpPayload::Tcp(tcp)))
}
}
}