local_zone answers.
- fixup uninit warning from random.c; also seems to fix sporadic
sigFPE coming out of openssl.
+ - made openssl entropy warning more silent for library use. Needs
+ verbosity 1 now.
+ - fixup forgotten locks for rbtree_searches on ctx->query tree.
25 January 2008: Wouter
- added tpkg for asynclook and library use.
log_assert( ldns_read_uint32(p) == UB_LIBCMD_ANSWER);
id = (int)ldns_read_uint32(p+sizeof(uint32_t));
q = (struct ctx_query*)rbtree_search(&ctx->queries, &id);
- if(!q) return NULL;
+ if(!q) return NULL;
*err = (int)ldns_read_uint32(p+2*sizeof(uint32_t));
q->msg_security = ldns_read_uint32(p+3*sizeof(uint32_t));
if(len > 4*sizeof(uint32_t)) {
return UB_NOERROR;
}
log_assert(q->async);
- msg = context_serialize_cancel(q, &len);
- if(!msg) {
- lock_basic_unlock(&ctx->cfglock);
- return UB_NOMEM;
- }
q->cancelled = 1;
/* delete it */
(void)rbtree_delete(&ctx->queries, q->node.key);
ctx->num_async--;
context_query_delete(q);
- }
- lock_basic_unlock(&ctx->cfglock);
-
- /* send cancel to background worker */
- lock_basic_lock(&ctx->qqpipe_lock);
- if(!libworker_write_msg(ctx->qqpipe[1], msg, len, 0)) {
+ msg = context_serialize_cancel(q, &len);
+ lock_basic_unlock(&ctx->cfglock);
+ if(!msg) {
+ return UB_NOMEM;
+ }
+ /* send cancel to background worker */
+ lock_basic_lock(&ctx->qqpipe_lock);
+ if(!libworker_write_msg(ctx->qqpipe[1], msg, len, 0)) {
+ lock_basic_unlock(&ctx->qqpipe_lock);
+ free(msg);
+ return UB_PIPE;
+ }
lock_basic_unlock(&ctx->qqpipe_lock);
free(msg);
- return UB_PIPE;
+ } else {
+ lock_basic_unlock(&ctx->cfglock);
}
- lock_basic_unlock(&ctx->qqpipe_lock);
- free(msg);
return UB_NOERROR;
}
(((unsigned int)w->thread_num)<<17);
seed ^= (unsigned int)w->env->alloc->next_id;
if(!w->is_bg || w->is_bg_thread) {
- /* Openssl RAND_... functions are not as threadsafe
- * as documented, put a lock around them. */
+ /* put lock around RAND*() */
lock_basic_lock(&ctx->cfglock);
}
if(!ub_initstate(seed, w->env->rnd, RND_STATE_SIZE)) {
static void
handle_cancel(struct libworker* w, uint8_t* buf, uint32_t len)
{
- struct ctx_query* q = context_deserialize_cancel(w->ctx, buf, len);
+ struct ctx_query* q;
+ if(w->is_bg_thread) {
+ lock_basic_lock(&w->ctx->cfglock);
+ q = context_deserialize_cancel(w->ctx, buf, len);
+ lock_basic_unlock(&w->ctx->cfglock);
+ } else {
+ q = context_deserialize_cancel(w->ctx, buf, len);
+ }
if(!q) {
/* probably simply lookup failed, i.e. the message had been
* processed and answered before the cancel arrived */
struct edns_data edns;
struct ctx_query* q;
if(w->is_bg_thread) {
+ lock_basic_lock(&w->ctx->cfglock);
q = context_lookup_new_query(w->ctx, buf, len);
+ lock_basic_unlock(&w->ctx->cfglock);
} else {
q = context_deserialize_new_query(w->ctx, buf, len);
}
int numq;
};
+/** check result structure for the 'correct' answer */
+static void
+ext_check_result(const char* desc, int err, struct ub_val_result* result)
+{
+ checkerr(desc, err);
+ if(result == NULL) {
+ printf("%s: error result is NULL.\n", desc);
+ exit(1);
+ }
+ /* DEBUG */
+ if(strcmp(result->qname, "localhost") != 0) {
+ printf("%s: error result has wrong qname.\n", desc);
+ exit(1);
+ }
+ if(result->qtype != LDNS_RR_TYPE_A) {
+ printf("%s: error result has wrong qtype.\n", desc);
+ exit(1);
+ }
+ if(result->qclass != LDNS_RR_CLASS_IN) {
+ printf("%s: error result has wrong qclass.\n", desc);
+ exit(1);
+ }
+ if(result->data == NULL) {
+ printf("%s: error result->data is NULL.\n", desc);
+ exit(1);
+ }
+ if(result->len == NULL) {
+ printf("%s: error result->len is NULL.\n", desc);
+ exit(1);
+ }
+ if(result->rcode != 0) {
+ printf("%s: error result->rcode is set.\n", desc);
+ exit(1);
+ }
+ if(result->havedata == 0) {
+ printf("%s: error result->havedata is unset.\n", desc);
+ exit(1);
+ }
+ if(result->nxdomain != 0) {
+ printf("%s: error result->nxdomain is set.\n", desc);
+ exit(1);
+ }
+ if(result->secure || result->bogus) {
+ printf("%s: error result->secure or bogus is set.\n", desc);
+ exit(1);
+ }
+ if(result->data[0] == NULL) {
+ printf("%s: error result->data[0] is NULL.\n", desc);
+ exit(1);
+ }
+ if(result->len[0] != 4) {
+ printf("%s: error result->len[0] is wrong.\n", desc);
+ exit(1);
+ }
+ if(result->len[1] != 0 || result->data[1] != NULL) {
+ printf("%s: error result->data[1] or len[1] is wrong.\n", desc);
+ exit(1);
+ }
+}
+
/** extended bg result callback, this function is ub_val_callback_t */
static void
ext_callback(void* mydata, int err, struct ub_val_result* result)
/* I have an id, make sure we are not cancelled */
if(*my_id == 0) {
printf("error: query returned, but was cancelled\n");
+ abort();
exit(1);
}
if(doprint)
printf("cb %d: ", *my_id);
}
- checkerr("ext_callback", err);
+ ext_check_result("ext_callback", err, result);
log_assert(result);
if(doprint) {
struct lookinfo pi;
/* blocking */
r = ub_val_resolve(inf->ctx, inf->argv[i%inf->argc],
LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, &result);
- checkerr("ub_val_resolve", r);
+ ext_check_result("ub_val_resolve", r, result);
}
}
if(inf->thread_num > NUMTHR/2) {
memmove(buf+i*sizeof(seed), &v, sizeof(seed));
v = v*seed + (unsigned int)i;
}
+ log_hex("seed with", buf, 256);
RAND_seed(buf, 256);
if(!RAND_status()) {
log_err("Random generator has no entropy (error %ld)",
ERR_get_error());
return 0;
}
- log_warn("openssl has no entropy, seeding with time");
+ verbose(VERB_OPS, "openssl has no entropy, seeding with time");
}
ub_arc4random_stir(state->s);
return 1;