/*
* Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* This provides a very simple example of an external loadable DLZ
* driver, with update support.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <dns/dlz_dlopen.h>
#include "driver.h"
#ifdef WIN32
#elif defined(_REENTRANT)
#else
#endif
#define CHECK(x) \
do { \
result = (x); \
if (result != ISC_R_SUCCESS) \
goto failure; \
} while (0)
/* For this simple example, use fixed sized strings */
struct record {
};
struct dlz_example_data {
char *zone_name;
/* An example driver doesn't need good memory management :-) */
/* Helper functions from the dlz_dlopen driver */
};
static isc_boolean_t
int i;
for (i = 0; single[i]; i++) {
return (ISC_TRUE);
}
}
return (ISC_FALSE);
}
/*
* Add a record to a list
*/
static isc_result_t
{
int i;
for (i = 0; i < MAX_RECORDS; i++) {
first_empty = i;
}
continue;
continue;
continue;
break;
}
i = first_empty;
}
if (i == MAX_RECORDS) {
"dlz_example: out of record space");
return (ISC_R_FAILURE);
}
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
}
/*
* Delete a record from a list
*/
static isc_result_t
const char *data)
{
int i;
for (i = 0; i < MAX_RECORDS; i++) {
break;
}
}
if (i == MAX_RECORDS) {
return (ISC_R_NOTFOUND);
}
return (ISC_R_SUCCESS);
}
static isc_result_t
const char *ret;
case AF_INET:
sizeof(addr_buf));
break;
case AF_INET6:
sizeof(addr_buf));
break;
default:
return (ISC_R_FAILURE);
}
return (ISC_R_FAILURE);
return (ISC_R_SUCCESS);
}
/*
* Return the version of the API
*/
int
return (DLZ_DLOPEN_VERSION);
}
/*
* Remember a helper function from the bind9 dlz_dlopen driver
*/
static void
const char *helper_name, void *ptr)
{
}
/*
* Called to initialize the driver
*/
void **dbdata, ...)
{
const char *helper_name;
const char *extra;
int n;
return (ISC_R_NOMEMORY);
/* Fill in the helper functions */
}
"dlz_example: please specify a zone name");
return (ISC_R_FAILURE);
}
/* Ensure zone name is absolute */
return (ISC_R_NOMEMORY);
}
else
extra = ".root";
else
extra = ".";
if (n < 0)
if ((unsigned)n >= sizeof(soa_data))
"a", 1800, "10.53.0.1");
return (ISC_R_SUCCESS);
return (result);
}
/*
* Shut down the backend
*/
void
"dlz_example: shutting down zone %s",
}
/*
* See if we handle a given zone
*/
{
{
}
"dlz_example: dlz_findzonedb called with name '%s' "
"in zone DB '%s' from %s",
/*
* Returning ISC_R_NOTFOUND will cause the query logic to
* check the database for parent names, looking for zone cuts.
*
* Returning ISC_R_NOMORE prevents the query logic from doing
* this; it will move onto the next database after a single query.
*/
return (ISC_R_NOMORE);
/*
* For example.net, only return ISC_R_NOMORE when queried
* from 10.53.0.1.
*/
return (ISC_R_NOMORE);
/*
* For bigcname.domain, return success so it appears to be
* the zone origin; this regression tests a bug in which
* zone origin nodes could fail to return SERVFAIL to the client.
*/
return (ISC_R_SUCCESS);
/*
* Return success if we have an exact match between the
* zone name and the qname
*/
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
return (ISC_R_NOTFOUND);
}
/*
* Look up one record in the sample database.
*
* If the queryname is "source-addr", send back a TXT record containing
* the address of the client, to test the use of 'methods' and 'clientinfo'
*
* If the queryname is "too-long", send back a TXT record that's too long
* to process; this should result in a SERVFAIL when queried.
*/
{
static int count = 0;
int i;
return (ISC_R_NOTIMPLEMENTED);
else
/*
* For test purposes, log all calls to dlz_lookup()
*/
count++;
else {
count = 1;
}
/*
* If we need to know the database version (as set in
* the 'newversion' dlz function) we can pick it up from the
* clientinfo.
*
* This allows a lookup to query the correct version of the DNS
* data, if the DLZ can differentiate between versions.
*
* For example, if a new database transaction is created by
* 'newversion', the lookup should query within the same
* transaction scope if it can.
*
* If the DLZ only operates on 'live' data, then version
* wouldn't necessarily be needed.
*/
if (clientinfo != NULL &&
"dlz_example: lookup against live "
"transaction");
}
{
}
"dlz_example: lookup connection from %s", buf);
if (result != ISC_R_SUCCESS)
return (result);
}
{
for (i = 0; i < 511; i++)
buf[i] = 'x';
buf[i] = '\0';
if (result != ISC_R_SUCCESS)
return (result);
}
/* Tests for DLZ redirection zones */
if (result != ISC_R_SUCCESS)
return (result);
}
{
if (result != ISC_R_SUCCESS)
return (result);
}
/* Answer from current records */
for (i = 0; i < MAX_RECORDS; i++) {
if (result != ISC_R_SUCCESS)
return (result);
}
}
if (!found)
return (ISC_R_NOTFOUND);
return (ISC_R_SUCCESS);
}
/*
* See if a zone transfer is allowed
*/
/* Just say yes for all our zones */
}
/*
* Perform a zone transfer
*/
int i;
return (ISC_R_NOTIMPLEMENTED);
for (i = 0; i < MAX_RECORDS; i++) {
continue;
}
if (result != ISC_R_SUCCESS)
return (result);
}
return (ISC_R_SUCCESS);
}
/*
* Start a transaction
*/
if (state->transaction_started) {
"dlz_example: transaction already "
"started for zone %s", zone);
return (ISC_R_FAILURE);
}
return (ISC_R_SUCCESS);
}
/*
* End a transaction
*/
void
{
if (!state->transaction_started) {
"started for zone %s", zone);
return;
}
if (commit) {
int i;
"transaction on zone %s", zone);
for (i = 0; i < MAX_RECORDS; i++) {
}
}
for (i = 0; i < MAX_RECORDS; i++) {
}
}
} else {
"transaction on zone %s", zone);
}
}
/*
* Configure a writeable zone
*/
"writeable_zone method available");
return (ISC_R_FAILURE);
}
if (result != ISC_R_SUCCESS) {
return (result);
}
return (ISC_R_SUCCESS);
}
/*
* Authorize a zone update
*/
{
return (ISC_FALSE);
}
return (ISC_TRUE);
}
static isc_result_t
{
#if defined(WIN32) || defined(_REENTRANT)
#endif
return (ISC_R_FAILURE);
/*
* The format is:
* FULLNAME\tTTL\tDCLASS\tTYPE\tDATA
*
* The DATA field is space separated, and is in the data format
* for the type used by dig
*/
goto error;
goto error;
goto error;
goto error;
goto error;
}
return (result);
return (ISC_R_FAILURE);
}
{
return (ISC_R_FAILURE);
}
{
return (ISC_R_FAILURE);
}
{
return (ISC_R_FAILURE);
return (ISC_R_SUCCESS);
}