Commit 78e31dd1 authored by Mark Andrews's avatar Mark Andrews
Browse files

4437. [func] Minimal-responses now has two additional modes

                        no-auth and no-auth-recursive which suppress
                        adding the NS records to the authority section
                        as well as the associated address records for the
                        nameservers. [RT #42005]
parent aaeed646
4437. [func] Minimal-responses now has two additional modes
no-auth and no-auth-recursive which suppress
adding the NS records to the authority section
as well as the associated address records for the
nameservers. [RT #42005]
4436. [func] Return TLSA records as additional data for MX and SRV 4436. [func] Return TLSA records as additional data for MX and SRV
lookups. [RT #42894] lookups. [RT #42894]
......
...@@ -241,7 +241,7 @@ options { ...@@ -241,7 +241,7 @@ options {
topology { <replaceable>address_match_element</replaceable>; ... }; // not implemented topology { <replaceable>address_match_element</replaceable>; ... }; // not implemented
auth-nxdomain <replaceable>boolean</replaceable>; // default changed auth-nxdomain <replaceable>boolean</replaceable>; // default changed
minimal-any <replaceable>boolean</replaceable>; minimal-any <replaceable>boolean</replaceable>;
minimal-responses <replaceable>boolean</replaceable>; minimal-responses ( <replaceable>boolean</replaceable> | no-auth | no-auth-recursive );
recursion <replaceable>boolean</replaceable>; recursion <replaceable>boolean</replaceable>;
rrset-order { rrset-order {
<optional> class <replaceable>string</replaceable> </optional> <optional> type <replaceable>string</replaceable> </optional> <optional> class <replaceable>string</replaceable> </optional> <optional> type <replaceable>string</replaceable> </optional>
......
...@@ -9048,9 +9048,21 @@ ns_query_start(ns_client_t *client) { ...@@ -9048,9 +9048,21 @@ ns_query_start(ns_client_t *client) {
if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0) if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0)
client->attributes |= NS_CLIENTATTR_WANTDNSSEC; client->attributes |= NS_CLIENTATTR_WANTDNSSEC;
if (client->view->minimalresponses) switch (client->view->minimalresponses) {
case dns_minimal_no:
break;
case dns_minimal_yes:
client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
NS_QUERYATTR_NOADDITIONAL); NS_QUERYATTR_NOADDITIONAL);
break;
case dns_minimal_noauth:
client->query.attributes |= NS_QUERYATTR_NOAUTHORITY;
break;
case dns_minimal_noauthrec:
if ((message->flags & DNS_MESSAGEFLAG_RD) != 0)
client->query.attributes |= NS_QUERYATTR_NOAUTHORITY;
break;
}
if ((client->view->cachedb == NULL) if ((client->view->cachedb == NULL)
|| (!client->view->additionalfromcache)) { || (!client->view->additionalfromcache)) {
......
...@@ -4090,7 +4090,20 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, ...@@ -4090,7 +4090,20 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
obj = NULL; obj = NULL;
result = ns_config_get(maps, "minimal-responses", &obj); result = ns_config_get(maps, "minimal-responses", &obj);
INSIST(result == ISC_R_SUCCESS); INSIST(result == ISC_R_SUCCESS);
view->minimalresponses = cfg_obj_asboolean(obj); if (cfg_obj_isboolean(obj)) {
if (cfg_obj_asboolean(obj))
view->minimalresponses = dns_minimal_yes;
else
view->minimalresponses = dns_minimal_no;
} else {
str = cfg_obj_asstring(obj);
if (strcasecmp(str, "no-auth") == 0) {
view->minimalresponses = dns_minimal_noauth;
} else if (strcasecmp(str, "no-auth-recursive") == 0) {
view->minimalresponses = dns_minimal_noauthrec;
} else
INSIST(0);
}
obj = NULL; obj = NULL;
result = ns_config_get(maps, "transfer-format", &obj); result = ns_config_get(maps, "transfer-format", &obj);
......
...@@ -18,6 +18,7 @@ options { ...@@ -18,6 +18,7 @@ options {
listen-on-v6 { none; }; listen-on-v6 { none; };
notify no; notify no;
minimal-any yes; minimal-any yes;
minimal-responses no-auth;
}; };
include "../../common/rndc.key"; include "../../common/rndc.key";
...@@ -30,3 +31,23 @@ zone "rt.example" { ...@@ -30,3 +31,23 @@ zone "rt.example" {
type master; type master;
file "rt.db"; file "rt.db";
}; };
zone "naptr.example" {
type master;
file "naptr.db";
};
zone "rt2.example" {
type master;
file "rt2.db";
};
zone "naptr2.example" {
type master;
file "naptr2.db";
};
zone "nid.example" {
type master;
file "nid.db";
};
...@@ -11,11 +11,13 @@ options { ...@@ -11,11 +11,13 @@ options {
notify-source 10.53.0.1; notify-source 10.53.0.1;
transfer-source 10.53.0.1; transfer-source 10.53.0.1;
recursion no; recursion no;
additional-from-auth no;
port 5300; port 5300;
pid-file "named.pid"; pid-file "named.pid";
listen-on { 10.53.0.1; }; listen-on { 10.53.0.1; };
listen-on-v6 { none; }; listen-on-v6 { none; };
notify no; notify no;
minimal-responses no-auth-recursive;
}; };
include "../../common/rndc.key"; include "../../common/rndc.key";
...@@ -33,3 +35,28 @@ zone "srv.example" { ...@@ -33,3 +35,28 @@ zone "srv.example" {
type master; type master;
file "srv.db"; file "srv.db";
}; };
zone "rt.example" {
type master;
file "rt.db";
};
zone "naptr.example" {
type master;
file "naptr.db";
};
zone "rt2.example" {
type master;
file "rt2.db";
};
zone "naptr2.example" {
type master;
file "naptr2.db";
};
zone "nid.example" {
type master;
file "nid.db";
};
...@@ -16,81 +16,192 @@ n=0 ...@@ -16,81 +16,192 @@ n=0
dotests() { dotests() {
n=`expr $n + 1` n=`expr $n + 1`
echo "I:test with RT, single zone ($n)" echo "I:test with RT, single zone (+rec) ($n)"
ret=0 ret=0
$DIG -t RT rt.rt.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1 $DIG +rec -t RT rt.rt.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $ret -eq 1 ] ; then if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1 echo "I: failed"; status=1
fi fi
n=`expr $n + 1` n=`expr $n + 1`
echo "I:test with RT, two zones ($n)" echo "I:test with RT, two zones (+rec) ($n)"
ret=0 ret=0
$DIG -t RT rt.rt2.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1 $DIG +rec -t RT rt.rt2.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $ret -eq 1 ] ; then if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1 echo "I: failed"; status=1
fi fi
n=`expr $n + 1` n=`expr $n + 1`
echo "I:test with NAPTR, single zone ($n)" echo "I:test with NAPTR, single zone (+rec) ($n)"
ret=0 ret=0
$DIG -t NAPTR nap.naptr.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1 $DIG +rec -t NAPTR nap.naptr.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $ret -eq 1 ] ; then if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1 echo "I: failed"; status=1
fi fi
n=`expr $n + 1` n=`expr $n + 1`
echo "I:test with NAPTR, two zones ($n)" echo "I:test with NAPTR, two zones (+rec) ($n)"
ret=0 ret=0
$DIG -t NAPTR nap.hang3b.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1 $DIG +rec -t NAPTR nap.hang3b.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $ret -eq 1 ] ; then if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1 echo "I: failed"; status=1
fi fi
n=`expr $n + 1` n=`expr $n + 1`
echo "I:test with LP ($n)" echo "I:test with LP (+rec) ($n)"
ret=0 ret=0
$DIG -t LP nid2.nid.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1 $DIG +rec -t LP nid2.nid.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
case $minimal in
no)
grep -w "NS" dig.out.$n > /dev/null || ret=1
grep -w "L64" dig.out.$n > /dev/null || ret=1
grep -w "L32" dig.out.$n > /dev/null || ret=1
;;
yes)
grep -w "NS" dig.out.$n > /dev/null && ret=1
grep -w "L64" dig.out.$n > /dev/null && ret=1
grep -w "L32" dig.out.$n > /dev/null && ret=1
;;
no-auth)
grep -w "NS" dig.out.$n > /dev/null && ret=1
grep -w "L64" dig.out.$n > /dev/null || ret=1
grep -w "L32" dig.out.$n > /dev/null || ret=1
;;
no-auth-recursive)
grep -w "NS" dig.out.$n > /dev/null && ret=1
grep -w "L64" dig.out.$n > /dev/null || ret=1
grep -w "L32" dig.out.$n > /dev/null || ret=1
;;
esac
if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1
fi
n=`expr $n + 1`
echo "I:test with NID (+rec) ($n)"
ret=0
$DIG +rec -t NID ns1.nid.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $minimal = no ] ; then if [ $minimal = no ] ; then
grep "L64" dig.out.$n > /dev/null || ret=1 # change && to || when we support NID additional processing
grep "L32" dig.out.$n > /dev/null || ret=1 grep -w "L64" dig.out.$n > /dev/null && ret=1
grep -w "L32" dig.out.$n > /dev/null && ret=1
else else
grep "L64" dig.out.$n > /dev/null && ret=1 grep -w "L64" dig.out.$n > /dev/null && ret=1
grep "L32" dig.out.$n > /dev/null && ret=1 grep -w "L32" dig.out.$n > /dev/null && ret=1
fi fi
if [ $ret -eq 1 ] ; then if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1 echo "I: failed"; status=1
fi fi
n=`expr $n + 1` n=`expr $n + 1`
echo "I:test with NID ($n)" echo "I:test with NID + LP (+rec) ($n)"
ret=0 ret=0
$DIG -t NID ns1.nid.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1 $DIG +rec -t NID nid2.nid.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $minimal = no ] ; then if [ $minimal = no ] ; then
# change && to || when we support NID additional processing # change && to || when we support NID additional processing
grep "L64" dig.out.$n > /dev/null && ret=1 grep -w "LP" dig.out.$n > /dev/null && ret=1
grep "L32" dig.out.$n > /dev/null && ret=1 grep -w "L64" dig.out.$n > /dev/null && ret=1
grep -w "L32" dig.out.$n > /dev/null && ret=1
else else
grep "L64" dig.out.$n > /dev/null && ret=1 grep -w "LP" dig.out.$n > /dev/null && ret=1
grep "L32" dig.out.$n > /dev/null && ret=1 grep -w "L64" dig.out.$n > /dev/null && ret=1
grep -w "L32" dig.out.$n > /dev/null && ret=1
fi
if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1
fi
n=`expr $n + 1`
echo "I:test with RT, single zone (+norec) ($n)"
ret=0
$DIG +norec -t RT rt.rt.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1
fi fi
n=`expr $n + 1`
echo "I:test with RT, two zones (+norec) ($n)"
ret=0
$DIG +norec -t RT rt.rt2.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $ret -eq 1 ] ; then if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1 echo "I: failed"; status=1
fi fi
n=`expr $n + 1` n=`expr $n + 1`
echo "I:test with NID + LP ($n)" echo "I:test with NAPTR, single zone (+norec) ($n)"
ret=0 ret=0
$DIG -t NID nid2.nid.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1 $DIG +norec -t NAPTR nap.naptr.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1
fi
n=`expr $n + 1`
echo "I:test with NAPTR, two zones (+norec) ($n)"
ret=0
$DIG +norec -t NAPTR nap.hang3b.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1
fi
n=`expr $n + 1`
echo "I:test with LP (+norec) ($n)"
ret=0
$DIG +norec -t LP nid2.nid.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
case $minimal in
no)
grep -w "NS" dig.out.$n > /dev/null || ret=1
grep -w "L64" dig.out.$n > /dev/null || ret=1
grep -w "L32" dig.out.$n > /dev/null || ret=1
;;
yes)
grep -w "NS" dig.out.$n > /dev/null && ret=1
grep -w "L64" dig.out.$n > /dev/null && ret=1
grep -w "L32" dig.out.$n > /dev/null && ret=1
;;
no-auth)
grep -w "NS" dig.out.$n > /dev/null && ret=1
grep -w "L64" dig.out.$n > /dev/null || ret=1
grep -w "L32" dig.out.$n > /dev/null || ret=1
;;
no-auth-recursive)
grep -w "NS" dig.out.$n > /dev/null || ret=1
grep -w "L64" dig.out.$n > /dev/null || ret=1
grep -w "L32" dig.out.$n > /dev/null || ret=1
;;
esac
if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1
fi
n=`expr $n + 1`
echo "I:test with NID (+norec) ($n)"
ret=0
$DIG +norec -t NID ns1.nid.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $minimal = no ] ; then if [ $minimal = no ] ; then
# change && to || when we support NID additional processing # change && to || when we support NID additional processing
grep "LP" dig.out.$n > /dev/null && ret=1 grep -w "L64" dig.out.$n > /dev/null && ret=1
grep "L64" dig.out.$n > /dev/null && ret=1 grep -w "L32" dig.out.$n > /dev/null && ret=1
grep "L32" dig.out.$n > /dev/null && ret=1
else else
grep "LP" dig.out.$n > /dev/null && ret=1 grep -w "L64" dig.out.$n > /dev/null && ret=1
grep "L64" dig.out.$n > /dev/null && ret=1 grep -w "L32" dig.out.$n > /dev/null && ret=1
grep "L32" dig.out.$n > /dev/null && ret=1 fi
if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1
fi
n=`expr $n + 1`
echo "I:test with NID + LP (+norec) ($n)"
ret=0
$DIG +norec -t NID nid2.nid.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
if [ $minimal = no ] ; then
# change && to || when we support NID additional processing
grep -w "LP" dig.out.$n > /dev/null && ret=1
grep -w "L64" dig.out.$n > /dev/null && ret=1
grep -w "L32" dig.out.$n > /dev/null && ret=1
else
grep -w "LP" dig.out.$n > /dev/null && ret=1
grep -w "L64" dig.out.$n > /dev/null && ret=1
grep -w "L32" dig.out.$n > /dev/null && ret=1
fi fi
if [ $ret -eq 1 ] ; then if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1 echo "I: failed"; status=1
...@@ -133,11 +244,19 @@ if [ $ret -eq 1 ] ; then ...@@ -133,11 +244,19 @@ if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1 echo "I: failed"; status=1
fi fi
echo "I:testing with 'minimal-responses no-auth;'"
minimal=no-auth
dotests
echo "I:reconfiguring server" echo "I:reconfiguring server"
cp ns1/named4.conf ns1/named.conf cp ns1/named4.conf ns1/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 reconfig 2>&1 | sed 's/^/I:ns1 /' $RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 reconfig 2>&1 | sed 's/^/I:ns1 /'
sleep 2 sleep 2
echo "I:testing with 'minimal-responses no-auth-recursive;'"
minimal=no-auth-recursive
dotests
n=`expr $n + 1` n=`expr $n + 1`
echo "I:testing returning TLSA records with MX query ($n)" echo "I:testing returning TLSA records with MX query ($n)"
ret=0 ret=0
......
...@@ -4429,7 +4429,7 @@ badresp:1,adberr:0,findfail:0,valfail:0] ...@@ -4429,7 +4429,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<optional> host-statistics <replaceable>yes_or_no</replaceable>; </optional> <optional> host-statistics <replaceable>yes_or_no</replaceable>; </optional>
<optional> host-statistics-max <replaceable>number</replaceable>; </optional> <optional> host-statistics-max <replaceable>number</replaceable>; </optional>
<optional> minimal-any <replaceable>yes_or_no</replaceable>; </optional> <optional> minimal-any <replaceable>yes_or_no</replaceable>; </optional>
<optional> minimal-responses <replaceable>yes_or_no</replaceable>; </optional> <optional> minimal-responses (<replaceable>yes_or_no</replaceable> | <constant>no-auth</constant> | <constant>no-auth-recursive</constant>); </optional>
<optional> multiple-cnames <replaceable>yes_or_no</replaceable>; </optional> <optional> multiple-cnames <replaceable>yes_or_no</replaceable>; </optional>
<optional> notify <replaceable>yes_or_no</replaceable> | <replaceable>explicit</replaceable> | <replaceable>master-only</replaceable>; </optional> <optional> notify <replaceable>yes_or_no</replaceable> | <replaceable>explicit</replaceable> | <replaceable>master-only</replaceable>; </optional>
<optional> recursion <replaceable>yes_or_no</replaceable>; </optional> <optional> recursion <replaceable>yes_or_no</replaceable>; </optional>
...@@ -6187,11 +6187,26 @@ options { ...@@ -6187,11 +6187,26 @@ options {
<term><command>minimal-responses</command></term> <term><command>minimal-responses</command></term>
<listitem> <listitem>
<para> <para>
If <userinput>yes</userinput>, then when generating If set to <userinput>yes</userinput>, then when generating
responses the server will only add records to the authority responses the server will only add records to the authority
and additional data sections when they are required (e.g. and additional data sections when they are required (e.g.
delegations, negative responses). This may improve the delegations, negative responses). This may improve the
performance of the server. performance of the server.
</para>
<para>
When set to <userinput>no-auth</userinput>, the
server will omit records from the authority section
unless they are required, but it may still add
records to the additional section. When set to
<userinput>no-auth-recursive</userinput>, this
is only done if the query is recursive. These
settings are useful when answering stub clients,
which usually ignore the authority section.
<userinput>no-auth-recursive</userinput> is
designed for mixed-mode servers which handle
both authoritative and recursive queries.
</para>
<para>
The default is <userinput>no</userinput>. The default is <userinput>no</userinput>.
</para> </para>
</listitem> </listitem>
......
...@@ -537,7 +537,7 @@ ...@@ -537,7 +537,7 @@
<listitem> <listitem>
<para> <para>
An <command>--enable-querytrace</command> configure switch is An <command>--enable-querytrace</command> configure switch is
now available to enable very verbose query tracelogging. This now available to enable very verbose query trace logging. This
option can only be set at compile time. This option has a option can only be set at compile time. This option has a
negative performance impact and should be used only for negative performance impact and should be used only for
debugging. [RT #37520] debugging. [RT #37520]
...@@ -843,6 +843,15 @@ ...@@ -843,6 +843,15 @@
block the server. block the server.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<command>minimal-responses</command> now takes two new
arguments: <option>no-auth</option> suppresses
populating the authority section but not the additional
section; <option>no-auth-recursive</option>
does the same but only when answering recursive queries.
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>
......
...@@ -188,6 +188,13 @@ typedef enum { ...@@ -188,6 +188,13 @@ typedef enum {
dns_notifytype_masteronly = 3 dns_notifytype_masteronly = 3
} dns_notifytype_t; } dns_notifytype_t;
typedef enum {
dns_minimal_no = 0,
dns_minimal_yes = 1,
dns_minimal_noauth = 2,
dns_minimal_noauthrec = 3
} dns_minimaltype_t;
typedef enum { typedef enum {
dns_dialuptype_no = 0, dns_dialuptype_no = 0,
dns_dialuptype_yes = 1, dns_dialuptype_yes = 1,
......
...@@ -117,7 +117,7 @@ struct dns_view { ...@@ -117,7 +117,7 @@ struct dns_view {
isc_boolean_t additionalfromcache; isc_boolean_t additionalfromcache;
isc_boolean_t additionalfromauth; isc_boolean_t additionalfromauth;
isc_boolean_t minimal_any; isc_boolean_t minimal_any;
isc_boolean_t minimalresponses; dns_minimaltype_t minimalresponses;
isc_boolean_t enablednssec; isc_boolean_t enablednssec;
isc_boolean_t enablevalidation; isc_boolean_t enablevalidation;
isc_boolean_t acceptexpired; isc_boolean_t acceptexpired;
......
...@@ -186,7 +186,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, ...@@ -186,7 +186,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->enablevalidation = ISC_TRUE; view->enablevalidation = ISC_TRUE;
view->acceptexpired = ISC_FALSE; view->acceptexpired = ISC_FALSE;
view->minimal_any = ISC_FALSE; view->minimal_any = ISC_FALSE;
view->minimalresponses = ISC_FALSE; view->minimalresponses = dns_minimal_no;
view->transfer_format = dns_one_answer; view->transfer_format = dns_one_answer;
view->cacheacl = NULL; view->cacheacl = NULL;
view->cacheonacl = NULL; view->cacheonacl = NULL;
......
...@@ -89,14 +89,19 @@ doc_geoip(cfg_printer_t *pctx, const cfg_type_t *type); ...@@ -89,14 +89,19 @@ doc_geoip(cfg_printer_t *pctx, const cfg_type_t *type);
static cfg_type_t cfg_type_acl; static cfg_type_t cfg_type_acl;
static cfg_type_t cfg_type_addrmatchelt; static cfg_type_t cfg_type_addrmatchelt;
static cfg_type_t cfg_type_bracketed_aml; static cfg_type_t cfg_type_bracketed_aml;
static cfg_type_t cfg_type_bracketed_namesockaddrkeylist;
static cfg_type_t cfg_type_bracketed_dscpsockaddrlist; static cfg_type_t cfg_type_bracketed_dscpsockaddrlist;
static cfg_type_t cfg_type_bracketed_namesockaddrkeylist;
static cfg_type_t cfg_type_bracketed_sockaddrlist; static cfg_type_t cfg_type_bracketed_sockaddrlist;
static cfg_type_t cfg_type_bracketed_sockaddrnameportlist; static cfg_type_t cfg_type_bracketed_sockaddrnameportlist;
static cfg_type_t cfg_type_controls; static cfg_type_t cfg_type_controls;
static cfg_type_t cfg_type_controls_sockaddr;