void libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s, char* why_bogus) { struct ctx_query* q = (struct ctx_query*)arg; /* fg query is done; exit comm base */ comm_base_exit(q->w->base); libworker_fillup_fg(q, rcode, buf, s, why_bogus); }
int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) { struct libworker* w = libworker_setup(ctx, 0); uint16_t qflags, qid; struct query_info qinfo; struct edns_data edns; if(!w) return UB_INITFAIL; if(!setup_qinfo_edns(w, q, &qinfo, &edns)) { libworker_delete(w); return UB_SYNTAX; } qid = 0; qflags = BIT_RD; q->w = w; /* see if there is a fixed answer */ ldns_buffer_write_u16_at(w->back->udp_buff, 0, qid); ldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags); if(local_zones_answer(ctx->local_zones, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) { regional_free_all(w->env->scratch); libworker_fillup_fg(q, LDNS_RCODE_NOERROR, w->back->udp_buff, sec_status_insecure, NULL); libworker_delete(w); free(qinfo.qname); return UB_NOERROR; } /* process new query */ if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns, w->back->udp_buff, qid, libworker_fg_done_cb, q)) { free(qinfo.qname); return UB_NOMEM; } free(qinfo.qname); /* wait for reply */ comm_base_dispatch(w->base); libworker_delete(w); return UB_NOERROR; }