[master] merge dyndb

4224.	[func]		Added support for "dyndb", a new interface for loading
			zone data from an external database, developed by
			Red Hat for the FreeIPA project.

			DynDB drivers fully implement the BIND database
			API, and are capable of significantly better
			performance and functionality than DLZ drivers,
			while taking advantage of advanced database
			features not available in BIND such as multi-master
			replication.

			Thanks to Adam Tkac and Petr Spacek of Red Hat.
			[RT #35271]
This commit is contained in:
Evan Hunt
2015-09-28 23:12:35 -07:00
parent 4d085258cc
commit a00f9e2f50
56 changed files with 3270 additions and 109 deletions

View File

@@ -64,6 +64,7 @@
#include <stdio.h>
#include <isc/commandline.h>
#include <isc/mem.h>
#include <isc/msgs.h>
#include <isc/print.h>
#include <isc/string.h>
@@ -220,3 +221,62 @@ isc_commandline_parse(int argc, char * const *argv, const char *options) {
return (isc_commandline_option);
}
isc_result_t
isc_commandline_strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp,
char ***argvp, unsigned int n)
{
isc_result_t result;
restart:
/* Discard leading whitespace. */
while (*s == ' ' || *s == '\t')
s++;
if (*s == '\0') {
/* We have reached the end of the string. */
*argcp = n;
*argvp = isc_mem_get(mctx, n * sizeof(char *));
if (*argvp == NULL)
return (ISC_R_NOMEMORY);
} else {
char *p = s;
while (*p != ' ' && *p != '\t' && *p != '\0' && *p != '{') {
if (*p == '\n') {
*p = ' ';
goto restart;
}
p++;
}
/* do "grouping", items between { and } are one arg */
if (*p == '{') {
char *t = p;
/*
* shift all characters to left by 1 to get rid of '{'
*/
while (*t != '\0') {
t++;
*(t-1) = *t;
}
while (*p != '\0' && *p != '}') {
p++;
}
/* get rid of '}' character */
if (*p == '}') {
*p = '\0';
p++;
}
/* normal case, no "grouping" */
} else if (*p != '\0')
*p++ = '\0';
result = isc_commandline_strtoargv(mctx, p,
argcp, argvp, n + 1);
if (result != ISC_R_SUCCESS)
return (result);
(*argvp)[n] = s;
}
return (ISC_R_SUCCESS);
}

View File

@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: hash.c,v 1.16 2009/09/01 00:22:28 jinmei Exp $ */
/*! \file
* Some portion of this code was derived from universal hash function
* libraries of Rice University.
@@ -101,7 +99,8 @@ struct isc_hash {
static isc_mutex_t createlock;
static isc_once_t once = ISC_ONCE_INIT;
static isc_hash_t *hash = NULL;
LIBISC_EXTERNAL_DATA isc_hash_t *isc_hashctx = NULL;
static unsigned char maptolower[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@@ -220,14 +219,15 @@ isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit) {
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(mctx != NULL);
INSIST(hash == NULL);
INSIST(isc_hashctx == NULL);
RUNTIME_CHECK(isc_once_do(&once, initialize_lock) == ISC_R_SUCCESS);
LOCK(&createlock);
if (hash == NULL)
result = isc_hash_ctxcreate(mctx, entropy, limit, &hash);
if (isc_hashctx == NULL)
result = isc_hash_ctxcreate(mctx, entropy, limit,
&isc_hashctx);
UNLOCK(&createlock);
@@ -276,9 +276,9 @@ isc_hash_ctxinit(isc_hash_t *hctx) {
void
isc_hash_init(void) {
INSIST(hash != NULL && VALID_HASH(hash));
INSIST(isc_hashctx != NULL && VALID_HASH(isc_hashctx));
isc_hash_ctxinit(hash);
isc_hash_ctxinit(isc_hashctx);
}
void
@@ -337,12 +337,12 @@ void
isc_hash_destroy(void) {
unsigned int refs;
INSIST(hash != NULL && VALID_HASH(hash));
INSIST(isc_hashctx != NULL && VALID_HASH(isc_hashctx));
isc_refcount_decrement(&hash->refcnt, &refs);
isc_refcount_decrement(&isc_hashctx->refcnt, &refs);
INSIST(refs == 0);
destroy(&hash);
destroy(&isc_hashctx);
}
static inline unsigned int
@@ -384,10 +384,10 @@ unsigned int
isc_hash_calc(const unsigned char *key, unsigned int keylen,
isc_boolean_t case_sensitive)
{
INSIST(hash != NULL && VALID_HASH(hash));
REQUIRE(keylen <= hash->limit);
INSIST(isc_hashctx != NULL && VALID_HASH(isc_hashctx));
REQUIRE(keylen <= isc_hashctx->limit);
return (hash_calc(hash, key, keylen, case_sensitive));
return (hash_calc(isc_hashctx, key, keylen, case_sensitive));
}
void
@@ -395,10 +395,10 @@ isc__hash_setvec(const isc_uint16_t *vec) {
int i;
hash_random_t *p;
if (hash == NULL)
if (isc_hashctx == NULL)
return;
p = hash->rndvector;
p = isc_hashctx->rndvector;
for (i = 0; i < 256; i++) {
p[i] = vec[i];
}

View File

@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: commandline.h,v 1.16 2007/06/19 23:47:18 tbox Exp $ */
#ifndef ISC_COMMANDLINE_H
#define ISC_COMMANDLINE_H 1
@@ -25,6 +23,7 @@
#include <isc/boolean.h>
#include <isc/lang.h>
#include <isc/platform.h>
#include <isc/result.h>
/*% Index into parent argv vector. */
LIBISC_EXTERNAL_DATA extern int isc_commandline_index;
@@ -41,9 +40,22 @@ LIBISC_EXTERNAL_DATA extern isc_boolean_t isc_commandline_reset;
ISC_LANG_BEGINDECLS
/*% parse command line */
int
isc_commandline_parse(int argc, char * const *argv, const char *options);
/*%<
* Parse a command line (similar to getopt())
*/
isc_result_t
isc_commandline_strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp,
char ***argvp, unsigned int n);
/*%<
* Tokenize the string "s" into whitespace-separated words,
* returning the number of words in '*argcp' and an array
* of pointers to the words in '*argvp'. The caller
* must free the array using isc_mem_free(). The string
* is modified in-place.
*/
ISC_LANG_ENDDECLS

View File

@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: hash.h,v 1.12 2009/01/17 23:47:43 tbox Exp $ */
#ifndef ISC_HASH_H
#define ISC_HASH_H 1
@@ -83,6 +81,8 @@
***/
ISC_LANG_BEGINDECLS
LIBDNS_EXTERNAL_DATA extern isc_hash_t *isc_hashctx;
isc_result_t
isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit,
isc_hash_t **hctx);

View File

@@ -90,6 +90,7 @@ ISC_LANG_BEGINDECLS
#define ISC_LEXOPT_ESCAPE 0x100 /*%< Recognize escapes. */
#define ISC_LEXOPT_QSTRINGMULTILINE 0x200 /*%< Allow multiline "" strings */
#define ISC_LEXOPT_OCTAL 0x400 /*%< Expect a octal number. */
#define ISC_LEXOPT_BTEXT 0x800 /*%< Bracketed text. */
/*@}*/
/*@{*/
/*!
@@ -122,7 +123,8 @@ typedef enum {
isc_tokentype_eof = 5,
isc_tokentype_initialws = 6,
isc_tokentype_special = 7,
isc_tokentype_nomore = 8
isc_tokentype_nomore = 8,
isc_tokentype_btext = 8
} isc_tokentype_t;
typedef union {

View File

@@ -63,6 +63,7 @@ struct isc_lex {
unsigned int comments;
isc_boolean_t comment_ok;
isc_boolean_t last_was_eol;
unsigned int brace_count;
unsigned int paren_count;
unsigned int saved_paren_count;
isc_lexspecials_t specials;
@@ -111,6 +112,7 @@ isc_lex_create(isc_mem_t *mctx, size_t max_token, isc_lex_t **lexp) {
lex->comments = 0;
lex->comment_ok = ISC_TRUE;
lex->last_was_eol = ISC_TRUE;
lex->brace_count = 0;
lex->paren_count = 0;
lex->saved_paren_count = 0;
memset(lex->specials, 0, 256);
@@ -312,7 +314,8 @@ typedef enum {
lexstate_ccomment,
lexstate_ccommentend,
lexstate_eatline,
lexstate_qstring
lexstate_qstring,
lexstate_btext
} lexstate;
#define IWSEOL (ISC_LEXOPT_INITIALWS | ISC_LEXOPT_EOL)
@@ -395,10 +398,17 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
source->at_eof)
{
if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 &&
lex->paren_count != 0) {
lex->paren_count != 0)
{
lex->paren_count = 0;
return (ISC_R_UNBALANCED);
}
if ((options & ISC_LEXOPT_BTEXT) != 0 &&
lex->brace_count != 0)
{
lex->brace_count = 0;
return (ISC_R_UNBALANCED);
}
if ((options & ISC_LEXOPT_EOF) != 0) {
tokenp->type = isc_tokentype_eof;
return (ISC_R_SUCCESS);
@@ -513,6 +523,12 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
result = ISC_R_UNBALANCED;
goto done;
}
if ((options & ISC_LEXOPT_BTEXT) != 0 &&
lex->brace_count != 0) {
lex->brace_count = 0;
result = ISC_R_UNBALANCED;
goto done;
}
if ((options & ISC_LEXOPT_EOF) == 0) {
result = ISC_R_EOF;
goto done;
@@ -545,22 +561,35 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
} else if (lex->specials[c]) {
lex->last_was_eol = ISC_FALSE;
if ((c == '(' || c == ')') &&
(options & ISC_LEXOPT_DNSMULTILINE) != 0) {
(options & ISC_LEXOPT_DNSMULTILINE) != 0)
{
if (c == '(') {
if (lex->paren_count == 0)
options &= ~IWSEOL;
lex->paren_count++;
} else {
if (lex->paren_count == 0) {
result = ISC_R_UNBALANCED;
goto done;
result =
ISC_R_UNBALANCED;
goto done;
}
lex->paren_count--;
if (lex->paren_count == 0)
options =
saved_options;
options = saved_options;
}
continue;
} else if (c == '{' &&
(options & ISC_LEXOPT_BTEXT) != 0)
{
if (lex->brace_count != 0) {
result = ISC_R_UNBALANCED;
goto done;
}
lex->brace_count++;
options &= ~IWSEOL;
state = lexstate_btext;
no_comments = ISC_TRUE;
continue;
}
tokenp->type = isc_tokentype_special;
tokenp->value.as_char = c;
@@ -778,6 +807,57 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
remaining--;
}
break;
case lexstate_btext:
if (c == EOF) {
result = ISC_R_UNEXPECTEDEND;
goto done;
}
if (c == '{') {
if (escaped) {
escaped = ISC_FALSE;
INSIST(prev != NULL);
*prev = '{';
} else {
lex->brace_count++;
}
} else if (c == '}') {
if (escaped) {
escaped = ISC_FALSE;
INSIST(prev != NULL);
*prev = '}';
break;
}
INSIST(lex->brace_count > 0);
lex->brace_count--;
if (lex->brace_count > 0)
break;
tokenp->type = isc_tokentype_btext;
tokenp->value.as_textregion.base = lex->data;
tokenp->value.as_textregion.length =
(unsigned int) (lex->max_token -
remaining);
no_comments = ISC_FALSE;
done = ISC_TRUE;
} else {
if (c == '\\' && !escaped)
escaped = ISC_TRUE;
else
escaped = ISC_FALSE;
if (remaining == 0U) {
result = grow_data(lex, &remaining,
&curr, &prev);
if (result != ISC_R_SUCCESS)
goto done;
}
INSIST(remaining > 0U);
prev = curr;
*curr++ = c;
*curr = '\0';
remaining--;
}
break;
default:
FATAL_ERROR(__FILE__, __LINE__,
isc_msgcat_get(isc_msgcat, ISC_MSGSET_LEX,

View File

@@ -168,6 +168,7 @@ isc_buffer_reserve
isc_bufferlist_availablecount
isc_bufferlist_usedcount
isc_commandline_parse
isc_commandline_strtoargv
isc_condition_broadcast
isc_condition_destroy
isc_condition_init
@@ -261,6 +262,7 @@ isc_hash_ctxdetach
isc_hash_ctxinit
isc_hash_destroy
isc_hash_init
isc_hashctx
isc_heap_create
isc_heap_decreased
isc_heap_delete