mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
595 lines
21 KiB
595 lines
21 KiB
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
|
|
|
<section id="auth.parameters" xmlns:xi="http://www.w3.org/2001/XInclude">
|
|
|
|
<title>Parameters</title>
|
|
|
|
<section id="auth.auth_checks">
|
|
<title>
|
|
<varname>auth_checks_register</varname>,
|
|
<varname>auth_checks_no_dlg</varname>, and
|
|
<varname>auth_checks_in_dlg</varname> (flags)
|
|
</title>
|
|
<para>
|
|
These three module parameters control which optional integrity
|
|
checks will be performed on the SIP message carrying digest response
|
|
during digest authentication. <varname>auth_check_register</varname>
|
|
controls integrity checks to be performed on REGISTER messages,
|
|
<varname>auth_checks_no_dlg</varname> controls which optional
|
|
integrity checks will be performed on SIP requests that have no To
|
|
header field or no To tag (in other words the requests either
|
|
establishing or outside
|
|
dialogs). <varname>auth_checks_in_dlg</varname> controls which
|
|
integrity checks will be performed on SIP requests within dialogs,
|
|
such as BYE or re-INVITE. The default value for all three parameters
|
|
is 0 (old behaviour, no extra checks). The set of integrity checks
|
|
that can be performed on REGISTERs is typically different from sets of
|
|
integrity checks that can be performed for other SIP request types,
|
|
hence we have three independent module parameters.
|
|
</para>
|
|
<para>
|
|
Without the extra checks the nonce will protect only against expired
|
|
values. Some reply attacks are still possible in the expire "window".
|
|
A possible workaround is to always force qop
|
|
authentication and always check the uri from the authorization
|
|
header, but this would not work if an upstream proxy rewrites the uri
|
|
and it will also not work with a lot of UA implementations.
|
|
</para>
|
|
<para>
|
|
In this case the nonce value will be used only to hold
|
|
the expire time (see <varname>nonce_expire</varname>) and an MD5
|
|
over it and some secret (the MD5 is used to make sure that nobody
|
|
tampers with the nonce expire time).
|
|
</para>
|
|
<para>
|
|
When the extra checks are enabled, the nonce will include and extra
|
|
MD5 over the selected part/parts of the message (see below) and some
|
|
other secret. This will be used to check if the selected part of
|
|
the message is the same when an UA tries to reuse the nonce, thus
|
|
protecting or severely limiting reply attacks.
|
|
</para>
|
|
<para>
|
|
The possible flag values for all three parameters are: 1 for checking
|
|
if the message uri changed (uses the whole uri), 2 for checking the
|
|
callid, 4 for the from tag and 8 for the source ip (see nonce.h). For
|
|
example setting
|
|
<varname>auth_checks_register</varname> to 6 would check if the
|
|
callid or the from tag changed from the REGISTER message for which
|
|
the original nonce was generated (this would allow nonce reuse only
|
|
within the same UA and for the expire time). Note that enabling
|
|
the extra checks will limit nonce caching by UAs, requiring extra
|
|
challenges and roundtrips, but will provide much better protection.
|
|
</para>
|
|
<para>
|
|
When the <varname>secret</varname> parameter is set and the extra
|
|
checks are enabled, the first half of the <varname>secret</varname>
|
|
will be used for the expire time MD5 and the other half for the extra
|
|
checks MD5, so make sure you have a long secret (32 chars or longer are
|
|
recommended).
|
|
</para>
|
|
<example>
|
|
<title>Setting the <varname>auth_checks_register</varname> module
|
|
parameter</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "auth_checks_register", 2) # callid
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="qop">
|
|
<title><varname>qop</varname> (string)</title>
|
|
<para>
|
|
If set, enable <emphasis>qop</emphasis> for challenges: each challenge
|
|
will include a <emphasis>qop</emphasis> parameter. This is the
|
|
recommended way, but some older non rfc3261 compliant UAs might get
|
|
confused and might not authenticate properly if <varname>qop</varname>
|
|
is enabled.
|
|
</para>
|
|
<para>
|
|
Enabling <varname>qop</varname> together with
|
|
<varname>nonce_count</varname> will provide extra-security
|
|
(protection against replay attacks) while still allowing
|
|
credentials caching at the UA side and thus not compromising
|
|
performance.
|
|
</para>
|
|
<para>
|
|
The possible values are: "auth", "auth-int" and "" (unset).
|
|
</para>
|
|
<para>
|
|
The default value is not-set ("").
|
|
</para>
|
|
<para>
|
|
See also:
|
|
<varname>nonce_count</varname>.
|
|
</para>
|
|
<example>
|
|
<title>qop example</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "qop", "auth") # set qop=auth
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="nonce_count">
|
|
<title><varname>nonce_count</varname> (boolean)</title>
|
|
<para>
|
|
If enabled the received <emphasis>nc</emphasis> value is remembered
|
|
and checked against the older value (for a successful authentication
|
|
the received <emphasis>nc</emphasis> must be greater then the
|
|
previously received one, see rfc2617 for more details). This will
|
|
provide protection against replay attacks while still allowing
|
|
credentials caching at the UA side.
|
|
</para>
|
|
<para>
|
|
It depends on <varname>qop</varname> being enabled (if
|
|
<varname>qop</varname> is not enabled, the challenges won't include
|
|
<emphasis>qop</emphasis> and so the UA will probably not include the
|
|
<emphasis>qop</emphasis> or <emphasis>nc</emphasis> parameters in its
|
|
response).
|
|
</para>
|
|
<para>
|
|
If a response doesn't include <emphasis>qop</emphasis> or
|
|
<emphasis>nc</emphasis> (for example obsolete UAs that don't support
|
|
them) the response will be checked according to the other enabled
|
|
nonce checks, in this order: one_time_nonce and auth_check_*.
|
|
If a response includes <emphasis>nc</emphasis> only the normal
|
|
<varname>nonce_expire</varname> checks and the
|
|
<varname>nonce_count</varname> checks will be performed, all
|
|
the other checks will be ignored.
|
|
</para>
|
|
<para>
|
|
The <varname>nonce_count</varname> checks work by tracking a limited
|
|
number of nonces. The maximum number of tracked nonces is set using
|
|
the <varname>nc_array_size</varname> or
|
|
<varname>nc_array_order</varname> parameters. If this number is
|
|
exceeded, older entries will be overwritten. As long as the maximum
|
|
rate of challengeable messages per average response time is lower then
|
|
<varname>nc_array_size</varname>, the <varname>nonce_count</varname>
|
|
checks should work flawlessly. For optimum performance (maximum reuse
|
|
of cache credentials) <varname>nc_array_size</varname> divided by
|
|
<varname>nid_pool_no</varname> should be lower then the message rate
|
|
multiplied by the desired <varname>nonce_expire</varname>.
|
|
</para>
|
|
<para>
|
|
The maximum accepted <emphasis>nc</emphasis> value is 255. If
|
|
<emphasis>nc</emphasis> becomes greater then this, the nonce will be
|
|
considered stale and the UA will be re-challenged.
|
|
</para>
|
|
<para>
|
|
<emphasis>Note:</emphasis> <varname>nonce_count</varname> should be
|
|
enabled only in stateful mode (a transaction should be created prior
|
|
to the authentication check to absorb possible retransmissions and all
|
|
the replies should be sent statefuly, using
|
|
<function>t_reply()</function>).
|
|
If <varname>nonce_count</varname> and the authentication checks are
|
|
used in the stateless mode then all retransmissions will be
|
|
challenged.
|
|
</para>
|
|
<para>
|
|
The default value is 0 (off).
|
|
</para>
|
|
<para>
|
|
See also:
|
|
<varname>qop</varname>,
|
|
<varname>nc_array_size</varname>,
|
|
<varname>nc_array_order</varname>,
|
|
<varname>nid_pool_no</varname>,
|
|
<varname>nonce_expire</varname>.
|
|
<varname>one_time_nonce</varname>.
|
|
</para>
|
|
<example>
|
|
<title>nonce_count example</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "nonce_count", 1) # enable nonce_count support
|
|
modparam("auth", "qop", "auth") # enable qop=auth
|
|
|
|
....
|
|
route{
|
|
...
|
|
# go stateful and catch retransmissions
|
|
if (!t_newtran()) {
|
|
xlog("L_NOTICE", "Failed to create new transaction\n");
|
|
drop;
|
|
};
|
|
if (method=="REGISTER"){
|
|
if (!www_authenticate("test", "credentials")){
|
|
# reply must be sent with t_reply because the
|
|
# transaction is already created at this point
|
|
# (we are in "stateful" mode)
|
|
if ($? == -2){
|
|
t_reply("500", "Internal Server Error");
|
|
}else if ($? == -3){
|
|
t_reply("400", "Bad Request");
|
|
}else{
|
|
if ($digest_challenge)
|
|
append_to_reply("%$digest_challenge");
|
|
t_reply("401", "Unauthorized");
|
|
}
|
|
drop;
|
|
}
|
|
if (!save_noreply("location")) {
|
|
t_reply("400", "Invalid REGISTER Request");
|
|
drop;
|
|
}
|
|
append_to_reply("%$contact");
|
|
t_reply("$code", "$reason"); # no %, avps are used directly
|
|
drop;
|
|
}else{
|
|
if (!proxy_authenticate("my_realm", "credentials")){
|
|
if ($? == -2){
|
|
t_reply("500", "Internal Server Error");
|
|
}else if ($? == -3){
|
|
t_reply("400", "Bad Request");
|
|
}else{
|
|
if ($digest_challenge)
|
|
append_to_reply("%$digest_challenge");
|
|
t_reply("401", "Unauthorized");
|
|
}
|
|
drop;
|
|
}
|
|
}
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="one_time_nonce">
|
|
<title><varname>one_time_nonce</varname> (boolean)</title>
|
|
<para>
|
|
If set to 1 nonce reuse is disabled: each nonce is allowed only once,
|
|
in the first reponse to a challenge. All the messages will be
|
|
challenged, even retransmissions. Stateful mode should be used, to
|
|
catch retransmissions before the authentication checks (using
|
|
<function>t_newtran()</function> before the authentication checks
|
|
and sending all the replies with <function>t_reply()</function>).
|
|
</para>
|
|
<para>
|
|
<varname>one_time_nonce</varname> provides enhanced replay protections
|
|
at the cost of invalidating UA side credentials caching, challenging
|
|
every message (and thus generating extra messages and extra
|
|
round-trips) and requiring stateful mode. In general
|
|
<varname>qop</varname> and <varname>nonce_count</varname> should
|
|
be prefered (if possible) with fallback to
|
|
<varname>auth_checks_*</varname>. Due to the disadvantages listed
|
|
above, <varname>one_time_nonce</varname> should be used only if the
|
|
extra checks provided by <varname>auth_checks_register</varname>,
|
|
<varname>auth_checks_no_dlg</varname> and
|
|
<varname>auth_checks_in_dlg</varname> are deemed insufficient for a
|
|
specific setup.
|
|
</para>
|
|
<para>
|
|
Compared to <varname>nonce_count</varname>,
|
|
<varname>one_time_nonce</varname> provides the same protection, but at
|
|
a higher message cost. The only advantages are that it works with
|
|
user agents that do not support <emphasis>qop</emphasis> and
|
|
<emphasis>nc</emphasis> and that it uses less memory for the same
|
|
supported number of maximum in-flight nonces (by a factor of 8).
|
|
<varname>one_time_nonce</varname> can be used as fallback from
|
|
<varname>nonce_count</varname>, when the UA doesn't support
|
|
<emphasis>nc</emphasis> (it happens automatically when both of them
|
|
are enabled).
|
|
</para>
|
|
<para>
|
|
Like <varname>nonce_count</varname>, <varname>one_time_nonce</varname>
|
|
works by tracking a limited number of nonces. The maximum number of
|
|
tracked nonces is set using the <varname>otn_in_flight_no</varname> or
|
|
<varname>otn_in_flight_order</varname> parameters. If this number is
|
|
exceeded, older entries will be overwritten. As long as the maximum
|
|
rate of challengeable messages per average response time is lower then
|
|
<varname>otn_in_flight_no</varname>, the
|
|
<varname>one_time_nonce</varname> checks should work flawlessly.
|
|
</para>
|
|
<para>
|
|
The default value is 0 (off).
|
|
</para>
|
|
<para>
|
|
See also:
|
|
<varname>otn_in_flight_no</varname>,
|
|
<varname>otn_in_flight_order</varname>,
|
|
<varname>nid_pool_no</varname> and
|
|
<varname>nonce_count</varname>.
|
|
</para>
|
|
<example>
|
|
<title>one_time_nonce example</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "one_time_nonce", 1)
|
|
# Note: stateful mode should be used, see the nonce_count example
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="nid_pool_no">
|
|
<title><varname>nid_pool_no</varname> (integer)</title>
|
|
<para>
|
|
Controls the number of partitions for the
|
|
<varname>nonce_count</varname> and <varname>one_time_nonce</varname>
|
|
arrays (it's common to both of them to reduce the nonce size).
|
|
</para>
|
|
<para>
|
|
Instead of using single arrays for keeping nonce state, these arrays
|
|
can be divided into more partitions. Each ser process is assigned to
|
|
one of these partitions, allowing for higher concurrency on multi-CPU
|
|
machines. Besides increasing performance, increasing
|
|
<varname>nid_pool_no</varname> has also a negative effect: it could
|
|
decrease the maximum supported in-flight nonces in certain conditions.
|
|
In the worst case, when only one ser process receives most of the
|
|
traffic (e.g. very busy tcp connection between two proxies), the
|
|
in-flight nonces could be limited to the array size
|
|
(<varname>nc_array_size</varname> for <varname>nonce_count</varname>
|
|
or <varname>otn_in_flight_no</varname> for
|
|
<varname>one_time_nonce</varname>) divided by the partitions number
|
|
(<varname>nid_pool_no</varname>). However for normal traffic, when
|
|
the process receiving a message is either random or chosen in
|
|
a round-robin fashion the maximum in-flight nonces number will be
|
|
very little influenced by <varname>nid_pool_no</varname> (the
|
|
messages will be close to equally distributed to processes using
|
|
different partitions).
|
|
</para>
|
|
<para>
|
|
<varname>nid_pool_no</varname> value should be one of: 1, 2, 4, 8, 16,
|
|
32 or 64 (the maximum value is 64 and all values should be of the
|
|
form 2^k or else they will be rounded down to 2^k).
|
|
</para>
|
|
<para>
|
|
The default value is 1.
|
|
</para>
|
|
<para>
|
|
See also:
|
|
<varname>nonce_count</varname>,
|
|
<varname>one_time_nonce</varname>,
|
|
<varname>nc_array_size</varname> and
|
|
<varname>otn_in_flight_no</varname>.
|
|
</para>
|
|
<example>
|
|
<title>nid_pool_no example</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "nid_pool_no", 4)
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="nc_array_size">
|
|
<title><varname>nc_array_size</varname> (integer)</title>
|
|
<para>
|
|
Maximum number of in-flight nonces for <varname>nonce_count</varname>.
|
|
It represents the maximum nonces for which state will be kept. When
|
|
this number is exceeded, state for the older nonces will be
|
|
discarded to make space for new ones (see
|
|
<varname>nonce_count</varname> for more details).
|
|
</para>
|
|
<para>
|
|
The value should be of the form 2^k. If it's not it will be rounded
|
|
down to 2^k (for example a value of 1000000 will be rounded down to
|
|
2^19=524288). <varname>nc_array_order</varname> can be used to
|
|
directly specify the power of 2 (e.g.
|
|
<varname>nc_array_order</varname> set to 20 is equivalent to
|
|
<varname>nc_array_size</varname> set to 1048576).
|
|
</para>
|
|
<para>
|
|
The memory used to keep the nonce state will be
|
|
<varname>nc_array_size</varname> in bytes.
|
|
</para>
|
|
<para>
|
|
The default value is 1048576 (1M in-flight nonces, using 1Mb memory).
|
|
</para>
|
|
<para>
|
|
See also:
|
|
<varname>nonce_count</varname> and
|
|
<varname>nid_pool_no</varname>.
|
|
</para>
|
|
<example>
|
|
<title>nc_array_size example</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "nc_array_size", 4194304) # 4Mb
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="nc_array_order">
|
|
<title><varname>nc_array_order</varname> (integer)</title>
|
|
<para>
|
|
Equivalent to <varname>nc_array_size</varname>, but instead of
|
|
directly specifying the size, its value is the power at which 2 should
|
|
be raised (log2(<varname>nc_array_size</varname>)).
|
|
</para>
|
|
<para>
|
|
<varname>nc_array_size</varname> = 2^<varname>nc_array_order</varname>.
|
|
For more details see <varname>nc_array_size</varname>.
|
|
</para>
|
|
<para>
|
|
The default value is 20 (1M in-flight nonces, using 1Mb memory).
|
|
</para>
|
|
<para>
|
|
See also:
|
|
<varname>nonce_count</varname>,
|
|
<varname>nc_array_size</varname> and
|
|
<varname>nid_pool_no</varname>.
|
|
</para>
|
|
<example>
|
|
<title>nc_array_order example</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "nc_array_order", 22) # 4Mb
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="otn_in_flight_no">
|
|
<title><varname>otn_in_flight_no</varname> (integer)</title>
|
|
<para>
|
|
Maximum number of in-flight nonces for
|
|
<varname>one_time_nonce</varname>. It represents the maximum number
|
|
of nonces remembered for the one-time-nonce check. When this
|
|
number is exceeded, information about older nonces will be discarded
|
|
and overwritten with information about the new generated ones (see
|
|
<varname>one_time_nonce</varname> for more details).
|
|
</para>
|
|
<para>
|
|
The value should be of the form 2^k. If it's not it will be rounded
|
|
down to 2^k (for example a value of 1000000 will be rounded down to
|
|
2^19=524288). <varname>otn_in_flight_no</varname> can be used to
|
|
directly specify the power of 2 (e.g.
|
|
<varname>otn_in_flight_order</varname> set to 19 is equivalent to
|
|
<varname>otn_in_fligh_number</varname> set to 524288).
|
|
</para>
|
|
<para>
|
|
The memory used to keep the nonce information will be the
|
|
<varname>otn_in_flight_no</varname> divided by 8 (only 1 bit of state
|
|
is kept per nonce).
|
|
</para>
|
|
<para>
|
|
The default value is 1048576 (1M in-flight nonces, using
|
|
128Kb memory).
|
|
</para>
|
|
<para>
|
|
See also:
|
|
<varname>one_time_nonce</varname> and
|
|
<varname>nid_pool_no</varname>.
|
|
</para>
|
|
<example>
|
|
<title>otn_in_flight_no example</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "otn_in_flight_no", 8388608) # 8 Mb (1Mb memory)
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="otn_in_flight_order">
|
|
<title><varname>otn_in_flight_order</varname> (integer)</title>
|
|
<para>
|
|
Equivalent to <varname>otn_in_flight_no</varname>, but instead of
|
|
directly specifying the size, its value is the power at which 2 should
|
|
be raised (log2(<varname>otn_in_flight_no</varname>)).
|
|
</para>
|
|
<para>
|
|
<varname>otn_in_flight_no</varname> =
|
|
2^<varname>otn_in_flight_order</varname>.
|
|
For more details see <varname>otn_in_flight_order</varname>.
|
|
</para>
|
|
<para>
|
|
The default value is 20 (1M in-flight nonces, using 128Kb memory).
|
|
</para>
|
|
<para>
|
|
See also:
|
|
<varname>one_time_nonce</varname>,
|
|
<varname>otn_in_flight_no</varname> and
|
|
<varname>nid_pool_no</varname>.
|
|
</para>
|
|
<example>
|
|
<title>otn_in_flight_order example</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "otn_in_flight_order", 23) # 8 Mb (1Mb memory)
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="auth.secret">
|
|
<title><varname>secret</varname> (string)</title>
|
|
<para>
|
|
Default value is randomly generated string.
|
|
</para>
|
|
<example>
|
|
<title>Setting secret module parameter</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "secret", "johndoessecretphrase")
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="nonce_expire">
|
|
<title><varname>nonce_expire</varname> (integer)</title>
|
|
<para>
|
|
Nonces have limited lifetime. After a given period of time nonces
|
|
will be considered invalid. This is to protect replay
|
|
attacks. Credentials containing a stale nonce will be not
|
|
authorized, but the user agent will be challenged again. This time
|
|
the challenge will contain <varname>stale</varname> parameter which
|
|
will indicate to the client that it doesn't have to disturb user by
|
|
asking for username and password, it can recalculate credentials
|
|
using existing username and password.
|
|
</para>
|
|
<para>
|
|
The value is in seconds and default value is 300 seconds.
|
|
</para>
|
|
<example>
|
|
<title>nonce_expire example</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "nonce_expire", 600) # Set nonce_expire to 600s
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="nonce_auth_max_drift">
|
|
<title><varname>nonce_auth_max_drift</varname> (integer)</title>
|
|
<para>
|
|
Maximum difference in seconds between a nonce creation time and the
|
|
current time, if the nonce creation time appears to be in the future.
|
|
</para>
|
|
<para>
|
|
In some cases, like shortly after a system time backward adjustment
|
|
or when the current proxy is part of a cluster which is not
|
|
time-synchronized, it's possible to receive a nonce with creation time
|
|
in the future. In this case if the difference is greater then
|
|
<varname>nonce_auth_max_drift</varname> seconds, consider the nonce
|
|
stale and re-challenge (otherwise after a dramatic time change
|
|
backwards, it might happen that some previously generated nonces will
|
|
be valid for too much time).
|
|
</para>
|
|
<para>
|
|
The default value is 3 seconds
|
|
</para>
|
|
<para>
|
|
See also: <varname>nonce_expire</varname>.
|
|
</para>
|
|
<example>
|
|
<title>nonce_auth_max_drift example</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "nonce_auth_max_drift", 1) # set max drift to 1 s
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section id="force_stateless_reply">
|
|
<title><varname>force_stateless_reply</varname> (boolean)</title>
|
|
<para>
|
|
If set to 1, <function>www_challenge()</function> and
|
|
<function>proxy_challenge()</function>
|
|
functions send reply statelessly no matter if transaction
|
|
exists or not. If set to 0 (default), reply is sent statefully
|
|
if transaction exists and stelelessly otherwise.
|
|
</para>
|
|
<example>
|
|
<title>force_stateless_reply example</title>
|
|
<programlisting>
|
|
...
|
|
modparam("auth", "force_stateless_reply", 1)
|
|
...
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
</section>
|