From 8270371e783c9549d94ead54529e8d5e01a72861 Mon Sep 17 00:00:00 2001 From: teor Date: Fri, 4 Feb 2022 17:06:53 +1000 Subject: [PATCH] fix(inbound): move address sanitization into the response future --- zebrad/src/components/inbound.rs | 48 +++++++++++++++++--------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/zebrad/src/components/inbound.rs b/zebrad/src/components/inbound.rs index 734af935269..d3cfb52ea94 100644 --- a/zebrad/src/components/inbound.rs +++ b/zebrad/src/components/inbound.rs @@ -307,31 +307,33 @@ impl Service for Inbound { // # Correctness // // Briefly hold the address book threaded mutex while - // cloning the address book. Then sanitize after releasing - // the lock. + // cloning the address book. Then sanitize in the future, + // after releasing the lock. let peers = address_book.lock().unwrap().clone(); - // Correctness: get the current time after acquiring the address book lock. - let now = Utc::now(); - - // Send a sanitized response - let mut peers = peers.sanitized(now); - - // Truncate the list - // - // TODO: replace with div_ceil once it stabilises - // https://github.com/rust-lang/rust/issues/88581 - let address_limit = (peers.len() + ADDR_RESPONSE_LIMIT_DENOMINATOR - 1) / ADDR_RESPONSE_LIMIT_DENOMINATOR; - let address_limit = MAX_ADDRS_IN_MESSAGE - .min(address_limit); - peers.truncate(address_limit); - - if !peers.is_empty() { - async { Ok(zn::Response::Peers(peers)) }.boxed() - } else { - debug!("ignoring `Peers` request from remote peer because our address book is empty"); - async { Ok(zn::Response::Nil) }.boxed() - } + async move { + // Correctness: get the current time after acquiring the address book lock. + let now = Utc::now(); + + // Send a sanitized response + let mut peers = peers.sanitized(now); + + // Truncate the list + // + // TODO: replace with div_ceil once it stabilises + // https://github.com/rust-lang/rust/issues/88581 + let address_limit = (peers.len() + ADDR_RESPONSE_LIMIT_DENOMINATOR - 1) / ADDR_RESPONSE_LIMIT_DENOMINATOR; + let address_limit = MAX_ADDRS_IN_MESSAGE.min(address_limit); + peers.truncate(address_limit); + + if peers.is_empty() { + // We don't know if the peer response will be empty until we've sanitized them. + debug!("ignoring `Peers` request from remote peer because our address book is empty"); + Ok(zn::Response::Nil) + } else { + Ok(zn::Response::Peers(peers)) + } + }.boxed() } zn::Request::BlocksByHash(hashes) => { // Correctness: