Use IPv6 'next header' for TCP routing

This commit is contained in:
Aram 🍐 2021-10-16 02:06:03 -04:00
parent 9aea0fce33
commit 660183b1c4

View file

@ -278,16 +278,12 @@ impl WireGuardTunnel {
// Only care if the packet is destined for this tunnel // Only care if the packet is destined for this tunnel
.filter(|packet| Ipv4Addr::from(packet.dst_addr()) == self.source_peer_ip) .filter(|packet| Ipv4Addr::from(packet.dst_addr()) == self.source_peer_ip)
.map(|packet| match packet.protocol() { .map(|packet| match packet.protocol() {
IpProtocol::Tcp => Some( IpProtocol::Tcp => Some(self.route_tcp_segment(
self.route_tcp_segment( IpVersion::Ipv4,
IpVersion::Ipv4, packet.src_addr().into(),
packet.src_addr().into(), packet.dst_addr().into(),
packet.dst_addr().into(), packet.payload(),
packet.payload(), )),
)
// Note: Ipv4 drops invalid TCP packets when the specified protocol says that it should be TCP
.unwrap_or(RouteResult::Drop),
),
// Unrecognized protocol, so we'll allow it. // Unrecognized protocol, so we'll allow it.
_ => Some(RouteResult::Broadcast), _ => Some(RouteResult::Broadcast),
}) })
@ -297,17 +293,17 @@ impl WireGuardTunnel {
.ok() .ok()
// Only care if the packet is destined for this tunnel // Only care if the packet is destined for this tunnel
.filter(|packet| Ipv6Addr::from(packet.dst_addr()) == self.source_peer_ip) .filter(|packet| Ipv6Addr::from(packet.dst_addr()) == self.source_peer_ip)
.map(|packet| { .map(|packet| match packet.next_header() {
self.route_tcp_segment( IpProtocol::Tcp => Some(self.route_tcp_segment(
IpVersion::Ipv6, IpVersion::Ipv6,
packet.src_addr().into(), packet.src_addr().into(),
packet.dst_addr().into(), packet.dst_addr().into(),
packet.payload(), packet.payload(),
) )),
// Note: Since Ipv6 doesn't inform us of the protocol at this layer, // Unrecognized protocol, so we'll allow it.
// we should broadcast unrecognized packets. _ => Some(RouteResult::Broadcast),
.unwrap_or(RouteResult::Broadcast)
}) })
.flatten()
.unwrap_or(RouteResult::Drop), .unwrap_or(RouteResult::Drop),
_ => RouteResult::Drop, _ => RouteResult::Drop,
} }
@ -321,24 +317,27 @@ impl WireGuardTunnel {
src_addr: IpAddress, src_addr: IpAddress,
dst_addr: IpAddress, dst_addr: IpAddress,
segment: &[u8], segment: &[u8],
) -> Option<RouteResult> { ) -> RouteResult {
TcpPacket::new_checked(segment).ok().map(|tcp| { TcpPacket::new_checked(segment)
if self.port_pool.is_in_use(tcp.dst_port()) { .ok()
RouteResult::Broadcast .map(|tcp| {
} else if tcp.rst() { if self.port_pool.is_in_use(tcp.dst_port()) {
RouteResult::Drop RouteResult::Broadcast
} else { } else if tcp.rst() {
// Port is not in use, but it's a TCP packet so we'll craft a RST. RouteResult::Drop
RouteResult::TcpReset(craft_tcp_rst_reply( } else {
ip_version, // Port is not in use, but it's a TCP packet so we'll craft a RST.
src_addr, RouteResult::TcpReset(craft_tcp_rst_reply(
tcp.src_port(), ip_version,
dst_addr, src_addr,
tcp.dst_port(), tcp.src_port(),
tcp.ack_number(), dst_addr,
)) tcp.dst_port(),
} tcp.ack_number(),
}) ))
}
})
.unwrap_or(RouteResult::Drop)
} }
} }