# traffic ## Name *traffic* - handout addresses according to assignments. ## Description The *traffic* plugin is a load balancer that allows traffic steering, weighted responses and draining of endpoints. It discovers the enpoints via the Envoy xDS protocol, specifically messages of the type "envoy.api.v2.ClusterLoadAssignment", these contain endpoints and an (optional) weight for each. The `cluster_name` or `service_name` for a service must be a domain name. The plugin takes care of handing out responses that adhere to these assignments. Assignments will need to be updated frequently, as discussed the [Envoy xDS protocol](https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol) documentation. Each response will contain one address record; which *traffic* considers the optimal one. When there are no assignments for a service name (yet), the responses will also be modified (see below). *Traffic* will load balance A and AAAA queries. As said, it will return precisely one record in a response. If a service should be load balanced, but no assignment can be found a random record from the *answer section* will be choosen. Every message that is handled by the *traffic* plugin will have its TTLs set to 5 seconds, the authority section, and all RRSIGs are removed from it. The *traffic* plugin has no notion of draining, drop overload and anything that advanced, *it just acts upon assignments*. This is means that if a endpoint goes down and *traffic* has not seen a new assignment yet, it will still include this endpoint address in responses. ## Syntax ~~~ traffic ~~~ This enables traffic load balancing for all (sub-)domains named in the server block. ## Examples ~~~ corefile example.org { traffic forward . 10.12.13.14 } ~~~ This will add load balancing for domains under example.org; the upstream information comes from 10.12.13.14; depending on received assignments, replies will be let through as-is or are load balanced. ## Assignments Assignments are streamed for a service that implements the xDS protocol, *traffic* will bla bla. TODO. Picking an endpoint is done as follows: (still true for xDs - check afer implementing things) * include spiffy algorithm. On seeing a query for a service, *traffic* will track the reply. When it returns with an answer *traffic* will rewrite it (and discard of any RRSIGs). Using the assignments the answer section will be rewritten as such: * A endpoint will be picked using the algorithm from above. * The TTL on the response will be 5s for all included records. * According to previous responses for this service and the relative weights of each endpoints the best endpoint will be put in the response. * If after the selection *no* endpoints are available an NODATA response will be sent. An SOA record will be synthesised, and a low TTL (and negative TTL) of 5 seconds will be set. Authority section will be removed. If no assignment, randomly pick an address other types then A and AAAA, like SRV - do the same selection. ## Bugs This plugin does not play nice with DNSSEC - if the endpoint returns signatures with the answer; they will be stripped. You can optionally sign responses on the fly by using the *dnssec* plugin. ## Also See * https://github.com/envoyproxy/go-control-plane * https://blog.christianposta.com/envoy/guidance-for-building-a-control-plane-to-manage-envoy-proxy-based-infrastructure/ * https://github.com/envoyproxy/envoy/blob/442f9fcf21a5f091cec3fe9913ff309e02288659/api/envoy/api/v2/discovery.proto#L63 * This is a [post on weighted random selection](https://medium.com/@peterkellyonline/weighted-random-selection-3ff222917eb6).