#  -*- text -*-
#
#
#  $Id: 9deb4dc2db229dc2619ffc3cba98fc8ffedf02a1 $

#######################################################################
#
#  = 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 {
			#
			#  connection_timeout:: How long to wait
			#  before giving up on a connection which is
			#  being opened.
			#
			connection_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 = ""
	}
}
