commit 08a262b9bd8293d8bae147e81383fb4ed17c728b from: murilo ijanc date: Fri Mar 27 02:00:05 2026 UTC Fix find_value_reply offset bug and increase recv buffer The find_value_reply handler used hardcoded offsets (off+24, off+26, off+28) that assumed ID_LEN=20, but ID_LEN is 32. This corrupted the NodeId field and left the flag byte as zero, causing receivers to reject the reply with "invalid message". Also increase the UDP recv buffer from 4096 to 65535 to prevent truncation of large value replies (which invalidates the Ed25519 signature). Promote signature verification failure log to DEBUG. commit - 557852ef3b2a4388f135fa0182adf7b84fc320b5 commit + 08a262b9bd8293d8bae147e81383fb4ed17c728b blob - 574aca329b91f08b7b7a6c58f4b7d42bfb190799 blob + 1ba3270aa01acc77f7f0cf095038ca0391b640c0 --- src/handlers.rs +++ src/handlers.rs @@ -721,14 +721,23 @@ impl Node { rbuf[off..off + 4].copy_from_slice(&fv.nonce.to_be_bytes()); fv.target .write_to(&mut rbuf[off + 4..off + 4 + crate::id::ID_LEN]); - rbuf[off + 24..off + 26].copy_from_slice(&0u16.to_be_bytes()); // index - rbuf[off + 26..off + 28].copy_from_slice(&1u16.to_be_bytes()); // total - rbuf[off + 28] = crate::wire::DATA_ARE_VALUES; - rbuf[off + 29] = 0; - rbuf[off + 30] = 0; - rbuf[off + 31] = 0; + let f = 4 + crate::id::ID_LEN; // 36 + rbuf[off + f..off + f + 2].copy_from_slice(&0u16.to_be_bytes()); // index + rbuf[off + f + 2..off + f + 4].copy_from_slice(&1u16.to_be_bytes()); // total + rbuf[off + f + 4] = crate::wire::DATA_ARE_VALUES; + rbuf[off + f + 5] = 0; + rbuf[off + f + 6] = 0; + rbuf[off + f + 7] = 0; rbuf[HEADER_SIZE + fixed..].copy_from_slice(&val.value); - let _ = self.send_signed(&rbuf, from); + match self.send_signed(&rbuf, from) { + Ok(n) => log::debug!( + "Sent find_value_reply ({} bytes) to {from}", + n + ), + Err(e) => log::warn!( + "Failed to send find_value_reply to {from}: {e}" + ), + } } } else { // Send closest nodes as find_node_reply format @@ -756,12 +765,13 @@ impl Node { rbuf[off..off + 4].copy_from_slice(&fv.nonce.to_be_bytes()); fv.target .write_to(&mut rbuf[off + 4..off + 4 + crate::id::ID_LEN]); - rbuf[off + 24..off + 26].fill(0); // index - rbuf[off + 26..off + 28].fill(0); // total - rbuf[off + 28] = crate::wire::DATA_ARE_NODES; - rbuf[off + 29] = 0; - rbuf[off + 30] = 0; - rbuf[off + 31] = 0; + let f = 4 + crate::id::ID_LEN; // 36 + rbuf[off + f..off + f + 2].fill(0); // index + rbuf[off + f + 2..off + f + 4].fill(0); // total + rbuf[off + f + 4] = crate::wire::DATA_ARE_NODES; + rbuf[off + f + 5] = 0; + rbuf[off + f + 6] = 0; + rbuf[off + f + 7] = 0; // Write nodes after the fixed part let nodes_off = HEADER_SIZE + msg::FIND_VALUE_REPLY_FIXED; blob - aa6d2a7231f301dd65dd7fca61f25d474b46fbc2 blob + 2f43775cdc914a772bfcefab4c32fa24b04f2ccf --- src/net.rs +++ src/net.rs @@ -716,7 +716,10 @@ impl Node { let pubkey = src.as_bytes(); if !crate::wire::verify_packet(buf, pubkey) { - log::trace!("Signature verification failed"); + log::debug!( + "Signature verification failed from {from} src={src:?} len={}", + buf.len() + ); self.metrics .packets_rejected .fetch_add(1, std::sync::atomic::Ordering::Relaxed); blob - 2c3cec98ae9d474b8ab3890d58ca080b1b16ff9a blob + fe347f36129ee1beceba8f6645e7160c0d07ccc5 --- src/node.rs +++ src/node.rs @@ -904,7 +904,7 @@ impl Node { let has_udp = self.net.drain_events().any(|ev| ev.token() == UDP_TOKEN); if has_udp { - let mut buf = [0u8; 4096]; + let mut buf = [0u8; 65535]; while let Ok((len, from)) = self.net.recv_from(&mut buf) { self.handle_packet(&buf[..len], from); }