Maintained by: NLnet Labs

[Unbound-users] Using libunbound from other languages

Phil Pennock
Tue Jul 23 20:46:06 CEST 2013

On 2013-07-23 at 09:02 +0100, Miek Gieben wrote:
> If you say, 'You don't need it", of what locking and where do you talk about?
> The Go code can be relative lock free, but why can I get away with not telling
> OpenSSL (or NSS) that it is going to get called from threaded code?

(I'm ignoring libraries that are actively thread hostile, by doing
things like repointing shared resources from outside the library, such
as stdio; OpenSSL and friends don't do this.)

>From a perspective of thread locking within a library, as long as it is
only ever entered into from one thread, the existence of other threads
is irrelevant.  You don't need to lock against calls that never happen.
You do need to be very sure that you're only called from one thread.

Of course, like an idiot in my second post with code samples, I went and
then suggested initialising multiple threads for concurrency,
undermining the whole reason for doing this.  Duh.  Sorry.  :(  Yes, if
you do setup multiple threads which can enter libunbound, you'd need to
init the SSL library appropriately.  Do you need to do this?  If only
one thread of DNS resolution is sufficient, then my point stands.

I was trying to offer a way forward using existing versions of Unbound
deployed today, rather than a dependency upon a new library version.
You could have one thread today, and a simple cgo-exported "is this
library new enough to let me init crypto for multiple threads" predicate
which you can use to decide whether or not to permit spawning more than
one lookup thread.

Assuming just one thread entering Unbound, you do still need to need to
ensure you build the library for threaded modes of operation, because
that will ensure that errno is a thread-safe wrapper instead of a shared
global.  That's library build-time, rather than invocation.

> >       runtime.LockOSThread()
> >       defer runtime.UnlockOSThread()
> >       // do Unbound setup
> This would be the point to "tell OpenSSL/NSS that it is going to get called from
> threaded code", No?

That's the function potentially called for multiple resolution threads,
so you'd need a sync.Once object you can call the .Do() method on, if
doing it there and invoking more that once.

But yes.

Looking more closely, and thinking, I realise you might be working on a
generic unbound wrapper for Go, so you're not asserting the app won't
use OpenSSL, only that your own library is not doing so?  In which case,
I misinterpreted the impact of your second bullet point, sorry.

And in which case, I see the problem.