int BinaryFileReader::read_bit() {
	if (buffer_capacity() == 0)
		fill_buffer();
	int bit = bit_at(buffer[get_iword()], get_ibit());
	++pointer;
	return bit;
}
Esempio n. 2
0
/**
 * Prepare response.
 *
 */
void
query_prepare(query_type* q)
{
    uint16_t limit = 0;
    uint16_t flags = 0;
    ods_log_assert(q);
    ods_log_assert(q->buffer);
    limit = buffer_limit(q->buffer);
    flags = buffer_pkt_flags(q->buffer);
    flags &= 0x0100U; /* preserve the rd flag */
    flags |= 0x8000U; /* set the qr flag */
    buffer_pkt_set_flags(q->buffer, flags);
    buffer_clear(q->buffer);
    buffer_set_position(q->buffer, limit);
    buffer_set_limit(q->buffer, buffer_capacity(q->buffer));
    q->reserved_space = edns_rr_reserved_space(q->edns_rr);
    q->reserved_space += tsig_rr_reserved_space(q->tsig_rr);
    return;
}
Esempio n. 3
0
size_t string_capacity(string *s)
{
  return buffer_capacity(&s->buffer) - 1;
}
Esempio n. 4
0
/**
 * NOTIFY.
 *
 */
static query_state
query_process_notify(query_type* q, ldns_rr_type qtype, void* engine)
{
    engine_type* e = (engine_type*) engine;
    dnsin_type* dnsin = NULL;
    uint16_t count = 0;
    uint16_t rrcount = 0;
    uint32_t serial = 0;
    size_t pos = 0;
    char address[128];
    if (!e || !q || !q->zone) {
        return QUERY_DISCARDED;
    }
    ods_log_assert(e->dnshandler);
    ods_log_assert(q->zone->name);
    ods_log_debug("[%s] incoming notify for zone %s", query_str,
        q->zone->name);
    if (buffer_pkt_rcode(q->buffer) != LDNS_RCODE_NOERROR ||
        buffer_pkt_qr(q->buffer) ||
        !buffer_pkt_aa(q->buffer) ||
        buffer_pkt_tc(q->buffer) ||
        buffer_pkt_rd(q->buffer) ||
        buffer_pkt_ra(q->buffer) ||
        buffer_pkt_ad(q->buffer) ||
        buffer_pkt_cd(q->buffer) ||
        buffer_pkt_qdcount(q->buffer) != 1 ||
        buffer_pkt_ancount(q->buffer) > 1 ||
        qtype != LDNS_RR_TYPE_SOA) {
        return query_formerr(q);
    }
    if (!q->zone->adinbound || q->zone->adinbound->type != ADAPTER_DNS) {
        ods_log_error("[%s] zone %s is not configured to have input dns "
            "adapter", query_str, q->zone->name);
        return query_notauth(q);
    }
    ods_log_assert(q->zone->adinbound->config);
    dnsin = (dnsin_type*) q->zone->adinbound->config;
    if (!acl_find(dnsin->allow_notify, &q->addr, q->tsig_rr)) {
        if (addr2ip(q->addr, address, sizeof(address))) {
            ods_log_info("[%s] unauthorized notify for zone %s from client %s: "
                "no acl matches", query_str, q->zone->name, address);
        } else {
            ods_log_info("[%s] unauthorized notify for zone %s from unknown "
                "client: no acl matches", query_str, q->zone->name);
        }
        return query_notauth(q);
    }
    ods_log_assert(q->zone->xfrd);
    /* skip header and question section */
    buffer_skip(q->buffer, BUFFER_PKT_HEADER_SIZE);
    count = buffer_pkt_qdcount(q->buffer);
    for (rrcount = 0; rrcount < count; rrcount++) {
        if (!buffer_skip_rr(q->buffer, 1)) {
            ods_log_error("[%s] dropped packet: zone %s received bad notify "
                "(bad question section)", query_str, q->zone->name);
            return QUERY_DISCARDED;
        }
    }
    pos = buffer_position(q->buffer);

    /* examine answer section */
    count = buffer_pkt_ancount(q->buffer);
    if (count) {
        if (!buffer_skip_dname(q->buffer) ||
            !query_parse_soa(q->buffer, &serial)) {
            ods_log_error("[%s] dropped packet: zone %s received bad notify "
                "(bad soa in answer section)", query_str, q->zone->name);
            return QUERY_DISCARDED;
        }
        lock_basic_lock(&q->zone->xfrd->serial_lock);
        q->zone->xfrd->serial_notify = serial;
        q->zone->xfrd->serial_notify_acquired = time_now();
        if (!util_serial_gt(q->zone->xfrd->serial_notify,
            q->zone->xfrd->serial_disk)) {
            ods_log_debug("[%s] ignore notify: already got zone %s serial "
                "%u on disk", query_str, q->zone->name,
                q->zone->xfrd->serial_notify);
            lock_basic_unlock(&q->zone->xfrd->serial_lock);
            goto send_notify_ok;
        }
        lock_basic_unlock(&q->zone->xfrd->serial_lock);
    } else {
        lock_basic_lock(&q->zone->xfrd->serial_lock);
        q->zone->xfrd->serial_notify = 0;
        q->zone->xfrd->serial_notify_acquired = 0;
        lock_basic_unlock(&q->zone->xfrd->serial_lock);
    }
    /* forward notify to xfrd */
    xfrd_set_timer_now(q->zone->xfrd);
    dnshandler_fwd_notify(e->dnshandler, buffer_begin(q->buffer),
        buffer_remaining(q->buffer));

send_notify_ok:
    /* send notify ok */
    buffer_pkt_set_qr(q->buffer);
    buffer_pkt_set_aa(q->buffer);
    buffer_pkt_set_ancount(q->buffer, 0);

    buffer_clear(q->buffer); /* lim = pos, pos = 0; */
    buffer_set_position(q->buffer, pos);
    buffer_set_limit(q->buffer, buffer_capacity(q->buffer));
    q->reserved_space = edns_rr_reserved_space(q->edns_rr);
    q->reserved_space += tsig_rr_reserved_space(q->tsig_rr);
    return QUERY_PROCESSED;
}