Commit db30f4bd authored by Mark Andrews's avatar Mark Andrews

2353. [func] Add support for Name Server ID (RFC 5001).

                        'dig +nsid' requests NSID from server.
                        'request-nsid yes;' causes recursive server to send
                        NSID requests to upstream servers.  Server responds
                        to NSID requests with the string configured by
                        'server-id' option.  [RT #17091]
parent aeb79380
2353. [func] Add support for Name Server ID (RFC 5001).
'dig +nsid' requests NSID from server.
'request-nsid yes;' causes recursive server to send
NSID requests to upstream servers. Server responds
to NSID requests with the string configured by
'server-id' option. [RT #17091]
2352. [bug] Various GSS_API fixups. [RT #17729]
2351. [bug] convertxsl.pl generated very long lines. [RT #17906]
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dig.c,v 1.220 2008/02/05 23:47:08 tbox Exp $ */
/* $Id: dig.c,v 1.221 2008/04/03 02:01:08 marka Exp $ */
/*! \file */
......@@ -194,6 +194,7 @@ help(void) {
" +[no]identify (ID responders in short answers)\n"
" +[no]trace (Trace delegation down from root)\n"
" +[no]dnssec (Request DNSSEC records)\n"
" +[no]nsid (Request Name Server ID)\n"
#ifdef DIG_SIGCHASE
" +[no]sigchase (Chase DNSSEC signatures)\n"
" +trusted-key=#### (Trusted Key when chasing DNSSEC sigs)\n"
......@@ -860,21 +861,33 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto invalid_option;
ndots = parse_uint(value, "ndots", MAXNDOTS);
break;
case 's': /* nssearch */
FULLCHECK("nssearch");
lookup->ns_search_only = state;
if (state) {
lookup->trace_root = ISC_TRUE;
lookup->recurse = ISC_TRUE;
lookup->identify = ISC_TRUE;
lookup->stats = ISC_FALSE;
lookup->comments = ISC_FALSE;
lookup->section_additional = ISC_FALSE;
lookup->section_authority = ISC_FALSE;
lookup->section_question = ISC_FALSE;
lookup->rdtype = dns_rdatatype_ns;
lookup->rdtypeset = ISC_TRUE;
short_form = ISC_TRUE;
case 's':
switch (cmd[2]) {
case 'i': /* nsid */
FULLCHECK("nsid");
if (state && lookup->edns == -1)
lookup->edns = 0;
lookup->nsid = state;
break;
case 's': /* nssearch */
FULLCHECK("nssearch");
lookup->ns_search_only = state;
if (state) {
lookup->trace_root = ISC_TRUE;
lookup->recurse = ISC_TRUE;
lookup->identify = ISC_TRUE;
lookup->stats = ISC_FALSE;
lookup->comments = ISC_FALSE;
lookup->section_additional = ISC_FALSE;
lookup->section_authority = ISC_FALSE;
lookup->section_question = ISC_FALSE;
lookup->rdtype = dns_rdatatype_ns;
lookup->rdtypeset = ISC_TRUE;
short_form = ISC_TRUE;
}
break;
default:
goto invalid_option;
}
break;
default:
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dighost.c,v 1.308 2008/01/18 23:46:57 tbox Exp $ */
/* $Id: dighost.c,v 1.309 2008/04/03 02:01:08 marka Exp $ */
/*! \file
* \note
......@@ -724,6 +724,7 @@ make_empty_lookup(void) {
looknew->servfail_stops = ISC_TRUE;
looknew->besteffort = ISC_TRUE;
looknew->dnssec = ISC_FALSE;
looknew->nsid = ISC_FALSE;
#ifdef DIG_SIGCHASE
looknew->sigchase = ISC_FALSE;
#if DIG_SIGCHASE_TD
......@@ -803,6 +804,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
looknew->servfail_stops = lookold->servfail_stops;
looknew->besteffort = lookold->besteffort;
looknew->dnssec = lookold->dnssec;
looknew->nsid = lookold->nsid;
#ifdef DIG_SIGCHASE
looknew->sigchase = lookold->sigchase;
#if DIG_SIGCHASE_TD
......@@ -1155,11 +1157,11 @@ setup_libs(void) {
/*%
* Add EDNS0 option record to a message. Currently, the only supported
* options are UDP buffer size and the DO bit.
* options are UDP buffer size, the DO bit, and NSID request.
*/
static void
add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_uint16_t edns,
isc_boolean_t dnssec)
isc_boolean_t dnssec, isc_boolean_t nsid)
{
dns_rdataset_t *rdataset = NULL;
dns_rdatalist_t *rdatalist = NULL;
......@@ -1182,8 +1184,19 @@ add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_uint16_t edns,
rdatalist->ttl = edns << 16;
if (dnssec)
rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO;
rdata->data = NULL;
rdata->length = 0;
if (nsid) {
unsigned char data[4];
isc_buffer_t buf;
isc_buffer_init(&buf, data, sizeof(data));
isc_buffer_putuint16(&buf, DNS_OPT_NSID);
isc_buffer_putuint16(&buf, 0);
rdata->data = data;
rdata->length = sizeof(data);
} else {
rdata->data = NULL;
rdata->length = 0;
}
ISC_LIST_INIT(rdatalist->rdata);
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
dns_rdatalist_tordataset(rdatalist, rdataset);
......@@ -1998,7 +2011,7 @@ setup_lookup(dig_lookup_t *lookup) {
if (lookup->edns < 0)
lookup->edns = 0;
add_opt(lookup->sendmsg, lookup->udpsize,
lookup->edns, lookup->dnssec);
lookup->edns, lookup->dnssec, lookup->nsid);
}
result = dns_message_rendersection(lookup->sendmsg,
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dig.h,v 1.105 2007/06/18 23:47:17 tbox Exp $ */
/* $Id: dig.h,v 1.106 2008/04/03 02:01:08 marka Exp $ */
#ifndef DIG_H
#define DIG_H
......@@ -102,7 +102,7 @@ typedef struct dig_searchlist dig_searchlist_t;
/*% The dig_lookup structure */
struct dig_lookup {
isc_boolean_t
pending, /*%< Pending a successful answer */
pending, /*%< Pending a successful answer */
waiting_connect,
doing_xfr,
ns_search_only, /*%< dig +nssearch, host -C */
......@@ -129,27 +129,28 @@ struct dig_lookup {
need_search,
done_as_is,
besteffort,
dnssec;
dnssec,
nsid; /*% Name Server ID (RFC 5001) */
#ifdef DIG_SIGCHASE
isc_boolean_t sigchase;
#if DIG_SIGCHASE_TD
isc_boolean_t do_topdown,
trace_root_sigchase,
rdtype_sigchaseset,
rdclass_sigchaseset;
isc_boolean_t do_topdown,
trace_root_sigchase,
rdtype_sigchaseset,
rdclass_sigchaseset;
/* Name we are going to validate RRset */
char textnamesigchase[MXNAME];
char textnamesigchase[MXNAME];
#endif
#endif
char textname[MXNAME]; /*% Name we're going to be looking up */
char cmdline[MXNAME];
dns_rdatatype_t rdtype;
dns_rdatatype_t qrdtype;
#if DIG_SIGCHASE_TD
dns_rdatatype_t rdtype_sigchase;
dns_rdatatype_t qrdtype_sigchase;
dns_rdataclass_t rdclass_sigchase;
dns_rdatatype_t rdtype_sigchase;
dns_rdatatype_t qrdtype_sigchase;
dns_rdataclass_t rdclass_sigchase;
#endif
dns_rdataclass_t rdclass;
isc_boolean_t rdtypeset;
......@@ -231,7 +232,7 @@ struct dig_searchlist {
};
#ifdef DIG_SIGCHASE
struct dig_message {
dns_message_t *msg;
dns_message_t *msg;
ISC_LINK(dig_message_t) link;
};
#endif
......@@ -249,7 +250,7 @@ extern dig_searchlistlist_t search_list;
extern unsigned int extrabytes;
extern isc_boolean_t check_ra, have_ipv4, have_ipv6, specified_source,
usesearch, showsearch, qr;
usesearch, showsearch, qr;
extern in_port_t port;
extern unsigned int timeout;
extern isc_mem_t *mctx;
......
/*
* Generated by convertxsl.pl 1.10 2008/04/02 03:35:13 marka Exp
* Generated by convertxsl.pl 1.11 2008/04/02 23:46:57 tbox Exp
* From bind9.xsl 1.15 2008/04/01 23:47:10 tbox Exp
*/
static char msg[] =
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: client.c,v 1.254 2008/03/31 05:00:29 marka Exp $ */
/* $Id: client.c,v 1.255 2008/04/03 02:01:08 marka Exp $ */
#include <config.h>
......@@ -48,6 +48,7 @@
#include <named/interfacemgr.h>
#include <named/log.h>
#include <named/notify.h>
#include <named/os.h>
#include <named/server.h>
#include <named/update.h>
......@@ -954,11 +955,9 @@ ns_client_send(ns_client_t *client) {
result = dns_message_renderbegin(client->message, &cctx, &buffer);
if (result != ISC_R_SUCCESS)
goto done;
if (client->opt != NULL) {
result = dns_message_setopt(client->message, client->opt);
/*
* XXXRTH dns_message_setopt() should probably do this...
*/
client->opt = NULL;
if (result != ISC_R_SUCCESS)
goto done;
......@@ -1190,11 +1189,46 @@ client_addopt(ns_client_t *client) {
*/
rdatalist->ttl = (client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE);
/*
* No EDNS options in the default case.
*/
rdata->data = NULL;
rdata->length = 0;
/* Set EDNS options if applicable */
if (client->attributes & NS_CLIENTATTR_WANTNSID &&
(ns_g_server->server_id != NULL ||
ns_g_server->server_usehostname)) {
/*
* Space required for NSID data:
* 2 bytes for opt code
* + 2 bytes for NSID length
* + NSID itself
*/
char nsid[BUFSIZ];
isc_buffer_t *buffer = NULL;
if (ns_g_server->server_usehostname) {
isc_result_t result;
result = ns_os_gethostname(nsid, sizeof(nsid));
if (result != ISC_R_SUCCESS) {
goto no_nsid;
}
} else {
strncpy(nsid, ns_g_server->server_id, sizeof(nsid));
}
rdata->length = strlen(nsid) + 4;
result = isc_buffer_allocate(client->mctx, &buffer,
rdata->length);
if (result != ISC_R_SUCCESS)
goto no_nsid;
isc_buffer_putuint16(buffer, DNS_OPT_NSID);
isc_buffer_putuint16(buffer, strlen(nsid));
isc_buffer_putstr(buffer, nsid);
rdata->data = buffer->base;
dns_message_takebuffer(client->message, &buffer);
} else {
no_nsid:
rdata->data = NULL;
rdata->length = 0;
}
rdata->rdclass = rdatalist->rdclass;
rdata->type = rdatalist->type;
rdata->flags = 0;
......@@ -1302,6 +1336,8 @@ client_request(isc_task_t *task, isc_event_t *event) {
dns_messageid_t id;
unsigned int flags;
isc_boolean_t notimp;
dns_rdata_t rdata;
isc_uint16_t optcode;
REQUIRE(event != NULL);
client = event->ev_arg;
......@@ -1524,6 +1560,24 @@ client_request(isc_task_t *task, isc_event_t *event) {
ns_client_error(client, result);
goto cleanup;
}
/* Check for NSID request */
result = dns_rdataset_first(opt);
if (result == ISC_R_SUCCESS) {
dns_rdata_init(&rdata);
dns_rdataset_current(opt, &rdata);
if (rdata.length >= 2) {
isc_buffer_t nsidbuf;
isc_buffer_init(&nsidbuf,
rdata.data, rdata.length);
isc_buffer_add(&nsidbuf, rdata.length);
optcode = isc_buffer_getuint16(&nsidbuf);
if (optcode == DNS_OPT_NSID)
client->attributes |=
NS_CLIENTATTR_WANTNSID;
}
}
/*
* Create an OPT for our reply.
*/
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: config.c,v 1.85 2008/04/02 02:37:41 marka Exp $ */
/* $Id: config.c,v 1.86 2008/04/03 02:01:08 marka Exp $ */
/*! \file */
......@@ -99,6 +99,7 @@ options {\n\
use-ixfr true;\n\
edns-udp-size 4096;\n\
max-udp-size 4096;\n\
request-nsid false;\n\
\n\
/* view */\n\
allow-notify {none;};\n\
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: client.h,v 1.85 2008/01/18 23:46:57 tbox Exp $ */
/* $Id: client.h,v 1.86 2008/04/03 02:01:08 marka Exp $ */
#ifndef NAMED_CLIENT_H
#define NAMED_CLIENT_H 1
......@@ -166,6 +166,7 @@ struct ns_client {
#define NS_CLIENTATTR_PKTINFO 0x04 /*%< pktinfo is valid */
#define NS_CLIENTATTR_MULTICAST 0x08 /*%< recv'd from multicast */
#define NS_CLIENTATTR_WANTDNSSEC 0x10 /*%< include dnssec records */
#define NS_CLIENTATTR_WANTNSID 0x20 /*%< include nameserver ID */
extern unsigned int ns_client_requests;
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.503 2008/03/31 05:00:29 marka Exp $ */
/* $Id: server.c,v 1.504 2008/04/03 02:01:08 marka Exp $ */
/*! \file */
......@@ -729,6 +729,11 @@ configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
if (obj != NULL)
CHECK(dns_peer_setrequestixfr(peer, cfg_obj_asboolean(obj)));
obj = NULL;
(void)cfg_map_get(cpeer, "request-nsid", &obj);
if (obj != NULL)
CHECK(dns_peer_setrequestnsid(peer, cfg_obj_asboolean(obj)));
obj = NULL;
(void)cfg_map_get(cpeer, "edns", &obj);
if (obj != NULL)
......@@ -1656,6 +1661,11 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
INSIST(result == ISC_R_SUCCESS);
view->provideixfr = cfg_obj_asboolean(obj);
obj = NULL;
result = ns_config_get(maps, "request-nsid", &obj);
INSIST(result == ISC_R_SUCCESS);
view->requestnsid = cfg_obj_asboolean(obj);
obj = NULL;
result = ns_config_get(maps, "max-clients-per-query", &obj);
INSIST(result == ISC_R_SUCCESS);
......@@ -3465,8 +3475,12 @@ load_configuration(const char *filename, ns_server_t *server,
result = ns_config_get(maps, "server-id", &obj);
server->server_usehostname = ISC_FALSE;
if (result == ISC_R_SUCCESS && cfg_obj_isboolean(obj)) {
server->server_usehostname = ISC_TRUE;
/* The parser translates "hostname" to ISC_TRUE */
server->server_usehostname = cfg_obj_asboolean(obj);
result = setstring(server, &server->server_id, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
} else if (result == ISC_R_SUCCESS) {
/* Found a quoted string */
CHECKM(setoptstring(server, &server->server_id, obj), "strdup");
} else {
result = setstring(server, &server->server_id, NULL);
......
......@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- File: $Id: Bv9ARM-book.xml,v 1.348 2008/04/02 02:37:42 marka Exp $ -->
<!-- File: $Id: Bv9ARM-book.xml,v 1.349 2008/04/03 02:01:08 marka Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
......@@ -7533,9 +7533,10 @@ query-source-v6 address * port *;
<term><command>server-id</command></term>
<listitem>
<para>
The ID of the server should report via a query of
the name <filename>ID.SERVER</filename>
with type <command>TXT</command>, class <command>CHAOS</command>.
The ID the server should report when receiving a Name
Server Identifier (NSID) query, or a query of the name
<filename>ID.SERVER</filename> with type
<command>TXT</command>, class <command>CHAOS</command>.
The primary purpose of such queries is to
identify which of a group of anycast servers is actually
answering your queries. Specifying <command>server-id none;</command>
......
......@@ -49,7 +49,7 @@
*/
/*
* $Id: nameser.h,v 1.8 2005/04/27 04:56:16 sra Exp $
* $Id: nameser.h,v 1.9 2008/04/03 02:01:08 marka Exp $
*/
#ifndef _ARPA_NAMESER_H_
......@@ -427,9 +427,10 @@ typedef enum __ns_cert_types {
#define NS_NXT_MAX 127
/*%
* EDNS0 extended flags, host order.
* EDNS0 extended flags and option codes, host order.
*/
#define NS_OPT_DNSSEC_OK 0x8000U
#define NS_OPT_NSID 3
/*%
* Inline versions of get/put short/long. Pointer is advanced.
......
......@@ -50,7 +50,7 @@
/*%
* @(#)resolv.h 8.1 (Berkeley) 6/2/93
* $Id: resolv.h,v 1.23 2005/08/25 04:41:46 marka Exp $
* $Id: resolv.h,v 1.24 2008/04/03 02:01:08 marka Exp $
*/
#ifndef _RESOLV_H_
......@@ -250,6 +250,7 @@ union res_sockaddr_union {
#define RES_NOCHECKNAME 0x00008000 /*%< do not check names for sanity. */
#define RES_KEEPTSIG 0x00010000 /*%< do not strip TSIG records */
#define RES_BLAST 0x00020000 /*%< blast all recursive servers */
#define RES_NSID 0x00040000 /*%< request name server ID */
#define RES_NOTLDQUERY 0x00100000 /*%< don't unqualified name as a tld */
#define RES_USE_DNSSEC 0x00200000 /*%< use DNSSEC using OK bit in OPT */
/* #define RES_DEBUG2 0x00400000 */ /* nslookup internal */
......@@ -396,6 +397,7 @@ extern const struct res_sym __p_rcode_syms[];
#define sym_ntos __sym_ntos
#define sym_ston __sym_ston
#define res_nopt __res_nopt
#define res_nopt_rdata __res_nopt_rdata
#define res_ndestroy __res_ndestroy
#define res_nametoclass __res_nametoclass
#define res_nametotype __res_nametotype
......@@ -482,6 +484,8 @@ int res_findzonecut2 __P((res_state, const char *, ns_class, int,
union res_sockaddr_union *, int));
void res_nclose __P((res_state));
int res_nopt __P((res_state, int, u_char *, int, int));
int res_nopt_rdata __P((res_state, int, u_char *, int, u_char *,
u_short, u_short, u_char *));
void res_send_setqhook __P((res_send_qhook));
void res_send_setrhook __P((res_send_rhook));
int __res_vinit __P((res_state, int));
......
......@@ -95,7 +95,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
static const char rcsid[] = "$Id: res_debug.c,v 1.15 2005/07/28 06:51:50 marka Exp $";
static const char rcsid[] = "$Id: res_debug.c,v 1.16 2008/04/03 02:01:08 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
......@@ -189,10 +189,56 @@ do_section(const res_state statp,
p_type(ns_rr_type(rr)),
p_class(ns_rr_class(rr)));
else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) {
u_int16_t optcode, optlen, rdatalen = ns_rr_rdlen(rr);
u_int32_t ttl = ns_rr_ttl(rr);
fprintf(file,
"; EDNS: version: %u, udp=%u, flags=%04x\n",
(ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff);
while (rdatalen >= 4) {
const u_char *cp = ns_rr_rdata(rr);
int i;
GETSHORT(optcode, cp);
GETSHORT(optlen, cp);
if (optcode == NS_OPT_NSID) {
fputs("; NSID: ", file);
if (optlen == 0) {
fputs("; NSID\n", file);
} else {
fputs("; NSID: ", file);
for (i = 0; i < optlen; i++)
fprintf(file, "%02x ",
cp[i]);
fputs(" (",file);
for (i = 0; i < optlen; i++)
fprintf(file, "%c",
isprint(cp[i])?
cp[i] : '.');
fputs(")\n", file);
}
} else {
if (optlen == 0) {
fprintf(file, "; OPT=%u\n",
optcode);
} else {
fprintf(file, "; OPT=%u: ",
optcode);
for (i = 0; i < optlen; i++)
fprintf(file, "%02x ",
cp[i]);
fputs(" (",file);
for (i = 0; i < optlen; i++)
fprintf(file, "%c",
isprint(cp[i]) ?
cp[i] : '.');
fputs(")\n", file);
}
}
rdatalen -= 4 + optlen;
}
} else {
n = ns_sprintrr(handle, &rr, NULL, NULL,
buf, buflen);
......@@ -204,7 +250,7 @@ do_section(const res_state statp,
buf = malloc(buflen += 1024);
if (buf == NULL) {
fprintf(file,
";; memory allocation failure\n");
";; memory allocation failure\n");
return;
}
continue;
......@@ -381,7 +427,7 @@ const struct res_sym __p_default_section_syms[] = {
{ns_s_an, "ANSWER", (char *)0},
{ns_s_ns, "AUTHORITY", (char *)0},
{ns_s_ar, "ADDITIONAL", (char *)0},
{0, (char *)0, (char *)0}
{0, (char *)0, (char *)0}
};
const struct res_sym __p_update_section_syms[] = {
......@@ -389,7 +435,7 @@ const struct res_sym __p_update_section_syms[] = {
{S_PREREQ, "PREREQUISITE", (char *)0},
{S_UPDATE, "UPDATE", (char *)0},
{S_ADDT, "ADDITIONAL", (char *)0},
{0, (char *)0, (char *)0}
{0, (char *)0, (char *)0}
};
const struct res_sym __p_key_syms[] = {
......@@ -617,6 +663,7 @@ p_option(u_long option) {
case RES_USE_INET6: return "inet6";
#ifdef RES_USE_EDNS0 /*%< KAME extension */
case RES_USE_EDNS0: return "edns0";
case RES_NSID: return "nsid";
#endif
#ifdef RES_USE_DNAME
case RES_USE_DNAME: return "dname";
......
......@@ -70,7 +70,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
static const char rcsid[] = "$Id: res_mkquery.c,v 1.6 2005/04/27 04:56:42 sra Exp $";
static const char rcsid[] = "$Id: res_mkquery.c,v 1.7 2008/04/03 02:01:08 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
......@@ -203,9 +203,6 @@ res_nmkquery(res_state statp,
#ifdef RES_USE_EDNS0
/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
#ifndef T_OPT
#define T_OPT 41
#endif
int
res_nopt(res_state statp,
......@@ -230,13 +227,14 @@ res_nopt(res_state statp,
if ((ep - cp) < 1 + RRFIXEDSZ)
return (-1);
*cp++ = 0; /*%< "." */
ns_put16(T_OPT, cp); /*%< TYPE */
*cp++ = 0; /*%< "." */
ns_put16(ns_t_opt, cp); /*%< TYPE */
cp += INT16SZ;
ns_put16(anslen & 0xffff, cp); /*%< CLASS = UDP payload size */
ns_put16(anslen & 0xffff, cp); /*%< CLASS = UDP payload size */
cp += INT16SZ;
*cp++ = NOERROR; /*%< extended RCODE */
*cp++ = 0; /*%< EDNS version */
*cp++ = NOERROR; /*%< extended RCODE */
*cp++ = 0; /*%< EDNS version */
if (statp->options & RES_USE_DNSSEC) {
#ifdef DEBUG
if (statp->options & RES_DEBUG)
......@@ -246,12 +244,60 @@ res_nopt(res_state statp,
}
ns_put16(flags, cp);
cp += INT16SZ;
ns_put16(0, cp); /*%< RDLEN */
ns_put16(0U, cp); /*%< RDLEN */
cp += INT16SZ;
hp->arcount = htons(ntohs(hp->arcount) + 1);
return (cp - buf);
}
/*
* Construct variable data (RDATA) block for OPT psuedo-RR, append it