Ed W wrote: > On 10/05/2011 08:06, Simon Kelley wrote: >> Yes, I would consider such a feature request, and in principle, passing >> information over from incoming DNS requests to outgoing DNS requests is >> quite simple. The pointer to Squid is good, it gives API examples which >> show that this is quite easy. HOWEVER, I think the showstopper is the >> concept of a "connection". The vast majority of DNS traffic runs over >> UDP, so there's no network-level connection to track. You could force >> everything to TCP, but that would be slow, and use more of your >> precious upsteam bandwidth than is strictly necessary. Have I got this >> wrong somewhere? > > Actually netfilter conntrack tries very hard to turn almost anything at > all into a kind of "connection". It has a concept of "related" packets > and so for example if you send a bunch of pings somewhere then those are > seen both as a separate bunch of ICMP through iptables and optionally > you can see them through conntrack as a single "connection" > > Really there is still a "connection" with UDP (or you wouldn't know what > the answer to your request was). From dnsmasqs' point of view all that > is needed is to ensure that a new socket is created for each request? > The subtlety here is that usually you setup your iptables rules to take > the packet mark (ie that dnsmasq sets), copy that to the "connection > mark" (used by conntrack), then when the reply packet comes back, > conntrack will match it for us and apply the same mark so that we will > tag it as the same users traffic (whether UDP or TCP) > > So the main thing needed is to read incoming packet marks and apply them > to the outgoing request. iptables/conntrack does everything else for us? > > Grateful for your thoughts on whether this could be implemented in dnsmasq? >
You supply the conntrack smarts and I'll do the dnsmasq ones, what a team! There's two stages to think about. One: a requestor sends a UDP request to dnsmasq. All of these are received by dnsmasq through the same listening socket, or a best through a very few sockets. We need some way of getting the conntrack information associated with individual packets, not sockets. Is that possible? Two: the request gets sent upstream. There is _normally_ a new socket for each request (for source-port randomisation), so that's fine. The exceptions to this probably don't matter (source-port randomisation configured off, very heavy load where sockets are re-used to avoid resource use growing without bound.) Given the abilty to read the conntrack mark for an incoming request, and set the conntrack mark for a socket-to-upstream, the rest is trivial in implement. Simon.