thank you very much for the investigation and giving a proposal to the issue. I successfully reproduced the blocking behavior with the faulty DNS server in resolv.conf.
Before answering you, we discussed the topic internally, and I would like to add a few notes to your email. (And maybe start a common discussion about the topic.)
1)
The connection handling in afsocket is running in the main thread (This is where the blocking behavior comes.), and mainly this is the reason why it has many callback functions. Unfortunately it makes the code more complex, and harder to maintain/debug.
You clearly recognized a good point in the code (afsocket_dd_try_connect) to introduce some asynchronous solution for DNS resolving. I think there is no need to handle the "first attempt" any different than the others.
2) Signal vs thread
You have absolutely control over this, there are examples in our code for both of them.
IMHO with signals there might be a chance to conflict with other components. (We recently had an issue with Java, but nothing which can not be sorted out.) This is clearly just a personal opinion.
note: See examples of using "main_loop_call". If you only use those callbacks to add some tasks to the main loop, than you don't have to deal with parallelism, and it will make the rest of the code independent from the chosen callback method.
3)
Unfortunately there is no action in the topic since that, so I do not recommend for you to wait for the final implementation. You can easily start your own, or contribute to ivykis.
However I think the idea is good: Introduce DNS resolving as an internal module or service. At least one should keep in mind during the refactor of afsocket, to make the DNS "service" interchangeable. (If we could gather TTL information beside the resolving, it can be completely independent from the main thread.)
4)