treebitmap icon indicating copy to clipboard operation
treebitmap copied to clipboard

Panic on remove()

Open ccakes opened this issue 6 years ago • 2 comments
trafficstars

I'm getting an occasional panic using this library on calling IpLookupTable.remove(). Panic location is below:

thread '<unnamed>' panicked at 'index out of bounds: the len is 0 but the index is 0', /cargo/registry/src/github.com-1ecc6299db9ec823/treebitmap-0.4.0/src/tree_bitmap/mod.rs:297:22

The Rust binary in question is processing a couple hundred full BGP feeds but the list of prefixes which trigger the panic is suspiciously small... 49.255.11.17/32 is by far the most frequent culprit. It doesn't seem to happen every time and I have yet to be able to reliably reproduce it in a simple example. All the prefixes that trigger the crashes are /32 IPv4 prefixes.

I added some debug logging and something looks odd. I started logging whenever I insert that prefix so I know it's been seen. Immediately before the panic I dump the table to a file and the prefix exists, however if I try to lookup the prefix using either exact_match() or longest_match() I get a None back..

I realise this is probably tricky to troubleshoot without a reliable reproduction, but any tips on where I can start looking? I tried a build with this line changed to an assert!() but it still gets past that, so something seems to be happening in remove_child()

ccakes avatar Jun 07 '19 18:06 ccakes

Actually - I can reproduce it with a pretty small example. This is using 0.4 from crates.io

use treebitmap::IpLookupTable;

use std::error::Error;
use std::net::Ipv4Addr;

const ADDR: Ipv4Addr = Ipv4Addr::new(49, 255, 11, 17);

fn main() -> Result<(), Box<dyn Error>> {
    let mut table = IpLookupTable::new();

    table.insert( Ipv4Addr::new(49, 255, 11, 16), 28, ());
    table.insert( ADDR, 32, ());

    println!("exact_match: {:?}", table.exact_match(ADDR, 32));
    println!("longest_match: {:?}", table.longest_match(ADDR));

    let v = table.remove(ADDR, 32);
    println!("removed: {:?}", v);

    Ok(())
}

ccakes avatar Jun 09 '19 14:06 ccakes

Looks like a bug with overlapping subnets.

pusateri avatar Jun 09 '19 18:06 pusateri