fn build_tcp_ack_packet(
idx: usize,
out: &mut [u8],
) -> Result<usize, &'static str>Expand description
指定ソケットへの ACK パケットを 組み立てるだけ で、送信はしない。
【2026-07-26 重要】以前はこの関数が transmit_nic_ipv4_packet() まで
行っており、しかも呼び出し元 parse_tcp_ipv4_packet が NET_LOCK を
保持したまま呼んでいた。送信経路は ARP キャッシュミス時に
build_usb_ethernet_ipv4_frame 内で最大 2 秒ブロッキングする
ARP 解決ループへ入り、そのループは内部で
poll_ethernet_data_plane_only() を回す。ポーリングは受信パケットを
parse_tcp_ipv4_packet / parse_udp_ipv4_packet へ流し、これらは
いずれも NET_LOCK を取得しようとするため、再入不可の spin::Mutex
に対する自己デッドロックになりうる。デッドロックに至らなくとも、
2 秒間 NET_LOCK を占有すると DNS 応答待ちループ
(udp_recv_matching も同じロックを取る)が自分のキューを確認できず、
dns response timeout が誘発される。
そのため組み立てと送信を分離し、送信はロック解放後に行う。