osbase/net/dns: add new DNS server

This adds a new DNS server service, which will replace CoreDNS. The
service has built-in handlers for certain names, but all other names
will be handled by runtime configurable handlers.

Change-Id: I4184d11422496e899794ef658ca1450e7bb01471
Reviewed-on: https://review.monogon.dev/c/monogon/+/3126
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/osbase/net/dns/metrics.go b/osbase/net/dns/metrics.go
new file mode 100644
index 0000000..13d046a
--- /dev/null
+++ b/osbase/net/dns/metrics.go
@@ -0,0 +1,26 @@
+package dns
+
+import (
+	"github.com/prometheus/client_golang/prometheus"
+	"github.com/prometheus/client_golang/prometheus/promauto"
+)
+
+// MetricsRegistry is the metrics registry in which all DNS metrics are
+// registered.
+var MetricsRegistry = prometheus.NewRegistry()
+var MetricsFactory = promauto.With(MetricsRegistry)
+
+var (
+	// rcode can be an uppercase rcode name, a numeric rcode if the rcode is not
+	// known, or one of:
+	//   * redirected: The query was redirected by CNAME, so the final rcode
+	//     is not yet known.
+	//   * not_ready: The handler is not yet ready, SERVFAIL is replied.
+	handlerDuration = MetricsFactory.NewHistogramVec(prometheus.HistogramOpts{
+		Namespace: "dnsserver",
+		Subsystem: "server",
+		Name:      "handler_duration_seconds",
+		Buckets:   prometheus.ExponentialBuckets(0.00025, 2, 16), // from 0.25ms to 8 seconds
+		Help:      "Histogram of the time each handler took.",
+	}, []string{"handler", "rcode"})
+)