dlz_lookup(const char *zone, const char *name, void *dbdata,
	   dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods,
	   dns_clientinfo_t *clientinfo)
{
	isc_result_t result;
	struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
	bool found = false;
	void *dbversion = NULL;
	isc_sockaddr_t *src;
	char full_name[256];
	char buf[512];
	static char last[256];
	static int count = 0;
	int i, size;

	UNUSED(zone);

	if (state->putrr == NULL) {
		return (ISC_R_NOTIMPLEMENTED);
	}

	if (strcmp(name, "@") == 0) {
		size = snprintf(full_name, sizeof(full_name),
				"%s", state->zone_name);
	} else if (strcmp(state->zone_name, ".") == 0) {
		size = snprintf(full_name, sizeof(full_name),
				"%s.", name);
	} else {
		size = snprintf(full_name, sizeof(full_name),
				"%s.%s", name, state->zone_name);
	}

	if (size < 0 ||
	    (size_t)size >= sizeof(full_name) ||
	    (size_t)size >= sizeof(last))
	{
		return (ISC_R_NOSPACE);
	}

	/*
	 * For test purposes, log all calls to dlz_lookup()
	 */
	if (strcasecmp(full_name, last) == 0) {
		count++;
	} else {
		count = 1;
		memcpy(last, full_name, size + 1);
	}
	state->log(ISC_LOG_INFO, "lookup #%d for %s", count, full_name);

	/*
	 * 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 &&
	    clientinfo->version >= DNS_CLIENTINFO_VERSION) {
		dbversion = clientinfo->dbversion;
		if (dbversion != NULL && *(bool *)dbversion)
			state->log(ISC_LOG_INFO,
				   "dlz_example: lookup against live "
				   "transaction");
	}

	if (strcmp(name, "source-addr") == 0) {
		strncpy(buf, "unknown", sizeof(buf));
		if (methods != NULL &&
		    methods->sourceip != NULL &&
		    (methods->version - methods->age <=
		     DNS_CLIENTINFOMETHODS_VERSION) &&
		    DNS_CLIENTINFOMETHODS_VERSION <= methods->version)
		{
			methods->sourceip(clientinfo, &src);
			fmt_address(src, buf, sizeof(buf));
		}

		state->log(ISC_LOG_INFO,
			   "dlz_example: lookup connection from %s", buf);

		found = true;
		result = state->putrr(lookup, "TXT", 0, buf);
		if (result != ISC_R_SUCCESS)
			return (result);
	}

	if (strcmp(name, "too-long") == 0 ||
	    strcmp(zone, "bigcname.domain") == 0)
	{
		for (i = 0; i < 511; i++)
			buf[i] = 'x';
		buf[i] = '\0';
		found = true;
		result = state->putrr(lookup, "TXT", 0, buf);
		if (result != ISC_R_SUCCESS)
			return (result);
	}

	/* Tests for DLZ redirection zones */
	if (strcmp(name, "*") == 0 && strcmp(zone, ".") == 0) {
		result = state->putrr(lookup, "A", 0, "100.100.100.2");
		found = true;
		if (result != ISC_R_SUCCESS)
			return (result);
	}

	if (strcmp(name, "long.name.is.not.there") == 0 &&
	    strcmp(zone, ".") == 0)
	{
		result = state->putrr(lookup, "A", 0, "100.100.100.3");
		found = true;
		if (result != ISC_R_SUCCESS)
			return (result);
	}

	/* Answer from current records */
	for (i = 0; i < MAX_RECORDS; i++) {
		if (strcasecmp(state->current[i].name, full_name) == 0) {
			found = true;
			result = state->putrr(lookup, state->current[i].type,
					      state->current[i].ttl,
					      state->current[i].data);
			if (result != ISC_R_SUCCESS)
				return (result);
		}
	}

	if (!found)
		return (ISC_R_NOTFOUND);

	return (ISC_R_SUCCESS);
}