void
ns_lwdclient_processnoop(ns_lwdclient_t *client, lwres_buffer_t *b) {
	lwres_nooprequest_t *req;
	lwres_noopresponse_t resp;
	isc_result_t result;
	lwres_result_t lwres;
	isc_region_t r;
	lwres_buffer_t lwb;

	REQUIRE(NS_LWDCLIENT_ISRECVDONE(client));
	INSIST(client->byaddr == NULL);

	req = NULL;

	result = lwres_nooprequest_parse(client->clientmgr->lwctx,
					 b, &client->pkt, &req);
	if (result != LWRES_R_SUCCESS)
		goto send_error;

	client->pkt.recvlength = LWRES_RECVLENGTH;
	client->pkt.authtype = 0; /* XXXMLG */
	client->pkt.authlength = 0;
	client->pkt.result = LWRES_R_SUCCESS;

	resp.datalength = req->datalength;
	resp.data = req->data;

	lwres = lwres_noopresponse_render(client->clientmgr->lwctx, &resp,
					  &client->pkt, &lwb);
	if (lwres != LWRES_R_SUCCESS)
		goto cleanup_req;

	r.base = lwb.base;
	r.length = lwb.used;
	client->sendbuf = r.base;
	client->sendlength = r.length;
	result = ns_lwdclient_sendreply(client, &r);
	if (result != ISC_R_SUCCESS)
		goto cleanup_lwb;

	/*
	 * We can now destroy request.
	 */
	lwres_nooprequest_free(client->clientmgr->lwctx, &req);

	NS_LWDCLIENT_SETSEND(client);

	return;

 cleanup_lwb:
	lwres_context_freemem(client->clientmgr->lwctx, lwb.base, lwb.length);

 cleanup_req:
	lwres_nooprequest_free(client->clientmgr->lwctx, &req);

 send_error:
	ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE);
}
Ejemplo n.º 2
0
void
ns_lwdclient_processgnba(ns_lwdclient_t *client, lwres_buffer_t *b) {
    lwres_gnbarequest_t *req;
    isc_result_t result;
    isc_sockaddr_t sa;
    ns_lwdclientmgr_t *cm;

    REQUIRE(NS_LWDCLIENT_ISRECVDONE(client));
    INSIST(client->byaddr == NULL);

    cm = client->clientmgr;
    req = NULL;

    result = lwres_gnbarequest_parse(cm->lwctx,
                                     b, &client->pkt, &req);
    if (result != LWRES_R_SUCCESS)
        goto out;

    client->options = 0;
    if (req->addr.family == LWRES_ADDRTYPE_V4) {
        client->na.family = AF_INET;
        if (req->addr.length != 4)
            goto out;
        memcpy(&client->na.type.in, req->addr.address, 4);
    } else if (req->addr.family == LWRES_ADDRTYPE_V6) {
        client->na.family = AF_INET6;
        if (req->addr.length != 16)
            goto out;
        memcpy(&client->na.type.in6, req->addr.address, 16);
    } else {
        goto out;
    }
    isc_sockaddr_fromnetaddr(&sa, &client->na, 53);

    ns_lwdclient_log(50, "client %p looking for addrtype %08x",
                     client, req->addr.family);

    /*
     * We no longer need to keep this around.
     */
    lwres_gnbarequest_free(cm->lwctx, &req);

    /*
     * Initialize the real name and alias arrays in the reply we're
     * going to build up.
     */
    init_gnba(client);
    client->options = 0;

    /*
     * Start the find.
     */
    start_byaddr(client);

    return;

    /*
     * We're screwed.  Return an error packet to our caller.
     */
out:
    if (req != NULL)
        lwres_gnbarequest_free(cm->lwctx, &req);

    ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE);
}
Ejemplo n.º 3
0
void
ns_lwdclient_processgrbn(ns_lwdclient_t *client, lwres_buffer_t *b) {
	lwres_grbnrequest_t *req;
	isc_result_t result;
	ns_lwdclientmgr_t *cm;
	isc_buffer_t namebuf;

	REQUIRE(NS_LWDCLIENT_ISRECVDONE(client));
	INSIST(client->byaddr == NULL);

	cm = client->clientmgr;
	req = NULL;

	result = lwres_grbnrequest_parse(cm->lwctx,
					 b, &client->pkt, &req);
	if (result != LWRES_R_SUCCESS)
		goto out;
	if (req->name == NULL)
		goto out;

	client->options = 0;
	if (req->rdclass != cm->view->rdclass)
		goto out;

	if (req->rdclass == dns_rdataclass_any ||
	    req->rdtype == dns_rdatatype_any)
		goto out;

	client->rdtype = req->rdtype;

	isc_buffer_init(&namebuf, req->name, req->namelen);
	isc_buffer_add(&namebuf, req->namelen);

	dns_fixedname_init(&client->query_name);
	result = dns_name_fromtext(dns_fixedname_name(&client->query_name),
				   &namebuf, NULL, 0, NULL);
	if (result != ISC_R_SUCCESS)
		goto out;
	ns_lwsearchctx_init(&client->searchctx,
			    cm->listener->manager->search,
			    dns_fixedname_name(&client->query_name),
			    cm->listener->manager->ndots);
	ns_lwsearchctx_first(&client->searchctx);

	ns_lwdclient_log(50, "client %p looking for type %d",
			 client, client->rdtype);

	/*
	 * We no longer need to keep this around.
	 */
	lwres_grbnrequest_free(cm->lwctx, &req);

	/*
	 * Initialize the real name and alias arrays in the reply we're
	 * going to build up.
	 */
	init_grbn(client);

	/*
	 * Start the find.
	 */
	start_lookup(client);

	return;

	/*
	 * We're screwed.  Return an error packet to our caller.
	 */
 out:
	if (req != NULL)
		lwres_grbnrequest_free(cm->lwctx, &req);

	ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE);
}
Ejemplo n.º 4
0
/*
 * When we are called, we can be assured that:
 *
 *	client->sockaddr contains the address we need to reply to,
 *
 *	client->pkt contains the packet header data,
 *
 *	the packet "checks out" overall -- any MD5 hashes or crypto
 *	bits have been verified,
 *
 *	"b" points to the remaining data after the packet header
 *	was parsed off.
 *
 *	We are in a the RECVDONE state.
 *
 * From this state we will enter the SEND state if we happen to have
 * everything we need or we need to return an error packet, or to the
 * FINDWAIT state if we need to look things up.
 */
void
ns_lwdclient_processgabn(ns_lwdclient_t *client, lwres_buffer_t *b) {
	isc_result_t result;
	lwres_gabnrequest_t *req;
	ns_lwdclientmgr_t *cm;
	isc_buffer_t namebuf;

	REQUIRE(NS_LWDCLIENT_ISRECVDONE(client));

	cm = client->clientmgr;
	req = NULL;

	result = lwres_gabnrequest_parse(client->clientmgr->lwctx,
					 b, &client->pkt, &req);
	if (result != LWRES_R_SUCCESS)
		goto out;
	if (req->name == NULL)
		goto out;

	isc_buffer_init(&namebuf, req->name, req->namelen);
	isc_buffer_add(&namebuf, req->namelen);

	dns_fixedname_init(&client->target_name);
	dns_fixedname_init(&client->query_name);
	result = dns_name_fromtext(dns_fixedname_name(&client->query_name),
				   &namebuf, NULL, 0, NULL);
	if (result != ISC_R_SUCCESS)
		goto out;
	ns_lwsearchctx_init(&client->searchctx,
			    cm->listener->manager->search,
			    dns_fixedname_name(&client->query_name),
			    cm->listener->manager->ndots);
	ns_lwsearchctx_first(&client->searchctx);

	client->find_wanted = req->addrtypes;
	ns_lwdclient_log(50, "client %p looking for addrtypes %08x",
			 client, client->find_wanted);

	/*
	 * We no longer need to keep this around.
	 */
	lwres_gabnrequest_free(client->clientmgr->lwctx, &req);

	/*
	 * Start the find.
	 */
	result = start_find(client);
	if (result != ISC_R_SUCCESS)
		goto out;

	return;

	/*
	 * We're screwed.  Return an error packet to our caller.
	 */
 out:
	if (req != NULL)
		lwres_gabnrequest_free(client->clientmgr->lwctx, &req);

	ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE);
}