Exemplo n.º 1
0
/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
lwres_result_t
lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req,
                          lwres_lwpacket_t *pkt, lwres_buffer_t *b)
{
    unsigned char *buf;
    size_t buflen;
    int ret;
    size_t payload_length;
    lwres_uint16_t datalen;
    int x;

    REQUIRE(ctx != NULL);
    REQUIRE(req != NULL);
    REQUIRE(pkt != NULL);
    REQUIRE(b != NULL);

    /* flags, class, type, ttl, nrdatas, nsigs */
    payload_length = 4 + 2 + 2 + 4 + 2 + 2;
    /* real name encoding */
    payload_length += 2 + req->realnamelen + 1;
    /* each rr */
    for (x = 0; x < req->nrdatas; x++)
        payload_length += 2 + req->rdatalen[x];
    for (x = 0; x < req->nsigs; x++)
        payload_length += 2 + req->siglen[x];

    buflen = LWRES_LWPACKET_LENGTH + payload_length;
    buf = CTXMALLOC(buflen);
    if (buf == NULL)
        return (LWRES_R_NOMEMORY);
    lwres_buffer_init(b, buf, buflen);

    pkt->length = buflen;
    pkt->version = LWRES_LWPACKETVERSION_0;
    pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
    pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
    pkt->authtype = 0;
    pkt->authlength = 0;

    ret = lwres_lwpacket_renderheader(b, pkt);
    if (ret != LWRES_R_SUCCESS) {
        lwres_buffer_invalidate(b);
        CTXFREE(buf, buflen);
        return (ret);
    }

    /*
     * Check space needed here.
     */
    INSIST(SPACE_OK(b, payload_length));

    /* Flags. */
    lwres_buffer_putuint32(b, req->flags);

    /* encode class, type, ttl, and nrdatas */
    lwres_buffer_putuint16(b, req->rdclass);
    lwres_buffer_putuint16(b, req->rdtype);
    lwres_buffer_putuint32(b, req->ttl);
    lwres_buffer_putuint16(b, req->nrdatas);
    lwres_buffer_putuint16(b, req->nsigs);

    /* encode the real name */
    datalen = req->realnamelen;
    lwres_buffer_putuint16(b, datalen);
    lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
    lwres_buffer_putuint8(b, 0);

    /* encode the rdatas */
    for (x = 0; x < req->nrdatas; x++) {
        datalen = req->rdatalen[x];
        lwres_buffer_putuint16(b, datalen);
        lwres_buffer_putmem(b, req->rdatas[x], datalen);
    }

    /* encode the signatures */
    for (x = 0; x < req->nsigs; x++) {
        datalen = req->siglen[x];
        lwres_buffer_putuint16(b, datalen);
        lwres_buffer_putmem(b, req->sigs[x], datalen);
    }

    INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
    INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length);

    return (LWRES_R_SUCCESS);
}
Exemplo n.º 2
0
/*% converts a getaddrbyname response structure lwres_gabnresponse_t to the lightweight resolver's canonical format. */
lwres_result_t
lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
			  lwres_lwpacket_t *pkt, lwres_buffer_t *b)
{
	unsigned char *buf;
	size_t buflen;
	int ret;
	size_t payload_length;
	lwres_uint16_t datalen;
	lwres_addr_t *addr;
	int x;

	REQUIRE(ctx != NULL);
	REQUIRE(req != NULL);
	REQUIRE(pkt != NULL);
	REQUIRE(b != NULL);

	/* naliases, naddrs */
	payload_length = 4 + 2 + 2;
	/* real name encoding */
	payload_length += 2 + req->realnamelen + 1;
	/* each alias */
	for (x = 0; x < req->naliases; x++)
		payload_length += 2 + req->aliaslen[x] + 1;
	/* each address */
	x = 0;
	addr = LWRES_LIST_HEAD(req->addrs);
	while (addr != NULL) {
		payload_length += 4 + 2;
		payload_length += addr->length;
		addr = LWRES_LIST_NEXT(addr, link);
		x++;
	}
	INSIST(x == req->naddrs);

	buflen = LWRES_LWPACKET_LENGTH + payload_length;
	buf = CTXMALLOC(buflen);
	if (buf == NULL)
		return (LWRES_R_NOMEMORY);
	lwres_buffer_init(b, buf, (unsigned int)buflen);

	pkt->length = (lwres_uint32_t)buflen;
	pkt->version = LWRES_LWPACKETVERSION_0;
	pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
	pkt->opcode = LWRES_OPCODE_GETADDRSBYNAME;
	pkt->authtype = 0;
	pkt->authlength = 0;

	ret = lwres_lwpacket_renderheader(b, pkt);
	if (ret != LWRES_R_SUCCESS) {
		lwres_buffer_invalidate(b);
		CTXFREE(buf, buflen);
		return (ret);
	}

	/*
	 * Check space needed here.
	 */
	INSIST(SPACE_OK(b, payload_length));

	/* Flags. */
	lwres_buffer_putuint32(b, req->flags);

	/* encode naliases and naddrs */
	lwres_buffer_putuint16(b, req->naliases);
	lwres_buffer_putuint16(b, req->naddrs);

	/* encode the real name */
	datalen = req->realnamelen;
	lwres_buffer_putuint16(b, datalen);
	lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
	lwres_buffer_putuint8(b, 0);

	/* encode the aliases */
	for (x = 0; x < req->naliases; x++) {
		datalen = req->aliaslen[x];
		lwres_buffer_putuint16(b, datalen);
		lwres_buffer_putmem(b, (unsigned char *)req->aliases[x],
				    datalen);
		lwres_buffer_putuint8(b, 0);
	}

	/* encode the addresses */
	addr = LWRES_LIST_HEAD(req->addrs);
	while (addr != NULL) {
		lwres_buffer_putuint32(b, addr->family);
		lwres_buffer_putuint16(b, addr->length);
		lwres_buffer_putmem(b, addr->address, addr->length);
		addr = LWRES_LIST_NEXT(addr, link);
	}

	INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
	INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length);

	return (LWRES_R_SUCCESS);
}