swift-nav/libsbp

Rust parser does not continue parsing after CRC error

Closed this issue · 5 comments

When a ParserError occurs, the rust parser correctly advances the buffer:
https://github.com/swift-nav/libsbp/blob/master/rust/sbp/src/parser/mod.rs#L138

However, other error types (including a CRC error) do not advance the buffer. Subsequent calls to .parse() will parse the same data and continue to return the same error type. The buffer is still full, so read_more will not be called.

Thanks for reporting this issue! Can you describe how you're invoking the parser that's causing this issue to manifest?

Hi Jason,

My code looks something like this:

let mut parser = sbp::parser::Parser::new();
let mut stream = TcpStream::connect(&addr)?;

loop {
    match parser.parse(&mut stream) {
        Ok(msg) => { }, /// handle parsed packet

        Err(Error::IoError(ref x)) if x.kind() == std::io::ErrorKind::WouldBlock => {
            // No data available. We do not expect to hit this as the socket is blocking.
            continue;
        },
        Err(Error::NotEnoughData) => {
            // Not enough data available.
            continue;
        },

        Err(Error::ParseError) => {
            // The sbp driver correctly handles this error. We can try again.
            continue;
        }

        e @ Err(Error::CrcError) | e @ Err(Error::UnrecoverableFailure) => {
            // The sbp driver does not correctly handle CrcError or UnrecoverableFailure. 
            // The only way to resolve these error types is to create a new parser.
            error!("{:?}", e);
            parser = sbp::parser::Parser::new();
            continue;
        }

        Err(Error::IoError(ref e)) => {
            // std::io::ErrorKind::UnexpectedEof indicates server closed connection.
            // Other std::io error types may also render the connection unusable. 
            // Break out of the inner loop and try to reconnect to the server.
            error!("{:?}", e);
            break;
        },
    }
}

As described above- in the event of a CrcError I am constructing a new parser to work around this bug.

Also note- I have not seen this with actual hardware- only with simulated packets! (obviously it would be very unusual to see a CRC error with a TCP/Ethernet setup and working hardware). The way I simulated it was by creating a TCP server that serves valid SBP packets, with a couple invalid bytes thrown in the middle. The parser correctly identifies the CRC error, but does not advance the buffer (as initially reported).

We have a potential fix in #798 -- if you'd like to try it out you can reference the fix revision in your Cargo.toml:

[dependencies.sbp]
git = "https://github.com/swift-nav/libsbp.git"
rev = "6280860ebb6dfa46bb163b3287639c9b35f01dd4"

Hi Jason- I just tested (sorry for the delay), works great for me! Thanks

@stabler Great! Glad to hear it!