netman: trigger reloading nameservers on NM_DEVICE_STATE_DISCONNECTED

Fixes a problem where this signal was previously ignored, e.g. when
disconnecting but still having other connections active/up, resulting in
the wrong set of nameservers being used.
netman: debug print state from NM and when nameservers are sent
netman: use map to store NM states

This will make it easier to print the string representation of the
states, e.g. for debug
types: remove Err from NSList
netman: use NSMsg for sending new nameserver lists
netman: add type for NS responses

This will allow moving the err type from NSList and into a type
specifically for communicating a new NS or any errors
pkg/dnsane: fix typo

replace logger with golog

Not only does golog seem to do what I want, but it's probably faster,
and definitely uses less memory than my janky logger.

I ran logger using the benchmark that ships with golog, along with the
std Go log package, and it's obviously faster and less memory intensive
(that even the std lib log package...):

$ go test -v -bench=. -benchtime=20s
goos: linux
goarch: amd64
pkg: github.com/kataras/golog/_benchmarks
cpu: Intel(R) Core(TM) i7-10710U CPU @ 1.10GHz
BenchmarkGologPrint-12          19795285              1200 ns/op             239 B/op         12 allocs/op
BenchmarkLoggerPrint-12          6285282              3694 ns/op            1416 B/op         51 allocs/op
BenchmarkStdPrint-12            14118765              1700 ns/op             480 B/op         24 allocs/op

I also measured a reduction from 2.21MB --> 1.98MB in server.go
forwarding/handling/responding to 1000 DNS requests just by changing to
golog, even when the min log level was INFO
server: add getNS method

Sugar for getting the nameserver list from the ns provider
server: use nsProvider instead of mutexes for internal NSList
server: add nsProvider

This allows setting/using a NSList without using mutexes/locks
server: remove old comment
pkg/dnsane: use logger for writing to console where appropriate
server/test: check that response ID is consistent

The ID of the response from doLookups should not change from the ID of
the msg that was passed in, so test for it.
server: add test for doLookups
server: in-line muxResults into handleDnsRequest

This cuts the number of cycles spent in doLookups by almost half, as
measured with pprof while spamming DNS lookups.

Most of the benefit is from no longer having to make a new slice.
server: pass through any lookup errors to the DNS client

This seems appropriate, e.g. if the lookup failed then let the client
handle retries if it wants... or not.
server: pass in lookup func to doLookups

This is an appropriate way of overriding the lookup func for testing,
using a global var would conflict with concurrent test/benchmark runs if
each one was trying to set its own lookup func.
server: don't pre-allocate results

This optimization was broken, appending new nameservers to a slice with
nil elements in it. this caused twice as many lookup()'s to be spawned
than necessary, with the first half always failing.
server: move all logic in handleDnsRequest to doLookups()

This allows testing/benchmarking the logic here in the hot path without
having to deal with the dns.ResponseWriter