From: Wouter Wijngaards Date: Mon, 28 Jan 2008 13:42:55 +0000 (+0000) Subject: more locks. X-Git-Tag: release-0.9~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5196b25ae73200c0da8fee372bd7129934c5457;p=thirdparty%2Funbound.git more locks. git-svn-id: file:///svn/unbound/trunk@906 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index faa2f2b03..9bc255a30 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -3,6 +3,9 @@ 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. diff --git a/libunbound/context.c b/libunbound/context.c index 26a03c8ed..39eb236b3 100644 --- a/libunbound/context.c +++ b/libunbound/context.c @@ -313,7 +313,7 @@ context_deserialize_answer(struct ub_val_ctx* ctx, 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)) { diff --git a/libunbound/unbound.c b/libunbound/unbound.c index 81c8e46a2..3f7e0b189 100644 --- a/libunbound/unbound.c +++ b/libunbound/unbound.c @@ -622,11 +622,6 @@ ub_val_cancel(struct ub_val_ctx* ctx, int async_id) 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 */ @@ -634,18 +629,23 @@ ub_val_cancel(struct ub_val_ctx* ctx, int async_id) (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; } diff --git a/libunbound/worker.c b/libunbound/worker.c index 3b0f5b952..9dd98b45e 100644 --- a/libunbound/worker.c +++ b/libunbound/worker.c @@ -128,8 +128,7 @@ libworker_setup(struct ub_val_ctx* ctx, int is_bg) (((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)) { @@ -175,7 +174,14 @@ libworker_setup(struct ub_val_ctx* ctx, int is_bg) 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 */ @@ -621,7 +627,9 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len) 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); } diff --git a/testcode/asynclook.c b/testcode/asynclook.c index 37ad2cb7c..655c7f0d1 100644 --- a/testcode/asynclook.c +++ b/testcode/asynclook.c @@ -147,6 +147,66 @@ struct ext_thr_info { 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) @@ -157,12 +217,13 @@ 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; @@ -212,7 +273,7 @@ ext_thread(void* arg) /* 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) { diff --git a/util/random.c b/util/random.c index 812148b58..d91e6e3a5 100644 --- a/util/random.c +++ b/util/random.c @@ -112,13 +112,14 @@ ub_initstate(unsigned int seed, struct ub_randstate* state, 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;