mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-03 05:19:34 -05:00
version.server and consorts support.
git-svn-id: file:///svn/unbound/trunk@438 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
a96e895bc9
commit
5e48023c6c
8 changed files with 173 additions and 3 deletions
|
|
@ -57,6 +57,7 @@
|
|||
#include "services/mesh.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgencode.h"
|
||||
#include "util/data/dname.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
|
|
@ -260,6 +261,94 @@ answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill CH class answer into buffer. Keeps query.
|
||||
* @param pkt: buffer
|
||||
* @param str: string to put into text record (<255).
|
||||
* @param edns: edns reply information.
|
||||
*/
|
||||
static void
|
||||
chaos_replystr(ldns_buffer* pkt, const char* str, struct edns_data* edns)
|
||||
{
|
||||
int len = strlen(str);
|
||||
int rd = LDNS_RD_WIRE(ldns_buffer_begin(pkt));
|
||||
int cd = LDNS_CD_WIRE(ldns_buffer_begin(pkt));
|
||||
if(len>255) len=255; /* cap size of TXT record */
|
||||
ldns_buffer_clear(pkt);
|
||||
ldns_buffer_skip(pkt, sizeof(uint16_t)); /* skip id */
|
||||
ldns_buffer_write_u16(pkt, BIT_QR|BIT_RA); /* noerror, no flags */
|
||||
if(rd) LDNS_RD_SET(ldns_buffer_begin(pkt));
|
||||
if(cd) LDNS_CD_SET(ldns_buffer_begin(pkt));
|
||||
ldns_buffer_write_u16(pkt, 1); /* qdcount */
|
||||
ldns_buffer_write_u16(pkt, 1); /* ancount */
|
||||
ldns_buffer_write_u16(pkt, 0); /* nscount */
|
||||
ldns_buffer_write_u16(pkt, 0); /* arcount */
|
||||
(void)query_dname_len(pkt); /* skip qname */
|
||||
ldns_buffer_skip(pkt, sizeof(uint16_t)); /* skip qtype */
|
||||
ldns_buffer_skip(pkt, sizeof(uint16_t)); /* skip qclass */
|
||||
ldns_buffer_write_u16(pkt, 0xc00c); /* compr ptr to query */
|
||||
ldns_buffer_write_u16(pkt, LDNS_RR_TYPE_TXT);
|
||||
ldns_buffer_write_u16(pkt, LDNS_RR_CLASS_CH);
|
||||
ldns_buffer_write_u32(pkt, 0); /* TTL */
|
||||
ldns_buffer_write_u16(pkt, sizeof(uint8_t) + len);
|
||||
ldns_buffer_write_u8(pkt, len);
|
||||
ldns_buffer_write(pkt, str, len);
|
||||
ldns_buffer_flip(pkt);
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->bits &= EDNS_DO;
|
||||
attach_edns_record(pkt, edns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer CH class queries.
|
||||
* @param w: worker
|
||||
* @param qinfo: query info. Pointer into packet buffer.
|
||||
* @param edns: edns info from query.
|
||||
* @param pkt: packet buffer.
|
||||
* @return: true if a reply is to be sent.
|
||||
*/
|
||||
static int
|
||||
answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
struct edns_data* edns, ldns_buffer* pkt)
|
||||
{
|
||||
struct config_file* cfg = w->env.cfg;
|
||||
if(qinfo->qtype != LDNS_RR_TYPE_ANY && qinfo->qtype != LDNS_RR_TYPE_TXT)
|
||||
return 0;
|
||||
if(query_dname_compare(qinfo->qname,
|
||||
(uint8_t*)"\002id\006server") == 0 ||
|
||||
query_dname_compare(qinfo->qname,
|
||||
(uint8_t*)"\010hostname\004bind") == 0)
|
||||
{
|
||||
if(cfg->hide_identity)
|
||||
return 0;
|
||||
if(cfg->identity==NULL || cfg->identity[0]==0) {
|
||||
char buf[MAXHOSTNAMELEN];
|
||||
if (gethostname(buf, MAXHOSTNAMELEN) == 0)
|
||||
chaos_replystr(pkt, buf, edns);
|
||||
else {
|
||||
log_err("gethostname: %s", strerror(errno));
|
||||
chaos_replystr(pkt, "no hostname", edns);
|
||||
}
|
||||
}
|
||||
else chaos_replystr(pkt, cfg->identity, edns);
|
||||
return 1;
|
||||
}
|
||||
if(query_dname_compare(qinfo->qname,
|
||||
(uint8_t*)"\007version\006server") == 0 ||
|
||||
query_dname_compare(qinfo->qname,
|
||||
(uint8_t*)"\007version\004bind") == 0)
|
||||
{
|
||||
if(cfg->hide_version)
|
||||
return 0;
|
||||
if(cfg->version==NULL || cfg->version[0]==0)
|
||||
chaos_replystr(pkt, PACKAGE_STRING, edns);
|
||||
else chaos_replystr(pkt, cfg->version, edns);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** handles callbacks from listening event interface */
|
||||
static int
|
||||
worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
|
|
@ -303,7 +392,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||
LDNS_RCODE_REFUSED);
|
||||
return 1;
|
||||
}
|
||||
h = query_info_hash(&qinfo);
|
||||
if((ret=parse_edns_from_pkt(c->buffer, &edns)) != 0) {
|
||||
verbose(VERB_ALGO, "worker parse edns: formerror.");
|
||||
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
|
||||
|
|
@ -340,6 +428,12 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||
}
|
||||
if(c->type != comm_udp)
|
||||
edns.udp_size = 65535; /* max size for TCP replies */
|
||||
if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
|
||||
&edns, c->buffer)) {
|
||||
verbose(VERB_ALGO, "class CH reply");
|
||||
return 1;
|
||||
}
|
||||
h = query_info_hash(&qinfo);
|
||||
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
|
||||
/* answer from cache - we have acquired a readlock on it */
|
||||
if(answer_from_cache(worker, e,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
- shuffle NS selection when getting nameserver target addresses.
|
||||
- fixup of deadlock warnings, yield cpu in checklock code so that
|
||||
freebsd scheduler selects correct process to run.
|
||||
- added identity and version config options and replies.
|
||||
|
||||
18 July 2007: Wouter
|
||||
- do not query addresses, 127.0.0.1, and ::1 by default.
|
||||
|
|
|
|||
|
|
@ -111,6 +111,18 @@ server:
|
|||
# the pid file.
|
||||
# pidfile: "unbound.pid"
|
||||
|
||||
# enable to not answer id.server and hostname.bind queries.
|
||||
# hide-identity: no
|
||||
|
||||
# enable to not answer version.server and version.bind queries.
|
||||
# hide-version: no
|
||||
|
||||
# the identity to report. Leave "" or default to return hostname.
|
||||
# identity: ""
|
||||
|
||||
# the version to report. Leave "" or default to return package version.
|
||||
# version: ""
|
||||
|
||||
# the target fetch policy.
|
||||
# series of integers describing the policy per dependency depth.
|
||||
# The number of values in the list determines the maximum dependency
|
||||
|
|
|
|||
|
|
@ -117,6 +117,16 @@ The logfile is appended to, in the following format:
|
|||
The process id is written to the file. Default is "unbound.pid". So,
|
||||
kill -HUP `cat /etc/unbound/unbound.pid` will trigger a reload,
|
||||
kill -QUIT `cat /etc/unbound/unbound.pid` will gracefully terminate.
|
||||
.It \fBhide-identity:\fR <yes or no>
|
||||
If enabled id.server and hostname.bind queries are refused.
|
||||
.It \fBidentity:\fR <string>
|
||||
Set the identity to report. If set to "", the default, then the hostname
|
||||
of the server is returned.
|
||||
.It \fBhide-version:\fR <yes or no>
|
||||
If enabled version.server and version.bind queries are refused.
|
||||
.It \fBversion:\fR <string>
|
||||
Set the version to report. If set to "", the default, then the package
|
||||
version is returned.
|
||||
.It \fBtarget-fetch-policy:\fR <"list of numbers">
|
||||
Set the target fetch policy used by unbound to determine if it should fetch
|
||||
nameserver target addresses opportunistically. The policy is described per
|
||||
|
|
|
|||
|
|
@ -106,6 +106,10 @@ config_create()
|
|||
cfg->forwards = NULL;
|
||||
cfg->harden_short_bufsize = 0;
|
||||
cfg->harden_large_queries = 0;
|
||||
cfg->hide_identity = 0;
|
||||
cfg->hide_version = 0;
|
||||
cfg->identity = NULL;
|
||||
cfg->version = NULL;
|
||||
return cfg;
|
||||
error_exit:
|
||||
config_delete(cfg);
|
||||
|
|
@ -196,6 +200,8 @@ config_delete(struct config_file* cfg)
|
|||
config_delstubs(cfg->stubs);
|
||||
config_delstubs(cfg->forwards);
|
||||
config_delstrlist(cfg->donotqueryaddrs);
|
||||
free(cfg->identity);
|
||||
free(cfg->version);
|
||||
free(cfg);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,15 @@ struct config_file {
|
|||
char* logfile;
|
||||
/** pidfile to write pid to. */
|
||||
char* pidfile;
|
||||
|
||||
/** do not report identity (id.server, hostname.bind) */
|
||||
int hide_identity;
|
||||
/** do not report version (version.server, version.bind) */
|
||||
int hide_version;
|
||||
/** identity, hostname is returned if "". */
|
||||
char* identity;
|
||||
/** version, package version returned if "". */
|
||||
char* version;
|
||||
|
||||
/** daemonize, i.e. fork into the background. */
|
||||
int do_daemonize;
|
||||
|
|
|
|||
|
|
@ -136,6 +136,10 @@ forward-zone{COLON} { YDOUT; return VAR_FORWARD_ZONE;}
|
|||
forward-addr{COLON} { YDOUT; return VAR_FORWARD_ADDR;}
|
||||
forward-host{COLON} { YDOUT; return VAR_FORWARD_HOST;}
|
||||
do-not-query-address{COLON} { YDOUT; return VAR_DO_NOT_QUERY_ADDRESS;}
|
||||
hide-identity{COLON} { YDOUT; return VAR_HIDE_IDENTITY;}
|
||||
hide-version{COLON} { YDOUT; return VAR_HIDE_VERSION;}
|
||||
identity{COLON} { YDOUT; return VAR_IDENTITY;}
|
||||
version{COLON} { YDOUT; return VAR_VERSION;}
|
||||
{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;}
|
||||
|
||||
/* Quoted strings. Strip leading and ending quotes */
|
||||
|
|
|
|||
|
|
@ -78,7 +78,8 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_STUB_ZONE VAR_STUB_HOST VAR_STUB_ADDR VAR_TARGET_FETCH_POLICY
|
||||
%token VAR_HARDEN_SHORT_BUFSIZE VAR_HARDEN_LARGE_QUERIES
|
||||
%token VAR_FORWARD_ZONE VAR_FORWARD_HOST VAR_FORWARD_ADDR
|
||||
%token VAR_DO_NOT_QUERY_ADDRESS
|
||||
%token VAR_DO_NOT_QUERY_ADDRESS VAR_HIDE_IDENTITY VAR_HIDE_VERSION
|
||||
%token VAR_IDENTITY VAR_VERSION
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
|
|
@ -109,7 +110,8 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||
server_infra_cache_slabs | server_infra_cache_numhosts |
|
||||
server_infra_cache_numlame | server_target_fetch_policy |
|
||||
server_harden_short_bufsize | server_harden_large_queries |
|
||||
server_do_not_query_address
|
||||
server_do_not_query_address | server_hide_identity |
|
||||
server_hide_version | server_identity | server_version
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
{
|
||||
|
|
@ -281,6 +283,38 @@ server_pidfile: VAR_PIDFILE STRING
|
|||
cfg_parser->cfg->pidfile = $2;
|
||||
}
|
||||
;
|
||||
server_hide_identity: VAR_HIDE_IDENTITY STRING
|
||||
{
|
||||
OUTYY(("P(server_hide_identity:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->hide_identity = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_hide_version: VAR_HIDE_VERSION STRING
|
||||
{
|
||||
OUTYY(("P(server_hide_version:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->hide_version = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_identity: VAR_IDENTITY STRING
|
||||
{
|
||||
OUTYY(("P(server_identity:%s)\n", $2));
|
||||
free(cfg_parser->cfg->identity);
|
||||
cfg_parser->cfg->identity = $2;
|
||||
}
|
||||
;
|
||||
server_version: VAR_VERSION STRING
|
||||
{
|
||||
OUTYY(("P(server_version:%s)\n", $2));
|
||||
free(cfg_parser->cfg->version);
|
||||
cfg_parser->cfg->version = $2;
|
||||
}
|
||||
;
|
||||
server_msg_cache_size: VAR_MSG_CACHE_SIZE STRING
|
||||
{
|
||||
OUTYY(("P(server_msg_cache_size:%s)\n", $2));
|
||||
|
|
|
|||
Loading…
Reference in a new issue