getdns/src/sync.c

233 lines
6.6 KiB
C
Raw Normal View History

/**
*
* /brief getdns core functions for synchronous use
2013-10-17 18:45:25 -05:00
*
* Originally taken from the getdns API description pseudo implementation.
*
*/
/*
2014-02-25 07:12:33 -06:00
* Copyright (c) 2013, NLnet Labs, Verisign, Inc.
* All rights reserved.
2013-12-09 11:55:33 -06:00
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the names of the copyright holders nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
2013-10-17 18:45:25 -05:00
*
* 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 Verisign, Inc. 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 <string.h>
#include "getdns/getdns.h"
#include "config.h"
#include "context.h"
#include "general.h"
#include "types-internal.h"
#include "util-internal.h"
#include "dnssec.h"
#include "stub.h"
#include "gldns/wire2str.h"
typedef struct getdns_sync_data {
#ifdef HAVE_LIBUNBOUND
getdns_eventloop_event ub_event;
#endif
getdns_context *context;
int to_run;
getdns_dict *response;
} getdns_sync_data;
2013-08-16 15:28:21 -05:00
static getdns_return_t
getdns_sync_data_init(getdns_context *context, getdns_sync_data *data)
{
2016-03-24 08:02:18 -05:00
#ifdef HAVE_LIBUNBOUND
getdns_eventloop *ext = &context->sync_eventloop.loop;
2016-03-24 08:02:18 -05:00
#endif
data->context = context;
data->to_run = 1;
data->response = NULL;
#ifdef HAVE_LIBUNBOUND
# ifndef USE_WINSOCK
data->ub_event.userarg = data->context;
data->ub_event.read_cb = _getdns_context_ub_read_cb;
data->ub_event.write_cb = NULL;
data->ub_event.timeout_cb = NULL;
data->ub_event.ev = NULL;
# endif
# ifdef HAVE_UNBOUND_EVENT_API
if (_getdns_ub_loop_enabled(&context->ub_loop)) {
context->ub_loop.extension = ext;
} else
# endif
# ifndef USE_WINSOCK
return ext->vmt->schedule(ext, ub_fd(context->unbound_ctx),
TIMEOUT_FOREVER, &data->ub_event);
# else
/* No sync full recursion requests on windows without
* UNBOUND_EVENT_API because ub_fd() doesn't work on windows.
*/
; /* pass */
# endif
#endif
return GETDNS_RETURN_GOOD;
}
static void
getdns_sync_data_cleanup(getdns_sync_data *data)
{
#if defined(HAVE_LIBUNBOUND) && !defined(USE_WINSOCK)
# ifdef HAVE_UNBOUND_EVENT_API
if (_getdns_ub_loop_enabled(&data->context->ub_loop)) {
data->context->ub_loop.extension = data->context->extension;
} else
# endif
data->context->sync_eventloop.loop.vmt->clear(
&data->context->sync_eventloop.loop, &data->ub_event);
#endif
}
static void
getdns_sync_loop_run(getdns_sync_data *data)
{
while (data->to_run)
data->context->sync_eventloop.loop.vmt->run_once(
&data->context->sync_eventloop.loop, 1);
}
static void
getdns_sync_cb(getdns_context *context, getdns_callback_type_t callback_type,
getdns_dict *response, void *userarg, getdns_transaction_t transaction_id)
{
getdns_sync_data *data = (getdns_sync_data *)userarg;
assert(data);
data->response = response;
data->to_run = 0;
}
getdns_return_t
getdns_general_sync(getdns_context *context, const char *name,
uint16_t request_type, getdns_dict *extensions, getdns_dict **response)
2013-08-16 15:28:21 -05:00
{
getdns_sync_data data;
getdns_return_t r;
if (!context || !name || !response)
return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = getdns_sync_data_init(context, &data)))
return r;
if ((r = _getdns_general_loop(context, &context->sync_eventloop.loop,
name, request_type, extensions, &data, NULL, getdns_sync_cb, NULL))) {
getdns_sync_data_cleanup(&data);
return r;
}
getdns_sync_loop_run(&data);
getdns_sync_data_cleanup(&data);
return (*response = data.response) ?
GETDNS_RETURN_GOOD : GETDNS_RETURN_GENERIC_ERROR;
2013-08-16 15:28:21 -05:00
}
getdns_return_t
getdns_address_sync(getdns_context *context, const char *name,
getdns_dict *extensions, getdns_dict **response)
2013-08-16 15:28:21 -05:00
{
getdns_sync_data data;
getdns_return_t r;
if (!context || !name || !response)
return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = getdns_sync_data_init(context, &data)))
return r;
if ((r = _getdns_address_loop(context, &context->sync_eventloop.loop,
name, extensions, &data, NULL, getdns_sync_cb))) {
getdns_sync_data_cleanup(&data);
return r;
}
getdns_sync_loop_run(&data);
getdns_sync_data_cleanup(&data);
return (*response = data.response) ?
GETDNS_RETURN_GOOD : GETDNS_RETURN_GENERIC_ERROR;
2013-08-16 15:28:21 -05:00
}
getdns_return_t
getdns_hostname_sync(getdns_context *context, getdns_dict *address,
getdns_dict *extensions, getdns_dict **response)
{
getdns_sync_data data;
getdns_return_t r;
if (!context || !address || !response)
return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = getdns_sync_data_init(context, &data)))
return r;
if ((r = _getdns_hostname_loop(context, &context->sync_eventloop.loop,
address, extensions, &data, NULL, getdns_sync_cb))) {
getdns_sync_data_cleanup(&data);
return r;
}
getdns_sync_loop_run(&data);
getdns_sync_data_cleanup(&data);
return (*response = data.response) ?
GETDNS_RETURN_GOOD : GETDNS_RETURN_GENERIC_ERROR;
}
getdns_return_t
getdns_service_sync(getdns_context *context, const char *name,
getdns_dict *extensions, getdns_dict **response)
2013-08-16 15:28:21 -05:00
{
getdns_sync_data data;
getdns_return_t r;
2013-10-17 18:45:25 -05:00
if (!context || !name || !response)
return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = getdns_sync_data_init(context, &data)))
return r;
2013-08-16 15:28:21 -05:00
if ((r = _getdns_service_loop(context, &context->sync_eventloop.loop,
name, extensions, &data, NULL, getdns_sync_cb))) {
getdns_sync_data_cleanup(&data);
return r;
}
getdns_sync_loop_run(&data);
getdns_sync_data_cleanup(&data);
return (*response = data.response) ?
GETDNS_RETURN_GOOD : GETDNS_RETURN_GENERIC_ERROR;
2013-08-16 15:28:21 -05:00
}
/* getdns_core_sync.c */