From d18936632616a2dbf1d5276993fb26e14d6e37d4 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 19 Sep 2025 11:39:45 +0000 Subject: [PATCH 1/3] Correct DoH base64 alphabet to base64url not base64 DoH is supposed to require the base64url encoding of the DNS request, but our encoder was actually using classic base64. While this is incorrect, it appears many (most?) DoH resolvers will actually accept base64 just fine. Still, best to swap for the correct alphabet, which we do here. Fixes #12 --- src/http_resolver.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/http_resolver.rs b/src/http_resolver.rs index 2bd5b2d..44fc972 100644 --- a/src/http_resolver.rs +++ b/src/http_resolver.rs @@ -51,11 +51,12 @@ impl Default for HTTPHrnResolver { } } +/// The "URL and Filename safe" Base64 Alphabet from RFC 4648 const B64_CHAR: [u8; 64] = [ b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O', b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', b'Z', b'a', b'b', b'c', b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', - b'w', b'x', b'y', b'z', b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'+', b'/', + b'w', b'x', b'y', b'z', b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'-', b'_', ]; #[rustfmt::skip] From e8c6348063cb52ea1e892feabce95860071b04f5 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 19 Sep 2025 11:50:10 +0000 Subject: [PATCH 2/3] Document that OM-based HRN resolution futures do not time out Fixes #11 --- src/onion_message_resolver.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/onion_message_resolver.rs b/src/onion_message_resolver.rs index 5bdc7ab..44def40 100644 --- a/src/onion_message_resolver.rs +++ b/src/onion_message_resolver.rs @@ -85,6 +85,10 @@ fn channel() -> (ChannelSend, ChannelRecv) { /// This implements LDK's [`DNSResolverMessageHandler`], which it uses to send onion messages and /// process response messages. /// +/// Note that because this implementation does not assume an async runtime, queries which are not +/// responded to *may hang forever*. You must always wrap resolution futures to ensure they time +/// out properly, eg via `tokio::time::timeout`. +/// /// Note that after a query begines, [`PeerManager::process_events`] should be called to ensure the /// query message goes out in a timely manner. You can call [`Self::register_post_queue_action`] to /// have this happen automatically. From dc044a8b4421437559376a72f67ec5fdf5695c24 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 19 Sep 2025 16:53:39 +0000 Subject: [PATCH 3/3] Make `onion_message_resolver` tests more robust by reconnecting --- src/onion_message_resolver.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/onion_message_resolver.rs b/src/onion_message_resolver.rs index 44def40..071ac1d 100644 --- a/src/onion_message_resolver.rs +++ b/src/onion_message_resolver.rs @@ -347,13 +347,19 @@ mod tests { let peer_manager = Arc::new(PeerManager::new(handlers, 0, &rand, &TestLogger, Arc::clone(&signer))); - // Connect to a static LDK node which we know will do DNS resolutions for us. + // Maintain a connection to a static LDK node which we know will do DNS resolutions for us. let their_id_hex = "03db10aa09ff04d3568b0621750794063df401e6853c79a21a83e1a3f3b5bfb0c8"; let their_id = PublicKey::from_slice(&Vec::::from_hex(their_id_hex).unwrap()).unwrap(); let addr = "ldk-ln-node.bitcoin.ninja:9735".to_socket_addrs().unwrap().next().unwrap(); - let _ = lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), their_id, addr) - .await - .unwrap(); + let connect_pm = Arc::clone(&peer_manager); + tokio::spawn(async move { + loop { + lightning_net_tokio::connect_outbound(Arc::clone(&connect_pm), their_id, addr) + .await + .unwrap() + .await; + } + }); let pm_reference = Arc::clone(&peer_manager); tokio::spawn(async move {