[BACK]Return to client.c CVS log [TXT][DIR] Up to [local] / acopm / lib / dnsbl

File: [local] / acopm / lib / dnsbl / client.c (download)

Revision 1.1, Sat May 8 15:42:18 2021 UTC (3 years ago) by bountyht
Branch point for: MAIN

Initial revision

/*
 * Copyright (C) 2017 Aaron M. D. Jones <aaronmdjones@gmail.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following
 * conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "acopm-common.h"

#include <assert.h> /* assert() */
#include <errno.h> /* errno */
#include <string.h> /* strerror() */

#include <event2/dns.h> /* evdns_*() */
#include <event2/event.h> /* struct event_base */

#include "3rdparty/utlist.h" /* DL_FOREACH_SAFE() */
#include "dnsbl/client.h" /* decls for own functions */
#include "dnsbl/lookup.h" /* ACOPM_DNSBL_LOOKUP_* */
#include "dnsbl/internal.h" /* internal decls */
#include "utils/log.h" /* acopm_log_*() */

struct acopm_dnsbl_client *
acopm_dnsbl_new(struct event_base *const restrict ev_base)
{
	assert(ev_base != NULL);

	struct acopm_dnsbl_client *const client = calloc(1, sizeof *client);

	if (! client)
	{
		(void) acopm_log_error("%s: calloc: %s", __func__, strerror(errno));
		return NULL;
	}

	if (! (client->ev_base = evdns_base_new(ev_base, 0)))
	{
		(void) acopm_log_error("%s: evdns_base_new: %s", __func__, strerror(errno));
		(void) acopm_dnsbl_free(client);
		return NULL;
	}

	(void) acopm_log_debug("%s: created client", __func__);
	return client;
}

bool
acopm_dnsbl_set_timeout(struct acopm_dnsbl_client *const restrict client, const unsigned int lookup_timeout)
{
	assert(client != NULL);
	assert(client->ev_base != NULL);
	assert((lookup_timeout >= ACOPM_DNSBL_LOOKUP_TIMEOUT_MIN) && (lookup_timeout <= ACOPM_DNSBL_LOOKUP_TIMEOUT_MAX));

	char timeout_str[32];
	(void) snprintf(timeout_str, sizeof timeout_str, "%u", lookup_timeout);

	if (evdns_base_set_option(client->ev_base, "timeout:", timeout_str) == -1)
	{
		(void) acopm_log_warning("%s: unable to set lookup timeout", __func__);
		return false;
	}

	(void) acopm_log_debug("%s: lookup timeout set to %u", __func__, lookup_timeout);
	return true;
}

bool
acopm_dnsbl_add_nameserver(struct acopm_dnsbl_client *const restrict client, const char *const restrict nameserver)
{
	assert(client != NULL);
	assert(nameserver != NULL);
	assert(*nameserver != 0x00);

	(void) acopm_log_debug("%s: adding nameserver %s", __func__, nameserver);

	if (evdns_base_nameserver_ip_add(client->ev_base, nameserver) != 0)
	{
		(void) acopm_log_error("%s: nameserver_ip_add: %s", __func__, strerror(errno));
		return false;
	}

	client->ready = true;
	return true;
}

void
acopm_dnsbl_free(struct acopm_dnsbl_client *const restrict client)
{
	assert(client != NULL);

	(void) acopm_log_debug("%s: freeing client", __func__);

	if (client->lookups)
	{
		struct acopm_dnsbl_lookup *lookup, *tmp;
		DL_FOREACH_SAFE(client->lookups, lookup, tmp)
		{
			if (! client->lookups)
				break;

			(void) acopm_dnsbl_lookup_free(lookup);
		}
	}
	if (client->domains)
	{
		struct acopm_dnsbl_domain *domain, *tmp;
		DL_FOREACH_SAFE(client->domains, domain, tmp)
		{
			if (! client->domains)
				break;

			(void) acopm_dnsbl_domain_free(domain);
		}
	}

	if (client->ev_base)
		(void) evdns_base_free(client->ev_base, 0);

	(void) free(client);
}