handlers

package
v0.6.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 15, 2025 License: BSD-3-Clause Imports: 26 Imported by: 0

README

Handlers

Query Processing

Once atomdns has been started and has parsed the configuration, it runs a server with handlers chains. Each handler chain is tied to a set of zones it serves.

When a query is being processed by atomdns, the following steps are performed:

  • It will check which one has the most specific zone for this query (longest suffix match). E.g. if there are two handler chains, one for example.org and one for a.example.org, and the query is for www.a.example.org, it will be routed to the latter.

  • Once a handler chains has been found, it will be routed through that chain. This happens in the order as defined in the configuration file (atomdns-conffile(5)).

  • Each handler in the chain will inspect the query and determine if it should process it. A couple of things can now happen:

    1. The query is processed by this handler..
    2. The query is not processed by this handler.
    3. The query is processed by this handler, but it decides it needs to call the next handler.
    4. The query is processed by this handler, a key/value (see [dnsctx])is added to the context and the next handler is called.

Processing a query means a handler will respond to the client with a reply.

Note that a handler is free to deviate from the above list as it wishes. Currently, all handlers that come with atomdns fall into one of these four groups though.

Logging

Each handler has a generated zerr.go file that defines a log function. This function should be used when logging from within the handler, this uses the standard library log/slog package:

alog := log().With(slog.String("path", filepath.Base(d.Path)))
alog.Error("Failed to reload", Err(err))
// or
alog.Info("Successful reload")

Adding a New Handler

There are some minimum requirements before a handler can be added to the main source tree. It basically boils down to: "it should add something unique and useful to atomdns". Furthermore documentation, tests and functionality should all be excellent.

It is easier to list when a handler can be included in atomdns than to say it should stay external, so:

  • First, the handler should be useful for other people. "Useful" is a subjective term, but the handler needs to fill a niche that appeals to more than one person.
  • It should be sufficiently different from other handlers.
  • Current internet standards need be supported: IPv4 and IPv6 are minimally required.
  • It must have tests.
  • It must have a README.md for documentation.
  • Care must be taken to make it efficient in both memory and CPU.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var StringToHandler = map[string]func() Handler{
	"acl":      func() Handler { return new(acl.Acl) },
	"any":      func() Handler { return new(any.Any) },
	"as112":    func() Handler { return new(as112.As112) },
	"chaos":    func() Handler { return new(chaos.Chaos) },
	"cookie":   func() Handler { return new(cookie.Cookie) },
	"dbfile":   func() Handler { return new(dbfile.Dbfile) },
	"dbhost":   func() Handler { return new(dbhost.Dbhost) },
	"dbsqlite": func() Handler { return new(dbsqlite.Dbsqlite) },
	"drunk":    func() Handler { return new(drunk.Drunk) },
	"ecs":      func() Handler { return new(ecs.Ecs) },
	"geoip":    func() Handler { return new(geoip.Geoip) },
	"log":      func() Handler { return new(log.Log) },
	"metrics":  func() Handler { return new(metrics.Metrics) },
	"msgcache": func() Handler { return new(msgcache.Msgcache) },
	"nsid":     func() Handler { return new(nsid.Nsid) },
	"refuse":   func() Handler { return new(refuse.Refuse) },
	"sign":     func() Handler { return new(sign.Sign) },
	"template": func() Handler { return new(template.Template) },
	"tsig":     func() Handler { return new(tsig.Tsig) },
	"unpack":   func() Handler { return new(unpack.Unpack) },
	"url":      func() Handler { return new(url.Url) },
	"whoami":   func() Handler { return new(whoami.Whoami) },
	"yes":      func() Handler { return new(yes.Yes) },
}

StringToHandler is a map of strings to a handler creation function.

Functions

func Compile

func Compile(hs []Handler) dns.HandlerFunc

Compile takes the Handlers hs and creates a wrapped handle func.

Types

type Handler

type Handler interface {
	// HandlerFunc run the handler's code.
	HandlerFunc(next dns.HandlerFunc) dns.HandlerFunc

	// Err returns a error with some extra data that identifies the handler in erroring. This method can be
	// created with go generate, once some scaffolding is in place.
	Err(error) error
}

A Handler is a dns.HandlerFunc that has a handler func (the next when to call in the middleware stack) as input and returns a handle func which is the handler itself.

There are several types of handlers that you can implement, handlers that:

  • observe, things like logging and metrics.
  • modify the dns.Msg and then call the next handler, they can enrich the context or modify the message.
  • call the next handler, wait for it to return and modify the dns.Msg, think of setting TSIG or a DNS cookie.

type Setupper

type Setupper interface {
	Setup(co *dnsserver.Controller) error
}

Setupper holds a single method that is called when this Handler has configuration that needs to be parsed from the config file. The co's Global holds the server's global config.

Directories

Path Synopsis
zone
Package implement a DNS zone, held in a binary tree.
Package implement a DNS zone, held in a binary tree.
Package sign implements a zone signer as a hander.
Package sign implements a zone signer as a hander.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL