#  -*- text -*-
#
#
#  $Id: 623c0d609224dab0efc508a5c87cc918ab7c1054 $

#######################################################################
#
#  = Tacacs Module
#
#  The `tacacs` module is used to send TACACS+ client requests to
#  TACACS+ servers.
#
#  The module has the following return codes:
#
#  [options="header,autowidth"]
#  |===
#  | Code        | Description
#  | invalid     | Something went wrong sending the request,
#                  or the reply packet is invalid.
#  | ok          | the module received an `ack` (`Access-Accept`,
#                  `Accounting-Response`, `CoA-ACK`, etc.)
#  | handled     | the module received an `Access-Challenge`
#  | fail        | there was no response to the proxied request
#  | reject      | the module received a `nak` (`Access-Reject`, `CoA-NAK`, etc.)
#  | noop        | the module saw its own `Proxy-State` attribute,
#                  and is will not proxy the request.  This behavior
#                  prevents proxy loops.
#  |===
#
tacacs {
	#
	#  transport:: Only TCP transport is allowed.
	#
	transport = tcp

	#
	#  max_attributes:: Maximum number of attributes to decode in
	#  response.
	#
	#  Default is 255.
	#
#	max_attributes = 255

	#
	#  type:: List of allowed packet types.
	#
	#  There is currently no way to change the packet type in the
	#  request. See `unlang` fork for that functionality.
	#
	type = Accounting-Request

	#
	#  response_window:: If we do not receive a reply within this time
	#  period, then start `zombie_period`
	#
	response_window = 15

	#
	#  zombie_period:: If the home server does not reply to a packet, the
	#  `zombie_period` starts.
	#
	#  The connection is marked `zombie`, and isn't used to send new
	#  packets. If there are no responses within `zombie_period`, the
	#  server either closes the connection (no `status_check`
	#  subsection), or starts pinging the home server (`status_check.type
	#  = Status-Server`).
	#
	zombie_period = 10

	#
	#  revive_interval:: If there are no status checks, mark the home
	#  server alive after `revive_interval` timeout.
	#
	#  Some home servers do not support status checks via the
	#  `Status-Server` packet. Others may not have a "test" user
	#  configured that can be used to query the server, to see if it is
	#  alive. For those servers, we have NO WAY of knowing when it
	#  becomes alive again. Therefore, after the server has been marked
	#  dead, we wait a period of time, and mark it alive again, in the
	#  hope that it has come back to life.
	#
	#  If it has NOT come back to life, then the module will wait for
	#  `zombie_period` before marking it dead again. During the
	#  `zombie_period`, ALL AUTHENTICATIONS WILL FAIL, because the home
	#  server is still dead. There is NOTHING that can be done about
	#  this, other than to enable the status checks, as documented above.
	#
	#  e.g. if `zombie_period` is 40 seconds, and `revive_interval` is
	#  300 seconds, the for 40 seconds out of every 340, or about 10% of
	#  the time, all authentications will fail.
	#
	#  If the `zombie_period` and `revive_interval` configurations are
	#  set smaller, than it is possible for up to 50% of authentications
	#  to fail.
	#
	#  As a result, we recommend enabling status checks, and we do NOT
	#  recommend using `revive_interval`.
	#
	#  The `revive_interval` configuration is used ONLY if the
	#  `status_check` subsection is not used. Otherwise,
	#  `revive_interval` is not necessary, and should be deleted.
	#
	#  Useful range of values: 10 to 3600
	#
	revive_interval = 3600

	#
	#  == Connection trunking
	#
	#  Each worker thread (see tacacsd.conf, num_workers), has it's own
	#  set of connections. These connections are grouped together into a
	#  "pool".
	#
	#  Much of the configuration here is similar to the old connection
	#  "pool" configuration in v3. However, there are more configuration
	#  parameters, and therefore more control over the behavior.
	#
	pool {
		#
		#  start:: Connections to create during module instantiation.
		#
		#  If the server cannot create specified number of connections
		#  during instantiation it will exit.
		#
		#  Set to `0` to allow the server to start without the database
		#  being available.
		#
		start = 0

		#
		#  min:: Minimum number of connections to keep open.
		#
		min = 1

		#
		#  max:: Maximum number of connections.
		#
		#  If these connections are all in use and a new one is requested,
		#  the request will NOT get a connection.
		#
		max = 8

		#
		#  connecting:: Maximum number of sockets to have in the
		#  "connecting" state.
		#
		#  If a home server goes down, the module will close old / broken
		#  connections, and try to open new ones. In order to avoid flooding
		#  the home server with connection attempts, set the `connecting`
		#  value to a small number.
		#
		connecting = 1

		#
		#  uses:: number of packets which will use the connection.
		#
		#  After `uses` packets have been sent the connection will be
		#  closed, and a new one opened. For no limits, set `uses = 0`.
		#
		uses = 0

		#
		#  lifetime:: lifetime of a connection, in seconds.
		#
		#  After `lifetime` seconds have passed, no new packets will be sent
		#  on the connection. When all replies have been received, the
		#  connection will be closed.
		#
		#  For no limits, set `lifetime = 0`.
		#
		#  It is possible to use precise times, such as `lifetime = 1.023`,
		#  or even qualifiers such as `lifetime = 400ms`.
		#
		lifetime = 0

		#
		#  open_delay:: How long (in seconds) a connection must be above
		#  `per_connection_target` before a new connection is opened.
		#
		#  Parsing of this field is the same as for `lifetime`.
		#
		open_delay = 0.2

		#
		#  close_delay:: How long (in seconds) a connection must be below
		#  `per_connection_target` before a connection is closed.
		#
		close_delay = 1.0

		#
		#  manage_interval:: How often (in seconds) the connections are
		#  checked for limits, in order to open / close connections.
		#
		manage_interval = 0.2

		#
		#  connection { ... }:: Per-connection configuration.
		#
		connection {
			#
			#  connect_timeout:: How long to wait before giving up on a
			#  connection which is being opened.
			#
			connect_timeout = 3.0

			#
			#  reconnect_delay:: If opening a connection fails, or an open
			#  connection fails, we wait `reconnect_delay` seconds before
			#  attempting to open another connection.
			#
			reconnect_delay = 5
		}

		#
		#  request { ... }:: Per-request configuration.
		#
		request {
			#
			#  per_connection_max:: The maximum number of requests which are
			#  "live" on a particular connection.
			#
			per_connection_max = 255

			#
			#  per_connection_target:: The target number of requests which are
			#  "live" on a particular connection.
			#
			#  There can be a balance between overloading a connection, and
			#  under-utilizing it. The default is to fill each connection
			#  before opening a new one.
			#
			per_connection_target = 255

			#
			#  free_delay:: How long to wait before freeing internal resources
			#  associated with the connection.
			#
			free_delay = 10
		}

	}

	#
	#  == Protocols
	#
	#  Only TCP is supported.
	#
	#  tcp { ... }:: TCP is configured here.
	#
	tcp {
		ipaddr = 127.0.0.1
		port = 49
		secret = testing123

		#
		#  NOTE: Don't change anything if you are not sure.
		#

		#
		#  interface:: Interface to bind to.
		#
#		interface = eth0

		#
		#  max_packet_size:: Our max packet size. may be different from the
		#  parent.
		#
#		max_packet_size = 4096

		#
		#  recv_buff:: How big the kernel's receive buffer should be.
		#
#		recv_buff = 1048576

		#
		#  send_buff:: How big the kernel's send buffer should be.
		#
#		send_buff = 1048576

		#
		#  src_ipaddr:: IP we open our socket on.
		#
#		src_ipaddr = ""
	}
}
