erldns_pipeline behaviour (erldns v7.0.0-rc9)
View SourceThe pipeline specification.
It declares a pipeline of sequential transformations to apply to the incoming query until a response is constructed.
This module is responsible for handling the pipeline of pipes that will be executed when a DNS message is received. Handlers in this pipeline will be executed sequentially, accumulating the result of each handler and passing it to the next. This designs a pluggable framework where new behaviour can be injected as a new pipe handler in the right order.
Default pipes
The following are enabled by default, see their documentation for details:
Types of pipelines
There are two kind of pipes: function pipes and module pipes.
Function pipes
A function pipe is by definition any function that receives a dns:message/0
and a set of options and returns a dns:message/0
. Function pipes must have
the following type signature:
-type pipe() :: fun((dns:message(), opts()) -> return()
Module pipes
The preferred mechanism, a module pipe is an extension of the function pipe.
It is a module that exports:
- a
prepare/1
function which takes a set of options and initializes it, or disables the pipe. - a
call/2
function with the signature defined as in the function pipe.
The API expected by a module pipe is defined as a behaviour by this module.
Configuration
{erldns, [
{packet_pipeline, [
erldns_query_throttle,
erldns_packet_cache,
erldns_resolver,
erldns_packet_cache,
erldns_empty_verification
]},
]}
Examples
Here's an example of a function pipe that arbitrarily sets the truncated bit on a message if the query is directed to the "example.com" domain:
-module(erldns_packet_pipe_example_set_truncated).
-behaviour(erldns_pipeline).
-export([prepare/1, call/2]).
-spec prepare(erldns_pipeline:opts()) -> disabled | erldns_pipeline:opts().
prepare(Opts) ->
case enabled() of
false -> disabled;
true -> Opts
end.
-spec call(dns:message(), erldns_pipeline:opts()) -> erldns_pipeline:return().
call(#dns_message{questions = [#dns_query{name = <<"example.com">>} | _]} = Msg, _Opts) ->
Msg#dns_message{tc = true}.
call(Msg, _Opts) ->
Msg.
Summary
Types
The host that originated the request.
Options that can be passed and accumulated to the pipeline.
The underlying request transport protocol. All requests come either through UDP or TCP.
Callbacks
Trigger the pipeline at run-time.
Initialise the pipe handler, triggering side-effects and preparing any necessary metadata.
Types
-type host() :: inet:ip_address() | inet:hostname().
The host that originated the request.
-type opts() :: #{resolved := boolean(), transport := transport(), host := host(), atom() => dynamic()}.
Options that can be passed and accumulated to the pipeline.
-type pipe() :: module() | fun((dns:message(), opts()) -> return()).
-type return() :: dns:message() | {dns:message(), opts()} | {stop, dns:message()}.
-type transport() :: tcp | udp.
The underlying request transport protocol. All requests come either through UDP or TCP.
Callbacks
-callback call(dns:message(), opts()) -> dns:message() | {dns:message(), opts()} | {stop, dns:message()}.
Trigger the pipeline at run-time.
This callback can return
- a possibly new
dns:message/0
; - a tuple containing a new
dns:message/0
and a new set ofopts/0
; - a tuple
{stop, t:dns:message/0}
tuple to stop the pipeline execution altogether.
Initialise the pipe handler, triggering side-effects and preparing any necessary metadata.
This will be called during the pipeline initialisation phase, which should happen at application startup provided you added the pipeline to your application's supervision tree. This will be called only once during application startup and therefore it is an opportunity to do any necessary preparations that can reduce the amount of work at runtime and therefore improve performance.
This callback can return disabled
, and then the call/2
callback won't be added to the
pipeline.
Functions
-spec call(dns:message(), #{atom() => dynamic()}) -> dns:message().