Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dns: add support for Offline Usage with libp2p::SwarmBuilder with_dns #5903

Open
LVivona opened this issue Mar 4, 2025 · 4 comments
Open

Comments

@LVivona
Copy link

LVivona commented Mar 4, 2025

Description

I was running a local build and had with_dns enabled, but I didn't have Wi-Fi in this instance, which it understandably threw me the error.

Error: Custom { kind: Other, error: ResolveError { kind: Proto(ProtoError { kind: Io(Custom { kind: Other, error: "no nameservers found in config" }) }) } }

I'd like to avoid un-commenting it if possible and just have the function with_dns downgrade back to the previous step builder phase in the small case of testing within the builder SawmBuilder with_dns within a local environment without a connection to the internet.

Motivation

  • Enable offline peer-to-peer communication for nodes in environments lacking internet access, ensuring that DNS errors don't disrupt functionality.

Current Implementation

There exist not current implementation as I am aware. without commentating it in the instance to which I have no internet

let mut swarm  = libp2p::SwarmBuilder::with_new_identity() 
        .with_tokio()   // tokio runtime
        .with_tcp(      
            tcp::Config::default(), // tcp Config defautlt
            noise::Config::new,     
            yamux::Config::default,
        )? 
        .with_quic()    // quic, and udp on top of ip4/ip6
        // .with_dns()?
        .with_behaviour(|_| stream::Behaviour::new())?  // stream behavioud
        .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(10))) // duration of stream lasts 10 seconds until given up
        .build();

Are you planning to do it yourself in a pull request?

Yes

@LVivona LVivona changed the title dns: add Support for Offline Usage with libp2p::SwarmBuilder with_dns dns: add support for Offline Usage with libp2p::SwarmBuilder with_dns Mar 4, 2025
@LVivona
Copy link
Author

LVivona commented Mar 5, 2025

Just playing with it a bit I came up with this hacky solution. Though I would also note it might be better to introduce a jsut higher-order function, such as with_dns_default_on_local.

This function would attempt to apply the system DNS configuration, but if an error occur whether from system_conf it would seamlessly fall back to localhost DNS settings without logging a warning, keeping the main logic concise and maintainable.

transports/dns/src/lib.rs

...
pub fn system(inner: T) -> Result<Transport<T>, std::io::Error> {
    let (cfg, opts) = system_conf::read_system_conf().unwrap_or_else(|_| {
        tracing::warn!("Unable to read /etc/resolv.conf, using localhost DNS");
        (Self::localhost_resolver_config(), ResolverOpts::default())
    });

    Ok(Self::custom(inner, cfg, opts))
}

fn localhost_resolver_config() -> ResolverConfig {
    ResolverConfig::from_parts(
        None,
        vec![],
        vec![
            NameServerConfig {
                socket_addr: SocketAddr::new(
                    std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST),
                    53,
                ),
                protocol: hickory_resolver::proto::xfer::Protocol::Udp,
                tls_dns_name: None,
                http_endpoint: None,
                trust_negative_responses: false,
                bind_addr: None,
            },
            NameServerConfig {
                socket_addr: SocketAddr::new(
                    std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST),
                    53,
                ),
                protocol: hickory_resolver::proto::xfer::Protocol::Tcp,
                tls_dns_name: None,
                http_endpoint: None,
                trust_negative_responses: false,
                bind_addr: None,
            },
        ],
    )
}
...

@elenaf9
Copy link
Contributor

elenaf9 commented Mar 9, 2025

HI @LVivona, thanks for your detailed report.

There is already a function SwarnBuilder::with_dns_config that allows you to use a custom config like the one above. Does that help?

Generally I am wondering: wouldn't it be easier in your scenario to just add a feature flag that handles the case of a offline node, and build the transport with and without dns depending on that feature flag?
It seems a bit weird to me to create dns with a resolver that will then fail all dns requests, rather than just disabling dns completely.

@LVivona
Copy link
Author

LVivona commented Mar 9, 2025

Thanks for the reply, @elenaf9

You're right using custom setting withwith_dns_config along with a feature flag is probably the easiest and cleanest way to fix this. That definitely helps, so thank you! 🙂

I guess my follow-up, is whether localhost should still be considered within the scope of with_dns, since it inherently relies on local DNS resolution, or would at add to much bloat, since this is very niche case.

@elenaf9
Copy link
Contributor

elenaf9 commented Mar 9, 2025

What do you mean with local DNS resolution? Requests to the OS dns cache? Or are you running a local DNS resolver?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants