< Previous by Date Date Index Next by Date >
  Thread Index Next in Thread >

[reSIProcate] DNS greylisting


There has been some discussion in the past about what the stack should do if a request times out, or gets a 503 without a Retry-After. I have argued that it is not appropriate to blacklist in these cases, but it is generally agreed that DNS results that have been found non-responsive should be prioritized lower than other DNS results. I proposed the idea of "greylisting", where a DNS result would be de-prioritized, but not removed from the candidate set. Greylisted targets would only be tried if there were no non-greylisted targets left to try. (see [reSIProcate] DNS not returning entries after 408?)

I have looked at the code that presently handles whitelisting, and it looks pretty easy to add the responsibility for greylisting. For those who aren't familiar with the code, to accomplish the whitelisting effect, DnsStub keeps an instance of class RRVip (RRVip derives from DnsStub::ResultTransform, a functor responsible for transforming incoming DNS result-sets in an arbitrary fashion). RRVip holds onto a map of functors (RRVip::Transform) that are keyed by resource-record type(A, AAAA, SRV, NAPTR), and resource name. Right now the only thing RRVip::Transform and its subclasses do is sort. Each time a result is whitelisted, we create an instance of RRVip::Transform (or an appropriate subclass, depending on what resource type we're talking about; A, SRV, etc), and place it in the map maintained by RRVip. When RRVip is asked to process a result-set, it finds the appropriate functor in the map, this functor will look through the result-set for the whitelisted result, and place this result at the beginning of the result-set. (If we do not find the whitelisted result, RRVip removes this functor from the map).

So, to implement greylisting, we have a couple of obvious choices:
1) Build greylisting into RRVip, leave everything else as-is.
2) Write another subclass of DnsStub::ResultTransform (say, RRGreylist) and a simple functor-composition class (say, DnsStub::ResultTransformComposition), and compose an RRVip and an RRGreylist into a single functor.

The first choice is quicker, easier, but less modular. Is modularity important enough in this particular case (DNS result transformations) to warrant the extra effort?

Best regards,
Byron Campen

Attachment: smime.p7s
Description: S/MIME cryptographic signature