Comments (4)
I suggest adding "mDNS" to the issue title.
There are two parts to this: Querying and responding (serving). It isn't possible to implement serving without querying because the first step of serving is "[...] for all those resource records that a Multicast DNS responder desires to be unique on the local link, it MUST send a Multicast DNS query asking for those resource records, to see if any of them are already in use." This implies that querying should be implemented first.
Regarding responding, ideally a multicast DNS responder implementation will be very compact; i.e. .the size considerations that prompted the minimization work for the resolver would also apply to the multicast DNS responder. In particular, it would be great to be able to embed the responder into a tiny IoT-like device.
from hickory-dns.
Note also that Multicast DNS reserves special semantics to ".local" addresses:
This document specifies that the DNS top-level domain ".local." is a
special domain with special semantics, namely that any fully
qualified name ending in ".local." is link-local, and names within
this domain are meaningful only on the link where they originate.
This is analogous to IPv4 addresses in the 169.254/16 prefix or IPv6
addresses in the FE80::/10 prefix, which are link-local and
meaningful only on the link where they originate.Any DNS query for a name ending with ".local." MUST be sent to the
mDNS IPv4 link-local multicast address 224.0.0.251 (or its IPv6
equivalent FF02::FB). The design rationale for using a fixed
multicast address instead of selecting from a range of multicast
addresses using a hash function is discussed in Appendix B.
Implementers MAY choose to look up such names concurrently via other
mechanisms (e.g., Unicast DNS) and coalesce the results in some
fashion.
from hickory-dns.
My current plan is to build two implementations (not sure if they will be new crates yet). There will be a new trust_dns_proto::MuticastStream
, which is nearly identical to trust_dns_proto::UdpStream
. I want to try and just use UdpStream
under the covers. The Client
will be able to send one-shot
, https://tools.ietf.org/html/rfc6762#section-5, queries using this stream.
For the resolution, the Resolver
will gain a new multicast resolution component through the NameServerPool
. multicast_conns
will be a new field, with IPv4 and IPv6 associated (thought I'm not yet sure about registering IPv6 and IPv4 at the same time here, that might create unnecessary duplication of multicast messages on the network). https://tools.ietf.org/html/rfc6762#section-20 only discusses IPv4 and IPv6 from the stand-point of registration, and doesn't give good guidance on query implementations. The RFC mentions allowing other non-.local.
queries to be sent via multicast. My plan would be this:
{
if name in zone `.local.` query only via multicast;
else query default registered nameservers;
on failure attempt to resolve via multicast with a one-shot query;
}
This will make multicast only a last resort for non-.local.
names, of course this logic could always be triggered by not adding any default nameservers. One negative issue with the continuous mDNS record maintenance is that queries are intended to be actively requested for names that are queried. This would require a background processing thread to maintain a consistent schedule (I don't think we should spin up additional threads in the Resolver
, so this seems like a non-starter). The other option would be to only perform this maintenance on the primary thread on a turn of the Resolver
s event loop (this will be the initial implementation) by utilizing the fact that multiple queries can be safely associated to a single DNS packet, this option seems reasonable. This does mean that records could go stale over longer periods, but why put traffic on the network when nothing is actually requesting names. It might be worthwhile to give an API into the maintenance method such that in cases where the Resolver
is embedded in other software, that software could spin up an additional thread and call the query maintenance method on a fixed schedule.
For a multicast dns responder my current plan is to modify the Server
to add a special authority for registering .local.
names and service all multicast requests that are received. The Server
can be managed either through dynamic dns, or if it's embedded, a direct API should be added for managing the .local.
Authority. Query forwarding will not be implemented as part of the initial mDNS support in the server. This can be added at the same point that general purpose forwarding is built in.
from hickory-dns.
I've run into a complexity on implementing mDNS support. I can easily create one-shot DNS queries. It's also possible to create a server that receives multicast packets. But on existing operating systems that already support mDNS, we can not create another "continuous", fully compliant, mDNS responder. This is due to the fact that we can no reuse the address that is owned by the host OS, specifically 0.0.0.0:5353
and/or [::0]:5353
. If the operating system has some means of creating network namespaces, like LXC or Docker, or somehow getting a separate IP, then this wouldn't necessarily be a blocker, but would require running in a container.
This is a bit of a bummer, as there is not good reason why the spec doesn't allow this. What is possibly is to bind a listening address directly to the mDNS well-known multicast address and port 5353
, as is required by the multicast spec for UDP, but this is only one half of the equation.
One option for the server is to create dual sockets, one for receiving bound to the UDP multicast addresses, and then one for replies bound to a random port and address. It's not clear at this point whether standard mDNS clients out there would accept responses that don't come from some address specifically from port 5353 (they might accept any response). For the client/respolver, it's more egregious in that mDNS responders will assume that the client is not fully mDNS compliant if it does not send packets from port 5353, not doing so is outside the RFC:
A compliant Multicast DNS querier, which implements the rules
specified in this document, MUST send its Multicast DNS queries from
UDP source port 5353 (the well-known port assigned to mDNS), and MUST
listen for Multicast DNS replies sent to UDP destination port 5353 at
the mDNS link-local multicast address (224.0.0.251 and/or its IPv6
equivalent FF02::FB).
For now I will move forward with supporting one-shot mDNS requests and routing. We should probably feature flag off continuous mDNS queries. This is disappointing.
from hickory-dns.
Related Issues (20)
- Failing to read "_acme-challenge" TXT record HOT 3
- Debug assert triggered: record types do not match, DNSKEY <> Some(Unknown(48)) HOT 4
- do not leak and requested domain to the log HOT 21
- trust-dns quic client can not querry trust-dns quic server HOT 11
- RecordType does not implement Deserialize... but it does? HOT 3
- How to run async dynamic update with DNS SEC? HOT 2
- `proto::op::Message` can panic when `dnssec` is not enabled no debug builds HOT 3
- Panic: "bad character in CAA issuer value" HOT 2
- Prometheus metrics HOT 4
- `ClientConfig` and `RootCertStore` improvements HOT 4
- trust-dns only warns instead of returning Err when it has no nameservers listed in /etc/resolv.conf HOT 6
- read_system_conf returns different Error types on unix vs windows HOT 1
- Unable to build without linking against libssl/libcrypt HOT 2
- Revisit maximum request sizes in TCP, DoT, DoH, and DoQ implementations
- Axfr and AxfrStream issues with big zones HOT 3
- Sync client hang HOT 4
- Hickory DNS rebranding HOT 9
- How can AsyncClient be used with UdpStream? HOT 10
- Use AsyncClient across multiple tokio async tasks HOT 2
- Update ring to support s390x and ppc64el HOT 12
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hickory-dns.