Compare commits
3 Commits
mnowak/mai
...
each-delv-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb78bbb27a | ||
|
|
19c4009055 | ||
|
|
d9cd97a9f1 |
145
bin/delv/delv.c
145
bin/delv/delv.c
@@ -84,6 +84,9 @@ static isc_log_t *lctx = NULL;
|
||||
/* Configurables */
|
||||
static char *server = NULL;
|
||||
static const char *port = "53";
|
||||
static isc_nm_t *netmgr = NULL;
|
||||
static isc_taskmgr_t *taskmgr = NULL;
|
||||
static isc_timermgr_t *timermgr = NULL;
|
||||
static isc_sockaddr_t *srcaddr4 = NULL, *srcaddr6 = NULL;
|
||||
static isc_sockaddr_t a4, a6;
|
||||
static char *curqname = NULL, *qname = NULL;
|
||||
@@ -1708,20 +1711,97 @@ get_reverse(char *reverse, size_t len, char *value, bool strict) {
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
setup_client(dns_client_t **clientp) {
|
||||
isc_result_t result;
|
||||
dns_client_t *client = NULL;
|
||||
|
||||
REQUIRE(clientp != NULL && *clientp == NULL);
|
||||
|
||||
/* Create client */
|
||||
result = dns_client_create(mctx, taskmgr, netmgr, timermgr, 0, &client,
|
||||
srcaddr4, srcaddr6);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
delv_log(ISC_LOG_ERROR, "dns_client_create: %s",
|
||||
isc_result_totext(result));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Set the nameserver */
|
||||
if (server != NULL) {
|
||||
addserver(client);
|
||||
} else {
|
||||
findserver(client);
|
||||
}
|
||||
|
||||
CHECK(setup_dnsseckeys(client));
|
||||
|
||||
*clientp = client;
|
||||
|
||||
cleanup:
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (client != NULL) {
|
||||
dns_client_detach(&client);
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
client_resolve(dns_client_t *client, const dns_name_t *query_name,
|
||||
dns_namelist_t *namelist)
|
||||
{
|
||||
isc_result_t result;
|
||||
unsigned int resopt;
|
||||
char namestr[DNS_NAME_FORMATSIZE];
|
||||
|
||||
/* Set up resolution options */
|
||||
resopt = DNS_CLIENTRESOPT_NOCDFLAG;
|
||||
if (no_sigs) {
|
||||
resopt |= DNS_CLIENTRESOPT_NODNSSEC;
|
||||
}
|
||||
if (!root_validation) {
|
||||
resopt |= DNS_CLIENTRESOPT_NOVALIDATE;
|
||||
}
|
||||
if (cdflag) {
|
||||
resopt &= ~DNS_CLIENTRESOPT_NOCDFLAG;
|
||||
}
|
||||
if (use_tcp) {
|
||||
resopt |= DNS_CLIENTRESOPT_TCP;
|
||||
}
|
||||
|
||||
/* Perform resolution */
|
||||
result = dns_client_resolve(client, query_name, dns_rdataclass_in,
|
||||
qtype, resopt, namelist);
|
||||
if (result != ISC_R_SUCCESS && !yaml) {
|
||||
delv_log(ISC_LOG_ERROR, "resolution failed: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
|
||||
if (yaml) {
|
||||
printf("type: DELV_RESULT\n");
|
||||
dns_name_format(query_name, namestr, sizeof(namestr));
|
||||
printf("query_name: %s\n", namestr);
|
||||
printf("status: %s\n", isc_result_totext(result));
|
||||
printf("records:\n");
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
dns_client_t *client = NULL;
|
||||
isc_result_t result;
|
||||
dns_fixedname_t qfn;
|
||||
dns_name_t *query_name, *response_name;
|
||||
char namestr[DNS_NAME_FORMATSIZE];
|
||||
dns_rdataset_t *rdataset;
|
||||
dns_namelist_t namelist;
|
||||
unsigned int resopt;
|
||||
isc_nm_t *netmgr = NULL;
|
||||
isc_taskmgr_t *taskmgr = NULL;
|
||||
isc_timermgr_t *timermgr = NULL;
|
||||
dns_master_style_t *style = NULL;
|
||||
struct sigaction sa;
|
||||
|
||||
ISC_LIST_INIT(namelist);
|
||||
|
||||
progname = argv[0];
|
||||
preparse_args(argc, argv);
|
||||
@@ -1744,58 +1824,21 @@ main(int argc, char *argv[]) {
|
||||
|
||||
setup_logging(stderr);
|
||||
|
||||
/* Create client */
|
||||
result = dns_client_create(mctx, taskmgr, netmgr, timermgr, 0, &client,
|
||||
srcaddr4, srcaddr6);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
delv_log(ISC_LOG_ERROR, "dns_client_create: %s",
|
||||
isc_result_totext(result));
|
||||
goto cleanup;
|
||||
/* Unblock SIGINT if it's been blocked by isc_app_ctxstart() */
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = SIG_DFL;
|
||||
if (sigfillset(&sa.sa_mask) != 0 || sigaction(SIGINT, &sa, NULL) < 0) {
|
||||
fatal("Couldn't set up signal handler");
|
||||
}
|
||||
|
||||
/* Set the nameserver */
|
||||
if (server != NULL) {
|
||||
addserver(client);
|
||||
} else {
|
||||
findserver(client);
|
||||
}
|
||||
|
||||
CHECK(setup_dnsseckeys(client));
|
||||
|
||||
/* Construct QNAME */
|
||||
CHECK(convert_name(&qfn, &query_name, qname));
|
||||
|
||||
/* Set up resolution options */
|
||||
resopt = DNS_CLIENTRESOPT_NOCDFLAG;
|
||||
if (no_sigs) {
|
||||
resopt |= DNS_CLIENTRESOPT_NODNSSEC;
|
||||
}
|
||||
if (!root_validation) {
|
||||
resopt |= DNS_CLIENTRESOPT_NOVALIDATE;
|
||||
}
|
||||
if (cdflag) {
|
||||
resopt &= ~DNS_CLIENTRESOPT_NOCDFLAG;
|
||||
}
|
||||
if (use_tcp) {
|
||||
resopt |= DNS_CLIENTRESOPT_TCP;
|
||||
}
|
||||
/* Set up DNS client */
|
||||
CHECK(setup_client(&client));
|
||||
|
||||
/* Perform resolution */
|
||||
ISC_LIST_INIT(namelist);
|
||||
result = dns_client_resolve(client, query_name, dns_rdataclass_in,
|
||||
qtype, resopt, &namelist);
|
||||
if (result != ISC_R_SUCCESS && !yaml) {
|
||||
delv_log(ISC_LOG_ERROR, "resolution failed: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
|
||||
if (yaml) {
|
||||
printf("type: DELV_RESULT\n");
|
||||
dns_name_format(query_name, namestr, sizeof(namestr));
|
||||
printf("query_name: %s\n", namestr);
|
||||
printf("status: %s\n", isc_result_totext(result));
|
||||
printf("records:\n");
|
||||
}
|
||||
/* Set up and perform DNS client resolution */
|
||||
CHECK(client_resolve(client, query_name, &namelist));
|
||||
|
||||
for (response_name = ISC_LIST_HEAD(namelist); response_name != NULL;
|
||||
response_name = ISC_LIST_NEXT(response_name, link))
|
||||
|
||||
@@ -499,9 +499,11 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||
* 'cb'.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_nm_dnspair(isc_nm_t *mgr, isc_nm_cb_t ccb, void *ccbarg,
|
||||
isc_nm_recv_cb_t scb, void *scbarg);
|
||||
/*%<
|
||||
* Returns 'true' iff 'handle' is associated with a socket of type
|
||||
* 'isc_nm_tlsdnssocket'.
|
||||
* FIXME
|
||||
*/
|
||||
|
||||
bool
|
||||
|
||||
@@ -295,6 +295,8 @@ typedef enum isc__netievent_type {
|
||||
netievent_tcpdnsread,
|
||||
netievent_tcpdnscancel,
|
||||
|
||||
netievent_dnspair,
|
||||
|
||||
netievent_tlsclose,
|
||||
netievent_tlssend,
|
||||
netievent_tlsstartread,
|
||||
@@ -1573,6 +1575,12 @@ isc__nm_async_tcpdnsread(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
* Callback handlers for asynchronous TCPDNS events.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__nm_async_dnspair(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
/*%<
|
||||
* Callback handlers for asynchronous DNS socket pair events.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__nm_tcpdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
|
||||
/*
|
||||
@@ -1956,6 +1964,8 @@ NETIEVENT_SOCKET_REQ_TYPE(tcpdnssend);
|
||||
NETIEVENT_SOCKET_HANDLE_TYPE(tcpdnscancel);
|
||||
NETIEVENT_SOCKET_QUOTA_TYPE(tcpdnsaccept);
|
||||
|
||||
NETIEVENT_SOCKET_REQ_TYPE(dnspair);
|
||||
|
||||
NETIEVENT_SOCKET_TYPE(tlsdnsclose);
|
||||
NETIEVENT_SOCKET_TYPE(tlsdnsread);
|
||||
NETIEVENT_SOCKET_TYPE(tlsdnsstop);
|
||||
@@ -2026,6 +2036,8 @@ NETIEVENT_SOCKET_REQ_DECL(tcpdnssend);
|
||||
NETIEVENT_SOCKET_HANDLE_DECL(tcpdnscancel);
|
||||
NETIEVENT_SOCKET_QUOTA_DECL(tcpdnsaccept);
|
||||
|
||||
NETIEVENT_SOCKET_REQ_DECL(dnspair);
|
||||
|
||||
NETIEVENT_SOCKET_DECL(tlsdnsclose);
|
||||
NETIEVENT_SOCKET_DECL(tlsdnsread);
|
||||
NETIEVENT_SOCKET_DECL(tlsdnsstop);
|
||||
|
||||
@@ -900,6 +900,8 @@ process_netievent(isc__networker_t *worker, isc__netievent_t *ievent) {
|
||||
NETIEVENT_CASE(tcpdnsread);
|
||||
NETIEVENT_CASE(tcpdnsstop);
|
||||
|
||||
NETIEVENT_CASE(dnspair);
|
||||
|
||||
NETIEVENT_CASE(tlsdnscycle);
|
||||
NETIEVENT_CASE(tlsdnsaccept);
|
||||
NETIEVENT_CASE(tlsdnslisten);
|
||||
@@ -1023,6 +1025,8 @@ NETIEVENT_SOCKET_REQ_DEF(tcpdnssend);
|
||||
NETIEVENT_SOCKET_HANDLE_DEF(tcpdnscancel);
|
||||
NETIEVENT_SOCKET_QUOTA_DEF(tcpdnsaccept);
|
||||
|
||||
NETIEVENT_SOCKET_REQ_DEF(dnspair);
|
||||
|
||||
NETIEVENT_SOCKET_DEF(tlsdnsclose);
|
||||
NETIEVENT_SOCKET_DEF(tlsdnsread);
|
||||
NETIEVENT_SOCKET_DEF(tlsdnsstop);
|
||||
|
||||
@@ -387,6 +387,7 @@ start_tcpdns_child(isc_nm_t *mgr, isc_sockaddr_t *iface, isc_nmsocket_t *sock,
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_nm_listentcpdns(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
|
||||
isc_nm_recv_cb_t recv_cb, void *recv_cbarg,
|
||||
@@ -701,7 +702,8 @@ isc__nm_tcpdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
* This MUST be done asynchronously, no matter which thread we're
|
||||
* in. The callback function for isc_nm_read() often calls
|
||||
* isc_nm_read() again; if we tried to do that synchronously
|
||||
* we'd clash in processbuffer() and grow the stack indefinitely.
|
||||
* we'd clash in isc__nm_tcpdns_processbuffer() and grow the
|
||||
* stack indefinitely.
|
||||
*/
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
@@ -1460,3 +1462,127 @@ isc__nm_async_tcpdnscancel(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF, false);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
pairdns_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
||||
isc_result_t result = ISC_R_UNSET;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
|
||||
REQUIRE(isc__nm_in_netthread());
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nm_closing(sock)) {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto error;
|
||||
}
|
||||
|
||||
atomic_store(&sock->connected, true);
|
||||
|
||||
error:
|
||||
LOCK(&sock->lock);
|
||||
sock->result = result;
|
||||
SIGNAL(&sock->cond);
|
||||
if (!atomic_load(&sock->active)) {
|
||||
WAIT(&sock->scond, &sock->lock);
|
||||
}
|
||||
INSIST(atomic_load(&sock->active));
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_async_dnspair(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc__netievent_dnspair_t *ievent =
|
||||
(isc__netievent_dnspair_t *)ev0;
|
||||
isc_nmsocket_t *sock = ievent->sock;
|
||||
isc__nm_uvreq_t *req = ievent->req;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
UNUSED(worker);
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->type == isc_nm_tcpdnssocket);
|
||||
REQUIRE(sock->parent == NULL);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
result = pairdns_direct(sock, req);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_connectcb(sock, req, result, true);
|
||||
atomic_store(&sock->active, false);
|
||||
isc__nm_tcpdns_close(sock);
|
||||
}
|
||||
|
||||
/*
|
||||
* The sock is now attached to the handle.
|
||||
*/
|
||||
isc__nmsocket_detach(&sock);
|
||||
}
|
||||
|
||||
void
|
||||
isc_nm_dnspair(isc_nm_t *mgr, isc_nm_cb_t ccb, void *ccbarg,
|
||||
isc_nm_recv_cb_t scb, void *scbarg) {
|
||||
uv_os_sock_t fds[2];
|
||||
isc_nmsocket_t *csock = NULL, *ssock = NULL;
|
||||
isc__netievent_tcpdnsconnect_t *cevent = NULL;
|
||||
isc__netievent_tcpdnslisten_t *sevent = NULL;
|
||||
isc__nm_uvreq_t *req = NULL;
|
||||
int r;
|
||||
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
|
||||
/* XXX: uv_socketpair() was introduced in libuv 1.40 */
|
||||
r = socketpair(PF_LOCAL, SOCK_STREAM, 0, fds);
|
||||
RUNTIME_CHECK(r == 0);
|
||||
|
||||
/* Set up server socket */
|
||||
ssock = isc_mem_get(mgr->mctx, sizeof(*ssock));
|
||||
isc__nmsocket_init(ssock, mgr, isc_nm_tcpdnssocket, NULL);
|
||||
ssock->recv_cb = scb;
|
||||
ssock->recv_cbarg = scbarg;
|
||||
ssock->fd = fds[1];
|
||||
|
||||
sevent = isc__nm_get_netievent_tcpdnslisten(mgr, ssock);
|
||||
|
||||
/* Set up client socket */
|
||||
csock = isc_mem_get(mgr->mctx, sizeof(*csock));
|
||||
isc__nmsocket_init(csock, mgr, isc_nm_tcpdnssocket, NULL);
|
||||
csock->result = ISC_R_UNSET;
|
||||
csock->fd = fds[0];
|
||||
atomic_init(&csock->client, true);
|
||||
|
||||
req = isc__nm_uvreq_get(mgr, csock);
|
||||
req->cb.connect = ccb;
|
||||
req->cbarg = ccbarg;
|
||||
req->handle = isc__nmhandle_get(csock, NULL, NULL);
|
||||
|
||||
cevent = isc__nm_get_netievent_dnspair(mgr, csock, req);
|
||||
|
||||
if (isc__nm_in_netthread()) {
|
||||
atomic_store(&csock->active, true);
|
||||
csock->tid = isc_nm_tid();
|
||||
isc__nm_async_dnspair(&mgr->workers[csock->tid],
|
||||
(isc__netievent_t *)cevent);
|
||||
isc__nm_put_netievent_dnspair(mgr, cevent);
|
||||
} else {
|
||||
atomic_init(&csock->active, false);
|
||||
csock->tid = isc_random_uniform(mgr->nworkers);
|
||||
isc__nm_enqueue_ievent(&mgr->workers[csock->tid],
|
||||
(isc__netievent_t *)cevent);
|
||||
}
|
||||
|
||||
ssock->tid = isc_random_uniform(mgr->nworkers);
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[ssock->tid],
|
||||
(isc__netievent_t *)sevent);
|
||||
|
||||
LOCK(&csock->lock);
|
||||
while (csock->result == ISC_R_UNSET) {
|
||||
WAIT(&csock->cond, &csock->lock);
|
||||
}
|
||||
atomic_store(&csock->active, true);
|
||||
BROADCAST(&csock->scond);
|
||||
UNLOCK(&csock->lock);
|
||||
}
|
||||
|
||||
@@ -898,8 +898,8 @@ isc__nm_tlsdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
* This MUST be done asynchronously, no matter which thread
|
||||
* we're in. The callback function for isc_nm_read() often calls
|
||||
* isc_nm_read() again; if we tried to do that synchronously
|
||||
* we'd clash in processbuffer() and grow the stack
|
||||
* indefinitely.
|
||||
* we'd clash in isc__nm_tlsdns_processbuffer() and grow the
|
||||
* stack indefinitely.
|
||||
*/
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
|
||||
@@ -1698,8 +1698,8 @@ ns__client_put_cb(void *client0) {
|
||||
* or tcpmsg (TCP case).
|
||||
*/
|
||||
void
|
||||
ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
||||
isc_region_t *region, void *arg) {
|
||||
ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
||||
isc_region_t *region, void *arg) {
|
||||
ns_client_t *client = NULL;
|
||||
isc_result_t result;
|
||||
isc_result_t sigresult = ISC_R_SUCCESS;
|
||||
|
||||
@@ -454,8 +454,8 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message,
|
||||
*/
|
||||
|
||||
void
|
||||
ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
||||
isc_region_t *region, void *arg);
|
||||
ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
||||
isc_region_t *region, void *arg);
|
||||
|
||||
/*%<
|
||||
* Handle client requests.
|
||||
|
||||
@@ -487,7 +487,7 @@ ns_interface_listenudp(ns_interface_t *ifp) {
|
||||
|
||||
/* Reserve space for an ns_client_t with the netmgr handle */
|
||||
result = isc_nm_listenudp(ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr,
|
||||
ns__client_request, ifp,
|
||||
ns_client_request, ifp,
|
||||
&ifp->udplistensocket);
|
||||
return (result);
|
||||
}
|
||||
@@ -497,7 +497,7 @@ ns_interface_listentcp(ns_interface_t *ifp) {
|
||||
isc_result_t result;
|
||||
|
||||
result = isc_nm_listentcpdns(
|
||||
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns__client_request,
|
||||
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request,
|
||||
ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog,
|
||||
&ifp->mgr->sctx->tcpquota, &ifp->tcplistensocket);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
@@ -537,7 +537,7 @@ ns_interface_listentls(ns_interface_t *ifp, isc_tlsctx_t *sslctx) {
|
||||
isc_result_t result;
|
||||
|
||||
result = isc_nm_listentlsdns(
|
||||
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns__client_request,
|
||||
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request,
|
||||
ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog,
|
||||
&ifp->mgr->sctx->tcpquota, sslctx, &ifp->tcplistensocket);
|
||||
|
||||
@@ -576,7 +576,7 @@ ns_interface_listenhttp(ns_interface_t *ifp, isc_tlsctx_t *sslctx, char **eps,
|
||||
|
||||
for (size_t i = 0; i < neps; i++) {
|
||||
result = isc_nm_http_endpoints_add(epset, eps[i],
|
||||
ns__client_request, ifp);
|
||||
ns_client_request, ifp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -793,7 +793,7 @@ ns_test_qctx_create(const ns_test_qctx_create_params_t *params,
|
||||
|
||||
/*
|
||||
* Allow recursion for the client. As NS_CLIENTATTR_RA normally gets
|
||||
* set in ns__client_request(), i.e. earlier than the unit tests hook
|
||||
* set in ns_client_request(), i.e. earlier than the unit tests hook
|
||||
* into the call chain, just set it manually.
|
||||
*/
|
||||
client->attributes |= NS_CLIENTATTR_RA;
|
||||
|
||||
Reference in New Issue
Block a user