From 69ba5584f34f5af81bc381494ef39a7a2c11da75 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 1 Dec 2020 14:56:38 -0800 Subject: [PATCH] network: correct parsing of reject messages Not all reject messages include a data field. This change partially addresses a problem that could lead to a depleted peer set: 1. We send a response to a `getheaders` message; 2. The remote peer `reject`s our `headers` message for some reason; 3. We fail to parse their `reject` message and close the connection; 4. Repeating this process, we have no more peers. This commit fixes (3) but does not address (2). --- zebra-network/src/protocol/external/codec.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/zebra-network/src/protocol/external/codec.rs b/zebra-network/src/protocol/external/codec.rs index 9c0599711..d867539c5 100644 --- a/zebra-network/src/protocol/external/codec.rs +++ b/zebra-network/src/protocol/external/codec.rs @@ -465,7 +465,14 @@ impl Codec { _ => return Err(Error::Parse("invalid RejectReason value in ccode field")), }, reason: reader.read_string()?, - data: Some(reader.read_32_bytes()?), + // Sometimes there's data, sometimes there isn't. There's no length + // field, this is just implicitly encoded by the body_len. + // Apparently all existing implementations only supply 32 bytes of + // data (hash identifying the rejected object) or none (and we model + // the Reject message that way), so instead of passing in the + // body_len separately and calculating remaining bytes, just try to + // read 32 bytes and ignore any failures. + data: reader.read_32_bytes().ok(), }) }