+
+This began as a cleanup of a few startling bugs in resolver.c, but I encountered so many other endemic issues (IMO) along the way that I just started from the top and groomed everything on my way through. Apologies if the style doesn't quite match the rest of the codebase, but I hope it's at least a little easier to follow.
+
+The resolver is still architected the same as the original (id est, a group of threads, all feeding from a common input stream in turn, resolving their data and responding independently before repeating), but it strives to do the things it does a little more correctly.
+
+I've probably screwed up portability somewhere, and it may now require a non-vintage compiler.
+
+
+Major fixes:
+
+ * locking. original had none around its core data structures (!)
+ * functions no longer harbor static buffers (!)
+ * non-blocking IO is more resilient
+
+
+Other changes:
+
+ * uses modern socket framework
+ * can cache successful lookups as well as failures
+ * cache lookups are now less than linear
+ * uses native stdio locking
+
+
+Possible future improvements to consider:
+
+ * track more internal data, dump stats on a signal
+ * make the threadpool dynamically sized
+ * use a different work-queue model entirely
+