예제 #1
0
/** fillup fg results */
static void
libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf, 
	enum sec_status s, char* why_bogus)
{
	if(why_bogus)
		q->res->why_bogus = strdup(why_bogus);
	if(rcode != 0) {
		q->res->rcode = rcode;
		q->msg_security = s;
		return;
	}

	q->res->rcode = LDNS_RCODE_SERVFAIL;
	q->msg_security = 0;
	q->msg = memdup(sldns_buffer_begin(buf), sldns_buffer_limit(buf));
	q->msg_len = sldns_buffer_limit(buf);
	if(!q->msg) {
		return; /* the error is in the rcode */
	}

	/* canonname and results */
	q->msg_security = s;
	libworker_enter_result(q->res, buf, q->w->env->scratch, s);
}
예제 #2
0
/** process answer from bg worker */
static int
process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len,
                      ub_callback_t* cb, void** cbarg, int* err,
                      struct ub_result** res)
{
    struct ctx_query* q;
    if(context_serial_getcmd(msg, len) != UB_LIBCMD_ANSWER) {
        log_err("error: bad data from bg worker %d",
                (int)context_serial_getcmd(msg, len));
        return 0;
    }

    lock_basic_lock(&ctx->cfglock);
    q = context_deserialize_answer(ctx, msg, len, err);
    if(!q) {
        lock_basic_unlock(&ctx->cfglock);
        /* probably simply the lookup that failed, i.e.
         * response returned before cancel was sent out, so noerror */
        return 1;
    }
    log_assert(q->async);

    /* grab cb while locked */
    if(q->cancelled) {
        *cb = NULL;
        *cbarg = NULL;
    } else {
        *cb = q->cb;
        *cbarg = q->cb_arg;
    }
    if(*err) {
        *res = NULL;
        ub_resolve_free(q->res);
    } else {
        /* parse the message, extract rcode, fill result */
        ldns_buffer* buf = ldns_buffer_new(q->msg_len);
        struct regional* region = regional_create();
        *res = q->res;
        (*res)->rcode = LDNS_RCODE_SERVFAIL;
        if(region && buf) {
            ldns_buffer_clear(buf);
            ldns_buffer_write(buf, q->msg, q->msg_len);
            ldns_buffer_flip(buf);
            libworker_enter_result(*res, buf, region,
                                   q->msg_security);
        }
        (*res)->answer_packet = q->msg;
        (*res)->answer_len = (int)q->msg_len;
        q->msg = NULL;
        ldns_buffer_free(buf);
        regional_destroy(region);
    }
    q->res = NULL;
    /* delete the q from list */
    (void)rbtree_delete(&ctx->queries, q->node.key);
    ctx->num_async--;
    context_query_delete(q);
    lock_basic_unlock(&ctx->cfglock);

    if(*cb) return 2;
    ub_resolve_free(*res);
    return 1;
}