fix icmp proxy on MacOS (#101)

1. MacOS doesn't fill length field in ip header when recving from raw
socket
2. Fix udp & icmp subnet proxy not work when no p2p connection.
This commit is contained in:
Sijie.Sun 2024-05-10 21:40:29 +08:00 committed by GitHub
parent 2a728482fa
commit b1153378c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 5 deletions

View File

@ -80,8 +80,8 @@ fn socket_recv(socket: &Socket, buf: &mut [MaybeUninit<u8>]) -> Result<(usize, I
}
fn socket_recv_loop(socket: Socket, nat_table: IcmpNatTable, sender: UnboundedSender<ZCPacket>) {
let mut buf = [0u8; 4096];
let data: &mut [MaybeUninit<u8>] = unsafe { std::mem::transmute(&mut buf[12..]) };
let mut buf = [0u8; 2048];
let data: &mut [MaybeUninit<u8>] = unsafe { std::mem::transmute(&mut buf[..]) };
loop {
let Ok((len, peer_ip)) = socket_recv(&socket, data) else {
@ -92,7 +92,7 @@ fn socket_recv_loop(socket: Socket, nat_table: IcmpNatTable, sender: UnboundedSe
continue;
}
let Some(mut ipv4_packet) = MutableIpv4Packet::new(&mut buf[12..12 + len]) else {
let Some(mut ipv4_packet) = MutableIpv4Packet::new(&mut buf[..len]) else {
continue;
};
@ -121,6 +121,10 @@ fn socket_recv_loop(socket: Socket, nat_table: IcmpNatTable, sender: UnboundedSe
};
ipv4_packet.set_destination(dest_ip);
// MacOS do not correctly set ip length when receiving from raw socket
ipv4_packet.set_total_length(len as u16);
ipv4_packet.set_checksum(ipv4::checksum(&ipv4_packet.to_immutable()));
let mut p = ZCPacket::new_with_payload(ipv4_packet.packet());

View File

@ -347,7 +347,7 @@ impl PeerManager {
let mut zc_packet = Some(ret);
let mut idx = 0;
for pipeline in pipe_line.read().await.iter().rev() {
tracing::debug!(?zc_packet, ?idx, "try_process_packet_from_peer");
tracing::trace!(?zc_packet, ?idx, "try_process_packet_from_peer");
idx += 1;
zc_packet = pipeline
.try_process_packet_from_peer(zc_packet.unwrap())
@ -519,7 +519,13 @@ impl PeerManager {
}
pub async fn send_msg(&self, msg: ZCPacket, dst_peer_id: PeerId) -> Result<(), Error> {
self.peers.send_msg(msg, dst_peer_id).await
if let Some(gateway) = self.peers.get_gateway_peer_id(dst_peer_id).await {
self.peers.send_msg_directly(msg, gateway).await
} else if self.foreign_network_client.has_next_hop(dst_peer_id) {
self.foreign_network_client.send_msg(msg, dst_peer_id).await
} else {
Err(Error::RouteError(None))
}
}
pub async fn send_msg_ipv4(&self, mut msg: ZCPacket, ipv4_addr: Ipv4Addr) -> Result<(), Error> {