#  -*- text -*-
#
#
#  $Id: 13b1fcab87581234bd0691b0acbc5b7fd6bc69df $

#######################################################################
#
#  = Delay Module
#
#  The `delay` module delays the processing of a request in a
#  non-blocking fashion.
#
#  The module is most useful for rate limiting reject responses.
#  Instead of having a specific "reject delay" configuration, it is
#  instead possible to have a policy that delays the response.
#
#  TIP: The module can also be used to introduce artificial jitter
#  into responses by adding random delays.
#
#  == xlat for delays
#
#  The module also registers an xlat function for delays
#
#  %delay(...)
#
#  This function takes a time-delta argument (or data which is
#  converted to a time-delta), and will delay the given number of
#  seconds.
#
#  .Example
#
#  ```
#  %delay(0.2s)
#  ```

#

#
#  == Configuration Settings
#

#
#  === Simple delay
#
delay {
	#
	#  delay:: How long to delay request processing for.
	#
	delay = 1.0s

	#
	#  force_reschedule:: Whether the request should be rescheduled even
	#  if no delay is needed.
	#
	#  Rescheduling the request pauses it momentarily, and introduces a
	#  small delay. It allows for processing of other requests ahead of
	#  this one. The result is a small amount of "jitter" in responses,
	#  which can help avoid some deterministic timings in the network.
	#
#	force_reschedule = no

	#
	#  relative:: Whether delay should be calculated relative to when the
	#  request was received.
	#
	#  This configuration can be useful for rate limiting, as most NAS
	#  will only allow a limited number of requests to be in flight.
	#
	#  The default is `no`, which means that.
	#
#	relative = no

	#
	#  rcode:: Which rcode the delay module should return when it resumes
	#  this can be useful for detecting whether a `timeout { ... }`
	#  section expired, whilst the delay module was waiting.
	#
	#  The default is `notset`, which means that the delay module will be
	#  transparent and not alter the section rcode.
	#
	#  [NOTE]
	#  ====
	#  The default section `rcode` in many places is `fail`. Care should
	#  be taken to set the `rcode` for the section a delay module appears
	#  in, if this configuration item is not set, and no other modules
	#  are present in the section.
	#  ====
	#
#	rcode = 'notset'
}

#
#  === Delaying Access-Reject packets
#
#  The `delay_reject` module should be used in a `send Access-Reject`
#  section, as the last module in that section. When `delay_reject` is
#  used there, the reject will be delayed for either
#  FreeRADIUS-Response-Delay seconds, or if that attribute does not
#  exist, then one second.
#
#  While the response is delayed, the server will continue processing
#  other requests. It will simply set a timer to wake up and send the
#  response after the delay.
#
#  NOTE: We set `relative = yes` here. That setting ensures that if
#  the server takes more than one second to process the request, then
#  the `delay_reject` module will not add *additional* delays.
#  Instead, this module will ensure that the `Access-Reject` is sent
#  no earlier than one second after the `Access-Request` had been
#  received.
#
delay delay_reject {
	delay = "%{reply.FreeRADIUS-Response-Delay || 1}"
	relative = yes
}
