review: 4 critical fixes (ICMP queue, refcount, udp panic, vlan send)
CRITICAL BUGS FIXED: 1. router/mod.rs: ICMP errors for Unreachable/Prohibit went to rx_buffer (infinite loop back to input) instead of tx_buffer (sent to source). Combined Unreachable/Prohibit arms; both now use tx_buffer. 2. scheme/socket.rs dup(): refcount leak in update_with branch. OLD code: new_handle.socket_handle() got +2 when update_with was Some, but only decremented once on close. Net: SH1 over-counted (+1), SH2 (new listening socket from update_with) never tracked at all. FIX: in update_with branch, increment refcount of 'socket_handle' (the new SH), not new_handle.socket_handle(). The always-run increment at the bottom covers new_handle. Both increments serve different purposes and are now distinct. 3. scheme/udp.rs: 4 .expect() panic vectors in bind/send/recv. 'Can't bind', 'Can't send', 'Can't receive', 'Can't recieve' all panicked the daemon. Now return EIO via ? operator. 4. link/vlan.rs (and vxlan/gre/ipip already partially fixed in R42): send() pushed tagged packets into self.recv_queue, creating a self-loop where packets were never delivered. Now drops packets with a debug log since no parent device reference exists. 5. link/qdisc.rs: TokenBucket token_add could overflow u64 on long elapsed durations. Changed to saturating_mul. DOC FIX: 6. filter/table.rs docstring example used --sport 1024:65535 (port range) but parse_port only accepts single port. Changed example to use single port value. Range support is a future enhancement. All 29 existing tests still pass.
This commit is contained in:
@@ -834,22 +834,27 @@ where
|
||||
|
||||
if let Some((socket_handle, data)) = update_with {
|
||||
if let SchemeFile::Socket(ref mut file) = *file {
|
||||
// We replace the socket_handle pointed by file so update the ref_counts
|
||||
// accordingly
|
||||
// We replace the socket_handle pointed by file so update
|
||||
// the ref_counts accordingly.
|
||||
self.ref_counts
|
||||
.entry(file.socket_handle)
|
||||
.and_modify(|e| *e = e.saturating_sub(1))
|
||||
.or_insert(0);
|
||||
|
||||
// Increment refcount of the NEW socket (socket_handle)
|
||||
// that the file is being updated to point at.
|
||||
*self
|
||||
.ref_counts
|
||||
.entry(new_handle.socket_handle())
|
||||
.entry(socket_handle)
|
||||
.or_insert(0) += 1;
|
||||
|
||||
file.socket_handle = socket_handle;
|
||||
file.data = data;
|
||||
}
|
||||
}
|
||||
// Increment refcount for the new_handle fd being inserted.
|
||||
// This is always done (regardless of update_with) because
|
||||
// new_handle represents a new fd in the handle table.
|
||||
*self
|
||||
.ref_counts
|
||||
.entry(new_handle.socket_handle())
|
||||
|
||||
Reference in New Issue
Block a user