NAME

    gdnsd-plugin-multifo - gdnsd plugin for multi-address, all-active
    failover groups

SYNOPSIS

    Example plugin config:

      plugins => {
        multifo => {
          up_thresh => 0.3
          service_types => default,
          v4www => {
            lb01 => 192.0.2.200,
            lb02 => 192.0.2.201,
            lb03 => 192.0.2.202,
          }
          v6smtp => {
            service_types => [ smtp ],
            up_thresh => 0.1,
            lb01_v6 => 2001:DB8::1,
            lb02_v6 => 2001:DB8::2,
            lb03_v6 => 2001:DB8::3,
          }
          pubwww => {
            up_thresh => 0.5
            service_types => [ corpwww_type, default ],
            addrs_v4 => [ 192.0.2.100, 192.0.2.101, 192.0.2.102 ]
            addrs_v6 => {
              service_types => [ up ],
              up_thresh => 0.7
              lb01_v6 => 2001:DB8::1,
              lb02_v6 => 2001:DB8::2,
              lb03_v6 => 2001:DB8::3,
            }
          }
        }
      }

    Example zonefile RRs:

      web4 180 DYNA multifo!v4www
      smtp 180 DYNA multifo!v6smtp
      www 180 DYNA multifo!pubwww

DESCRIPTION

    gdnsd-plugin-multifo is designed to do multi-address all-active failover
    grouping. Basically, for each configured resource name, you supply a
    labeled list of addresses. multifo monitors these addresses according to
    "service_types", and answers "DYNA" address queries using the non-"DOWN"
    subset. The core gdnsd code will round-robin rotate the records on the
    way out, as it does for all address RR-sets.

TOP-LEVEL PLUGIN CONFIG

    At the top level of the plugin's configuration stanza, two special
    parameters "up_thresh" and "service_types" are supported. These set
    default per-resource options of the same name for any resources which do
    not define them explicitly.

    The rest of the hash entries at the top level are the names of the
    resources you define. Each resource gets a configuration hash of its own
    for containing resource-specific parameters as well as the actual
    address data.

RESOURCE CONFIG

    Within a resource, you have two basic options. You can either directly
    specify a set of "label => address" pairs which are all the same family
    (IPv4 or IPv6), or you can use the sub-stanzas "addrs_v4" and/or
    "addrs_v6" to specify one or both families in the same resource.

    The "up_thresh" and "service_types" parameters are inherited through
    every level, and can be overridden at any level (even
    per-address-family):

    up_thresh
        Floating point, default 0.5, range (0.0 - 1.0]. This configures the
        per-resource "up_thresh" threshold. More details in "UP THRESH"
        below.

    service_types
        Array of strings, or single string. Default "default". This sets the
        monitored service_types for this resource. If an array of more than
        one is provided, all will be monitored for each address, and the net
        monitored state will be the minimum (worst) of the set. See
        gdnsd.config(8) for more details on service_types.

SHORTCUT CONFIG

    If you have no parameters (service_types, up_thresh) to configure in a
    given stanza (single-family direct resource config, or addrs_v[46]), and
    do not care about the descriptive per-address labels used in monitoring,
    you can replace the hash with an array of addresses. The labels will be
    generated for you as a series of integers starting with 1. For example,
    the following are equivalent:

       res1 => { addrs_v4 => [ 192.0.2.1, 192.0.2.2 ] }
       res1 => { addrs_v4 => { 1 => 192.0.2.1, 2 => 192.0.2.2 } }

OPERATIONAL MECHANICS

    All of the addresses for all of the resources are monitored using the
    per-address-family inherited "service_types" specified (default would be
    simple HTTP/1.0 monitoring for "200 OK" on port 80). When the core
    daemon requests a lookup for address records of a given family on one of
    this plugin's resources, it goes through essentially the following
    process to determine the set of response addresses for that address
    family: 1) Add all non-DOWN addresses to the result set. 2) If the set
    of non-DOWN addresses fail the up_thresh check, add *all* addresses to
    the result set as a fallback. 3) If any address is in the DOWN or even
    DANGER state, cut the zonefile-specified TTL in half

    This process is repeated independently for each of the IPv4 and IPv6
    address subsets, in the case that a resource has both address families
    configured (the TTL is only cut in half once of course). Details on the
    up_thresh check follow:

UP THRESH

    Any non-DOWN address is considered an acceptable result for up_thresh
    purposes, even ones in the transitional DANGER state. If there are not
    "enough" non-DOWN addresses to pass the threshold (per address family),
    all addresses (of a given address family) will be returned as a
    fallback.

    The threshold is implemented mathematically as in the following
    pseudo-code "if(non_down >= ceil(thresh * total)) threshold_passed;".
    For example, if thresh is at the default value of 0.5, and there are 3
    total IPv4 addresses, then 2 of them must be non-down to pass the
    threshold. The net result is that with the default threshold, the plugin
    will never return an isolated single address from a set of 3. It will
    either return all 3, or it will return 2/3 if a single address from the
    set has failed.

    When the threshold check fails (and all addresses are returned) for
    either address family, resource-level total failure will also be
    signaled to any applicable upstream meta-plugins such as metafo or
    geoip.

    General rules for the results of the up_thresh formula:

    *   A threshold of 1.0 will only pass if all addresses are not-down.
        This is mostly pointless, you might as well not monitor anything and
        set up these addresses as a static set in a zonefile.

    *   A threshold of 0.01 will pass even if only one address is alive and
        return just that one address, even if it's e.g. the only one left
        out of 40.

    *   Because a threshold of 0.0 is illegal, if all addresses are down the
        threshold will always fail, returning all addresses.

    Intermediate value examples: (threshold: non-down/total required to pass
    threshold):

    *   0.1: 1/1 1/2 1/3 1/4 1/5 1/6 1/7 1/8 2/16

    *   0.2: 1/1 1/2 1/3 1/4 1/5 2/6 2/7 2/8 4/16

    *   0.3: 1/1 1/2 1/3 2/4 2/5 2/6 3/7 3/8 5/16

    *   0.4: 1/1 1/2 2/3 2/4 2/5 3/6 3/7 4/8 7/16

    *   0.5: 1/1 1/2 2/3 2/4 3/5 3/6 4/7 4/8 8/16

    *   0.6: 1/1 2/2 2/3 3/4 3/5 4/6 5/7 5/8 10/16

    *   0.7: 1/1 2/2 3/3 3/4 4/5 5/6 5/7 6/8 12/16

    *   0.8: 1/1 2/2 3/3 4/4 4/5 5/6 6/7 7/8 13/16

    *   0.9: 1/1 2/2 3/3 4/4 5/5 6/6 7/7 8/8 15/16

SEE ALSO

    gdnsd.config(5), gdnsd.zonefile(5), gdnsd(8), gdnsd-plugin-simplefo(8)

    The gdnsd manual.

COPYRIGHT AND LICENSE

    Copyright (c) 2012 Brandon L Black <blblack@gmail.com>

    This file is part of gdnsd.

    gdnsd is free software: you can redistribute it and/or modify it under
    the terms of the GNU General Public License as published by the Free
    Software Foundation, either version 3 of the License, or (at your
    option) any later version.

    gdnsd is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    more details.

    You should have received a copy of the GNU General Public License along
    with gdnsd. If not, see <http://www.gnu.org/licenses/>.

