simple-mdns 0.1.1

Rust implementation of mDNS for service discovering (DNS-SD)
Documentation

Simple mDNS

Pure Rust implementation for mDNS and DNS-SD protocols

ServiceDiscovery

Advertise registered addresses and query for available instances on the same network.

    use simple_mdns::ServiceDiscovery;
    use std::net::SocketAddr;

    let mut discovery = ServiceDiscovery::new("_mysrv._tcp.local", 60, true).expect("Invalid Service Name");
    let my_socket_addr = "192.168.1.22:8090".parse().unwrap();
    discovery.add_socket_address(my_socket_addr);

OneShotMdnsResolver (Legacy mDNS)

One shot resolvers are considered legacy and not fully compliant with the mDNS protocol, but they are handy for service discovery if you have (or need) only one service instance

How it works

One shot resolvers or queries send a multicast DNS question to discover available services in the network.

  • Only the IP address is necessary (port is fixed or already known), a A or AAAA question is sent.
  • IP address and port are necessary, a SRV question is sent.

Since mDNS is a well known protocol, you can register your service in any mDNS responder inside your network, and they should be able to reply the requested information about your service.

Query example:

    let resolver = OneShotMdnsResolver::new();
    // querying for IP Address
    let answer = resolver.query_service_address("_myservice._tcp.local").await.unwrap();
    println!("{:?}", answer);
    // IpV4Addr or IpV6Addr, depending on what was returned
    
    let answer = resolver.query_service_address_and_port("_myservice._tcp.local").await.unwrap();
    println!("{:?}", answer);
    // SocketAddr, "127.0.0.1:8080", with a ipv4 or ipv6

SimpleMdnsResponder

In case you don't have a mDNS responder in your network, or for some reason don't want to use the ones available.

This responder will list for any mDNS query in the network via Multicast and will reply only to the resources that were added.

     let mut responder = SimpleMdnsResponder::new(10, true);
     let srv_name = Name::new_unchecked("_srvname._tcp.local");

     responder.add_resource(ResourceRecord {
         class: CLASS::IN,
         name: srv_name.clone(),
         ttl: 10,
         rdata: RData::A(A { address: Ipv4Addr::LOCALHOST.into() }),
     });

     responder.add_resource(ResourceRecord {
         class: CLASS::IN,
         name: srv_name.clone(),
         ttl: 10,
         rdata: RData::SRV(Box::new(SRV {
             port: 8080,
             priority: 0,
             weight: 0,
             target: srv_name
         }))
     });

TODOs

  • IPv6 queries
  • Support to runtimes other than Tokio