Patch: Elm ME+ 2.5 PLalpha46 -> Elm ME+ 2.5 PLalpha47 [5/7] (6/7)
From
Kari Hurtta@21:1/5 to
All on Sat Feb 10 14:46:35 2018
[continued from previous message]
+ DPRINT(Debug,14,(&Debug,
+ "query_one_name: [pid %d] query %lu %s: failed to parse query\n",
+ pid,
+ (unsigned long)querynum,
+ name_buffer ? name_buffer : name));
+ free_resolv_query_item(&ret);
+ goto failure;
+ }
+
+ inc_resolv_query_item_recount(ret);
+
+ select_resolv_process(pid,querynum,name_buffer ? name_buffer : name);
+
+ failure:
+ if (name_buffer)
+ free(name_buffer);
+
+ DPRINT(Debug,14,(&Debug, "query_one_name=%p [pid %d]",ret,pid));
+
+ if (*err_p) {
+ DPRINT(Debug,14,(&Debug, "; *err_p=%d",*err_p));
+ }
+
+ DPRINT(Debug,14,(&Debug, "\n"));
+
+ return ret;
+ }
+
+
+ /* Returns 1 is answer is already ready */
+ static int resolv_answer_ready P_((struct resolv_query_item * qitem,
+ int * resize,
+ int pid));
+ static int resolv_answer_ready(qitem,resize,pid)
+ struct resolv_query_item * qitem;
+ int * resize;
+ int pid;
+ {
+ int done = 0;
+
+ if (RESOLV_QUERY_ITEM_magic != qitem->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "resolv_answer_ready",
+ "Bad magic number (resolv_query_item)",0);
+
+ DPRINT(Debug,16,(&Debug,
+ "resolv_answer_ready: [pid %d] start --------------------------\n",
+ pid));
+ DPRINT(Debug,16,(&Debug,
+ " : querynum = %lu\n",
+ (unsigned long)qitem->querynum));
+ DPRINT(Debug,16,(&Debug,
+ " : name = %s\n",
+ qitem->name ? qitem->name : "<none>"));
+ DPRINT(Debug,16,(&Debug,
+ " : last_errno = %d\n",
+ qitem->last_errno));
+ DPRINT(Debug,16,(&Debug,
+ " : looking_up = %d",
+ qitem->looking_up));
+ switch (qitem->looking_up) {
+ case l_up_none: DPRINT(Debug,16,(&Debug," (none)")); break;
+ case l_up_printed: DPRINT(Debug,16,(&Debug," (printed)")); break;
+ case l_up_error: DPRINT(Debug,16,(&Debug," (error)")); break;
+ case l_up_truncated_retry: DPRINT(Debug,16,(&Debug," (truncated retry)")); break;
+ case l_up_stalled: DPRINT(Debug,16,(&Debug," (stalled)")); break;
+ }
+ DPRINT(Debug,16,(&Debug,"\n"));
+ DPRINT(Debug,16,(&Debug,
+ " : fill_have_error = %d\n",
+ qitem->fill_have_error));
+ DPRINT(Debug,16,(&Debug,
+ " : transient_error = %d\n",
+ qitem->transient_error));
+ DPRINT(Debug,16,(&Debug,
+ " : other = %d\n",
+ qitem->other));
+ DPRINT(Debug,16,(&Debug,
+ " : is_search = %d\n",
+ qitem->is_search));
+ DPRINT(Debug,16,(&Debug,
+ " : query_sent = %d\n",
+ qitem->query_sent));
+ DPRINT(Debug,16,(&Debug,
+ " : valid_answer = %d\n",
+ qitem->valid_answer));
+ DPRINT(Debug,16,(&Debug,
+ " : invalid_answer = %d\n",
+ qitem->invalid_answer));
+ DPRINT(Debug,16,(&Debug,
+ " : shutdown = %d\n",
+ qitem->shutdown));
+ DPRINT(Debug,16,(&Debug,
+ "resolv_answer_ready: [pid %d] --------------------------------\n",
+ pid));
+
+ if (qitem->last_errno) {
+ DPRINT(Debug,14,(&Debug,
+ "resolv_answer_ready: [pid %d] query %lu %s: done, error %d (%s)\n",
+ pid,(unsigned long)qitem->querynum,
+ qitem->name ? qitem->name : "<none>",
+ qitem->last_errno,strerror(qitem->last_errno)));
+
+ if (resize && EMSGSIZE == qitem->last_errno && qitem->answer_buffer) { + struct resolv_message * answer_buffer = qitem->answer_buffer;
+
+ if (RESOLV_MESSAGE_magic != answer_buffer->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "resolv_answer_ready",
+ "Bad magic number (resolv_message)",0);
+
+ if (answer_buffer->message_size < MAX_resolv_bufsize) {
+ DPRINT(Debug,14,(&Debug,
+ "resolv_answer_ready: [pid %d] query %lu %s: message size %lu, can resized\n",
+ pid,(unsigned long)qitem->querynum,
+ qitem->name ? qitem->name : "<none>",
+ (unsigned long)answer_buffer->message_size)); + *resize = 1;
+ } else
+ goto no_resize;
+
+ } else {
+ no_resize:
+ if (qitem->looking_up < l_up_error && qitem->name) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookError,
+ "Looking up %s: %s"),
+ qitem->name,strerror(qitem->last_errno));
+ qitem->looking_up = l_up_error;
+ }
+ }
+ done = 1;
+
+ } else if (qitem->fill_have_error ||
+ qitem->transient_error ||
+ qitem->valid_answer ||
+ qitem->failed_answer ||
+ qitem->invalid_answer ||
+ qitem->shutdown) {
+ DPRINT(Debug,14,(&Debug,
+ "resolv_answer_ready: [pid %d] query %lu %s: done%s%s%s%s%s\n",
+ pid,(unsigned long)qitem->querynum,
+ qitem->name ? qitem->name : "<none>",
+ qitem->fill_have_error ? ", fill have error" : "",
+ qitem->transient_error ? ", (fill have) transient error" : "",
+ qitem->valid_answer ? ", valid answer" : "",
+ qitem->invalid_answer ? ", invalid answer" : "",
+ qitem->shutdown ? ", shutdown" : ""));
+
+ done = 1;
+ } else if (qitem->answer_buffer) {
+ struct resolv_message * answer_buffer = qitem->answer_buffer;
+
+ if (RESOLV_MESSAGE_magic != answer_buffer->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "resolv_answer_ready",
+ "Bad magic number (resolv_message)",0);
+
+ if (answer_buffer->message_parsed) {
+ DPRINT(Debug,14,(&Debug,
+ "resolv_answer_ready: [pid %d] query %lu %s: done, message parsed\n",
+ pid,(unsigned long)qitem->querynum,
+ qitem->name ? qitem->name : "<none>"));
+
+ done=1;
+ }
+ }
+
+ DPRINT(Debug,14,(&Debug,
+ "resolv_answer_ready=%d (%s): [pid %d] query %lu %s",
+ done,
+ done ? "done" : "not done",
+ pid,(unsigned long)qitem->querynum,
+ qitem->name ? qitem->name : "<none>"));
+
+ if (resize) {
+ DPRINT(Debug,14,(&Debug,"; *resize=%d",
+ *resize));
+ }
+
+ DPRINT(Debug,14,(&Debug,"\n"));
+
+ return done;
+
+ }
+
+ #define STALLED_SECONDS_DEFAULT (5 * 60)
+ static const int MAX_stalled_seconds = (STALLED_SECONDS_DEFAULT > (60 *60)) ? STALLED_SECONDS_DEFAULT : (60 *60);
+ static const int MIN_stalled_seconds = (STALLED_SECONDS_DEFAULT < 30) ? STALLED_SECONDS_DEFAULT : 30;
+
+ static char resolv_stalled_seconds_value[SHORT]; /* cache exact string */
+ static int resolv_stalled_seconds
+ #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET) && defined(BACKGROUD_PROCESSES)
+ = STALLED_SECONDS_DEFAULT /* deadline 5 minutes from reference time of query */
+ #endif
+ ;
+
+
+ /* return 1 if got answer */
+ static int resolv_wait_answer P_((struct resolv_query_item * qitem,
+ int * resize,
+ struct cancel_data ** cancel_p));
+ static int resolv_wait_answer(qitem, resize, cancel_p)
+ struct resolv_query_item * qitem;
+ int * resize;
+ struct cancel_data ** cancel_p
+ /* May be NULL, Used if dns lookup was cancelable
+ -- not really canceled, just
+ stop waiting of result
+ */;
+ {
+
+ char *X = NULL;
+ int pid = getpid();
+ struct schedule_timelimit wait_deadline = NO_schedule_timelimit;
+ struct schedule_timelimit current = NO_schedule_timelimit;
+ int done = 0;
+
+ if (RESOLV_QUERY_ITEM_magic != qitem->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "resolv_wait_answer",
+ "Bad magic number (resolv_query_item)",0);
+
+ if (resize)
+ *resize = 0;
+
+ X = schedule_timeout_string(& (qitem->query_time));
+ if (X) {
+ DPRINT(Debug,14,(&Debug,
+ "resolv_wait_answer: [pid %d] query %lu %s: query time %s\n",
+ pid,(unsigned long)qitem->querynum,
+ qitem->name ? qitem->name : "<NONE>",X));
+ free(X); X = NULL;
+ }
+
+ if (schedule_set_next_timeout0(&wait_deadline,& (qitem->query_time),resolv_stalled_seconds,
+ se_use_time_MAX)) {
+
+ X = schedule_timeout_string(&wait_deadline);
+
+ if (X) {
+ DPRINT(Debug,14,(&Debug,
+ "resolv_wait_answer: [pid %d] query %lu %s: wait deadline %s\n",
+ pid,(unsigned long)qitem->querynum,
+ qitem->name ? qitem->name : "<NONE>",X));
+ free(X); X = NULL;
+ }
+ }
+
+ done = resolv_answer_ready(qitem,resize,pid);
+
+ #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
+ while (!done) {
+ enum wait_for_status r;
+
+ errno = 0;
+
+ if (cancel_p) {
+
+ if (l_up_none == qitem->looking_up && qitem->name) {
+ if (!*cancel_p || is_schedule_cancel(*cancel_p,NULL)) {
+ r = wait_for_action_or_timeout_settime_c(resolv_read_message,1,¤t,
+ *cancel_p);
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "resolv_wait_answer: 'Looking up' already printed.\n"));
+ qitem->looking_up = l_up_printed;
+
+ r = wait_for_action_or_deadline_settime_c(resolv_read_message,&wait_deadline,
+ ¤t,*cancel_p);
+ }
+ } else {
+ r = wait_for_action_or_deadline_settime_c(resolv_read_message,&wait_deadline,
+ ¤t,*cancel_p); + }
+
+ } else {
+ if (l_up_none == qitem->looking_up && qitem->name)
+ r = wait_for_action_or_timeout_settime(resolv_read_message,1,¤t);
+ else
+ r = wait_for_action_or_deadline_settime(resolv_read_message,&wait_deadline,
+ ¤t);
+ }
+
+ if (r > wait_for_none) {
+
+ done = resolv_answer_ready(qitem,resize,pid);
+
+ if (!done) {
+ if (l_up_none == qitem->looking_up && qitem->name) {
+
+ if (qitem->looking_up < l_up_error && qitem->name) {
+ if (cancel_p && *cancel_p) {
+ if (is_schedule_cancel(*cancel_p,NULL))
+ set_cancel_message(*cancel_p,
+ -1 /* Show immediately */,
+ CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookingUp,
+ "Looking up %s ..."),
+ qitem->name);
+ else {
+ DPRINT(Debug,14,(&Debug,
+ "resolv_wait_answer: 'Looking up' already printed.\n"));
+ }
+
+ } else
+ lib_transient(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookingUp,
+ "Looking up %s ..."),
+ qitem->name);
+ }
+
+ qitem->looking_up = l_up_printed;
+
+ /* Messages may wait events -- so recheck status .... */
+ done = resolv_answer_ready(qitem,resize,pid);
+
+ } else if (schedule_timeout_reached(&wait_deadline,¤t)) { + if (qitem->looking_up < l_up_error && qitem->name) {
+ lib_transient(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookingUpStalled,
+ "Looking up %s: Stalled (giving up)"),
+ qitem->name);
+
+ qitem->looking_up = l_up_stalled;
+
+ /* Messages may wait events -- so recheck status .... */
+ done = resolv_answer_ready(qitem,resize,pid);
+ }
+
+ DPRINT(Debug,14,(&Debug,
+ "resolv_wait_answer: [pid %d] query %lu %s: timeout\n",
+ pid,(unsigned long)qitem->querynum,
+ qitem->name ? qitem->name : "<none>"));
+ goto timeout;
+ }
+ }
+ } else {
+ switch (r) {
+ int err;
+ case wait_for_done: break;
+ case wait_for_none:
+ DPRINT(Debug,14,(&Debug,
+ "resolv_wait_answer: [pid %d] query %lu %s: unexpected result from wait_for_action_or_...\n",
+ pid,(unsigned long)qitem->querynum,
+ qitem->name ? qitem->name : "<none>"));
+ break;
+ case wait_for_error:
+ err = errno;
+
+ DPRINT(Debug,14,(&Debug,
+ "resolv_wait_answer: [pid %d] query %lu %s: errno=%d, %s\n",
+ pid,(unsigned long)qitem->querynum,
+ qitem->name ? qitem->name : "<none>",
+ err,strerror(err)));
+ if (err == EINTR && cancel_p && *cancel_p && is_canceled(*cancel_p)) {
+ DPRINT(Debug,12,(&Debug,
+ "bgconnect_wait_delay: wait canceled\n")); +
+ goto out;
+ }
+ break;
+ }
+ }
+ }
+ #endif
+
+ out:
+ timeout:
+ X = schedule_timeout_string(¤t);
+
+ DPRINT(Debug,14,(&Debug,
+ "resolv_wait_answer=%d%s [pid %d] query %lu %s",
+ done,
+ done ? " (done) " : "",
+ pid,(unsigned long)qitem->querynum,
+ qitem->name ? qitem->name : "<none>"));
+ if (X) {
+ DPRINT(Debug,14,(&Debug," at %s",
+ X));
+ free(X);
+ }
+
+ DPRINT(Debug,14,(&Debug,"\n"));
+ return done;
+ }
+
+ /* input / output flags */
+ static const struct check_query_answer_f {
+ unsigned int have_error :1;
+ unsigned int other :1;
+ unsigned int no_name :1;
+ unsigned int end_search :1;
+ } NULL_check_query_answer_f = {
+ 0,0,0,0
+ };
+
+ static struct resolv_cache * check_query_answer P_((struct resolv_query_item * query,
+ const char * name,
+ enum looking_up * looking_up_p,
+ char ** search_name_p,
+ struct check_query_answer_f * flags_p));
+ static struct resolv_cache * check_query_answer(query,name,looking_up_p,
+ search_name_p,flags_p)
+ struct resolv_query_item * query;
+ const char * name;
+ enum looking_up * looking_up_p;
+ char ** search_name_p;
+ struct check_query_answer_f * flags_p;
+ {
+ struct resolv_cache * ret = NULL;
+
+ if (RESOLV_QUERY_ITEM_magic != query->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "check_query_answer",
+ "Bad magic number (resolv_query_item)",0);
+
+
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: IN flags have_error:%d other:%d no_name:%d end_search:%d\n",
+ name,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>",
+ flags_p->have_error,
+ flags_p->other,
+ flags_p->no_name,
+ flags_p->end_search));
+
+ if (query->answer_buffer) {
+ struct resolv_message * answer_buffer = query->answer_buffer;
+
+ if (RESOLV_MESSAGE_magic != answer_buffer->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "check_query_answer",
+ "Bad magic number (resolv_message)",0);
+
+ if (answer_buffer->message_parsed) {
+ ns_rcode response_code =
+ ns_msg_getflag(answer_buffer->parsed_message,
+ ns_f_rcode);
+ unsigned short aa UNUSED_VAROK =
+ ns_msg_getflag(answer_buffer->parsed_message,
+ ns_f_aa);
+
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: answer buffer: resonse code=%d, authorative=%d (%s)\n",
+ name,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>",
+ response_code,aa,
+ aa ? "yes" : "no"));
+
+ if (ns_r_nxdomain == response_code) {
+
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: no name\n",
+ name,(unsigned long)query->querynum,
+ query->name ? query->name : "<none>"));
+ flags_p->no_name = 1;
+ }
+ }
+ }
+
+ if (query->valid_answer) {
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: valid answer set\n",
+ name,(unsigned long)query->querynum,
+ query->name ? query->name : "<none>"));
+
+ if (query->other) { /* Name found, no more search */
+ flags_p->end_search = 1;
+ flags_p->other = 1;
+ }
+
+ ret = query-> cache_answer_ret;
+ if (ret) {
+ inc_resolv_cache_refcount(ret);
+
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: got resolv cache record\n",
+ name,(unsigned long)query->querynum,
+ query->name ? query->name : "<none>"));
+ }
+
+ if (search_name_p && query->answer_search_name) {
+
+ if (*search_name_p) {
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: changing *search_name_p: %s => %s\n",
+ name,(unsigned long)query->querynum,
+ query->name ? query->name : "<none>",
+ *search_name_p,
+ query->answer_search_name));
+
+ *search_name_p = strmcpy(*search_name_p,query->answer_search_name);
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: setting *search_name_p: %s\n",
+ name,(unsigned long)query->querynum,
+ query->name ? query->name : "<none>",
+ query->answer_search_name));
+
+ *search_name_p = safe_strdup(query->answer_search_name);
+ }
+ }
+ }
+
+ if (query->failed_answer) {
+
+ struct resolv_query_hdr * answer_hdr = query->answer_hdr;
+
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: failed answer set\n",
+ name,(unsigned long)query->querynum,
+ query->name ? query->name : "<none>"));
+
+ if (answer_hdr) {
+ if ( RESOLV_QUERY_HDR_magic != answer_hdr->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "check_query_answer",
+ "Bad magic number (resolv_query_hdr)",0);
+
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: answer hdr: h_errno=%d, errno=%d (%s)\n",
+ name,(unsigned long)query->querynum,
+ query->name ? query->name : "<none>",
+ answer_hdr->h_errno_val,answer_hdr->errno_val,
+ strerror(answer_hdr->errno_val)));
+
+ switch(answer_hdr->h_errno_val) {
+ case HOST_NOT_FOUND:
+ if (query->looking_up < l_up_error) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookNotFound,
+ "Looking up %s: not found"),
+ name);
+
+ query->looking_up = l_up_error;
+ if (looking_up_p)
+ *looking_up_p = l_up_error;
+ }
+
+ flags_p->end_search = 1;
+ break;
+
+ case NO_DATA:
+ flags_p->other = 1;
+ break;
+
+ case TRY_AGAIN:
+
+ if (query->looking_up < l_up_error) {
+ if (answer_hdr->errno_val)
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookErrno,
+ "Looking up %s: %s"),
+ name,strerror(answer_hdr->errno_val));
+ else
+ lib_transient(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookTryAgain,
+ "Looking up %s: not found yet"), + name);
+
+ query->looking_up = l_up_error;
+ }
+
+ flags_p->have_error= 1;
+ flags_p->end_search = 1;
+ break;
+
+ case NO_RECOVERY:
+
+ if (query->looking_up < l_up_error) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookBadName,
+ "Looking up %s: bad name or refused query"),
+ name);
+
+ query->looking_up = l_up_error;
+ }
+
+ flags_p->have_error = 1;
+ flags_p->end_search = 1;
+ break;
+
+ case NETDB_INTERNAL:
+ default:
+
+ if (answer_hdr->errno_val) {
+
+ if (query->looking_up < l_up_error) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookErrno,
+ "Looking up %s: %s"),
+ name,strerror(answer_hdr->errno_val));
+ query->looking_up = l_up_error;
+ }
+
+ flags_p->have_error = 1;
+ flags_p->end_search = 1;
+
+ } else if (answer_hdr->h_errno_val) {
+
+ if (query->looking_up < l_up_error) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookFailed,
+ "Looking up %s: failed"),
+ name);
+
+ query->looking_up = l_up_error;
+ }
+
+ flags_p->have_error = 1;
+ flags_p->end_search = 1;
+
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: no error data on failed answer\n",
+ name,(unsigned long)query->querynum,
+ query->name ? query->name : "<none>"));
+ }
+ break;
+ }
+ }
+ }
+
+ if (query->transient_error) {
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: fill have transient error set\n",
+ name,(unsigned long)query->querynum,
+ query->name ? query->name : "<none>"));
+ }
+
+ if (query->fill_have_error) {
+
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: fill have error set\n",
+ name,(unsigned long)query->querynum,
+ query->name ? query->name : "<none>"));
+
+ flags_p->have_error = 1;
+ flags_p->end_search = 1;
+
+ if (query->looking_up < l_up_error) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookErrorProcess,
+ "Looking up %s: Failed to process answer"),
+ name);
+
+ query->looking_up = l_up_error;
+ }
+
+
+ }
+
+ if (looking_up_p)
+ *looking_up_p = query->looking_up;
+
+ DPRINT(Debug,14,(&Debug,
+ "check_query_answer: %s: query %lu %s: OUT flags have_error:%d other:%d no_name:%d end_search:%d\n",
+ name,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>",
+ flags_p->have_error,
+ flags_p->other,
+ flags_p->no_name,
+ flags_p->end_search));
+
+ return ret;
+ }
+
+ /* return 1 if still have answer */
+ static int resize_query_answer P_((struct resolv_query_item * query,
+ int * resize,
+ struct cancel_data ** cancel_p));
+ static int resize_query_answer(query,resize,cancel_p)
+ struct resolv_query_item * query;
+ int * resize;
+ struct cancel_data ** cancel_p
+ /* May be NULL, Used if dns lookup was cancelable
+ -- not really canceled, just
+ stop waiting of result
+ */;
+ {
+ size_t asize = RESOLV_BUFSIZE;
+ int need_recheck = 0;
+ int answer_ok = 1;
+ int pid = getpid();
+
+ if (RESOLV_QUERY_ITEM_magic != query->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "resize_query_answer",
+ "Bad magic number (resolv_query_item)",0);
+
+ do {
+ int need_resize = 0;
+ int anslen = 0;
+
+ if (resize) {
+ need_resize = *resize;
+
+ if (need_resize) {
+ DPRINT(Debug,14,(&Debug,
+ "resize_query_answer: [pid %d] query %lu %s: resizing request %s set\n",
+ pid,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>",
+ need_recheck ? "still" : "already"));
+ *resize = 0;
+ }
+ }
+
+ need_recheck = 0;
+
+ if (query->answer_buffer) {
+ struct resolv_message * answer_buffer = query->answer_buffer;
+
+ if (RESOLV_MESSAGE_magic != answer_buffer->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "check_query_answer",
+ "Bad magic number (resolv_message)",0);
+
+ asize = answer_buffer->message_size;
+
+ DPRINT(Debug,14,(&Debug,
+ "resize_query_answer: [pid %d] query %lu %s: answer size %lu\n",
+ pid,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>",
+ (unsigned long)asize));
+
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "resize_query_answer: [pid %d] query %lu %s: no answer buffer?\n",
+ pid,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>"));
+
+ query->answer_buffer = new_resolv_message();
+ need_resize = 1;
+ }
+
+ if (query->answer_hdr) {
+
+ struct resolv_query_hdr * answer_hdr = query->answer_hdr;
+
+ if (RESOLV_QUERY_HDR_magic != answer_hdr->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "resize_query_answer",
+ "Bad magic number (resolv_query_hdr)",0);
+
+ if (answer_hdr->errno_val) {
+ DPRINT(Debug,14,(&Debug,
+ "resize_query_answer: [pid %d] query %lu %s: answer hdr errno %d (%s), answer buffer message size %lu\n",
+ pid,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>",
+ answer_hdr->errno_val,
+ strerror(answer_hdr->errno_val),
+ (unsigned long)query->answer_buffer->message_size));
+
+ if (EMSGSIZE == answer_hdr->errno_val &&
+ query->answer_buffer->message_size < MAX_resolv_bufsize) { + DPRINT(Debug,14,(&Debug,
+ "resize_query_answer: [pid %d] query %lu %s: answer buffer message size %lu, can resized\n",
+ pid,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>",
+ (unsigned long)query->answer_buffer->message_size));
+ need_resize = 1;
+
+ anslen = query->answer_buffer->message_len;
+ }
+ }
+ }
+
+
+ if (need_resize) {
+
+ if (asize < MAX_resolv_bufsize) {
+ size_t old UNUSED_VAROK = asize;
+
+ if (asize < sizeof (struct resolv_sizeupdate))
+ asize = sizeof (struct resolv_sizeupdate);
+ else
+ asize <<= 1;
+
+ if (asize > MAX_resolv_bufsize)
+ asize = MAX_resolv_bufsize;
+
+ DPRINT(Debug,14,(&Debug,
+ "resize_query_answer: [pid %d] query %lu %s: resizing answer buffer message size %lu => %lu\n",
+ pid,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>",
+ (unsigned long)old,
+ (unsigned long)asize));
+
+ if (anslen) {
+ lib_transient(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookTruncatedRetry,
+ "Looking up %s: Answer truncated (%d bytes), retrying..."),
+ query->name ? query->name : "<none>",
+ anslen);
+ query->looking_up = l_up_truncated_retry;
+ }
+
+ resize_resolv_message(query->answer_buffer,asize);
+
+ /* Reset answer data */
+ if (query->answer_hdr)
+ *(query->answer_hdr) = NULL_resolv_query_hdr;
+ query->last_errno = 0;
+ if (query->cache_answer_ret)
+ free_resolv_cache(& (query->cache_answer_ret));
+
+ query->fill_have_error = 0;
+ query->transient_error = 0;
+ query->other = 0;
+ query->query_sent = 0; /* cause resent */
+ query->valid_answer = 0;
+ query->failed_answer = 0;
+ query-> invalid_answer = 0;
+ query->shutdown = 0;
+
+ select_resolv_process(pid,query->querynum,
+ query->name ? query->name : "<none>");
+
+
+ answer_ok = resolv_wait_answer(query,resize,cancel_p);
+
+ if (answer_ok) {
+ DPRINT(Debug,14,(&Debug,
+ "resize_query_answer: [pid %d] query %lu %s: got answer after resent\n",
+ pid,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>"));
+ need_recheck = 1;
+ } else
+ need_recheck = 0;
+
+ } else
+ need_recheck = 0;
+
+ } else
+ need_recheck = 0;
+
+ if (need_recheck) {
+ DPRINT(Debug,14,(&Debug,
+ "resize_query_answer: [pid %d] query %lu %s: rechecking\n",
+ pid,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>"));
+ }
+
+ } while (need_recheck);
+
+ DPRINT(Debug,14,(&Debug,
+ "resize_query_answer%d%s: [pid %d] query %lu %s\n",
+ answer_ok,
+ answer_ok ? " (answer ok)" : " (no answer)",
+ pid,
+ (unsigned long)query->querynum,
+ query->name ? query->name : "<none>"));
+
+
+ return answer_ok;
+ }
+
+
+ static void end_query_helper P_((struct resolv_query_item ** query_p,
+ const int err,
+ const char * name,
+ struct resolv_cache ** ret_p,
+ enum looking_up * looking_up_p,
+ char ** search_name_p,
+ struct check_query_answer_f * flags_p,
+ struct cancel_data ** cancel_p
+ /* May be NULL, Used if dns lookup was cancelable
+ -- not really canceled, just
+ stop waiting of result
+ */));
+ static void end_query_helper(query_p,err,name,ret_p,looking_up_p,search_name_p,
+ flags_p,cancel_p)
+ struct resolv_query_item ** query_p;
+ const int err;
+ const char * name;
+ struct resolv_cache ** ret_p;
+ enum looking_up * looking_up_p;
+ char ** search_name_p;
+ struct check_query_answer_f * flags_p;
+ struct cancel_data ** cancel_p
+ /* May be NULL, Used if dns lookup was cancelable
+ -- not really canceled, just
+ stop waiting of result
+ */;
+ {
+
+ if (*query_p) {
+ int resize = 0;
+
+ if (RESOLV_QUERY_ITEM_magic != (*query_p)->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "end_query_helper",
+ "Bad magic number (resolv_query_item)",0);
+
+ DPRINT(Debug,16,(&Debug,
+ "end_query_helper: %s: got query\n",
+ name));
+
+ if (*ret_p)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "end_query_helper",
+ "result already set",0);
+
+ if (resolv_wait_answer(*query_p,&resize,cancel_p)) {
+
+ if (resize_query_answer(*query_p,&resize,cancel_p)) {
+ *ret_p = check_query_answer(*query_p,name,looking_up_p,
+ search_name_p,flags_p);
+ } else
+ goto end_search;
+ } else {
+ end_search:
+ if (cancel_p && *cancel_p &&
+ is_canceled(*cancel_p)) {
+
+ DPRINT(Debug,14,(&Debug,
+ "end_query_helper: %s: DNS lookup canceled\n", + name));
+
+ flags_p->end_search = 1;
+ flags_p->have_error = 1; /* Not actually used when is_canceled()
+ is set, in that case error is set directly
+ on caller
+ */
+ goto fail;
+
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "end_query_helper: %s: no answer\n",
+ name));
+ flags_p->end_search = 1; /* No answer or no answer after retry*/
+ }
+ }
+
+ } else if (err) {
+ DPRINT(Debug,14,(&Debug,
+ "end_query_helper: %s: error %d (%s)\n",
+ name,err,strerror(err)));
+
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookError,
+ "Looking up %s: %s"),
+ name,strerror(err));
+
+ if (looking_up_p)
+ *looking_up_p = l_up_error;
+
+ flags_p->end_search = 1;
+ } else {
+ DPRINT(Debug,16,(&Debug,
+ "end_query_helper: %s: no query\n",
+ name));
+
+ flags_p->no_name = 1; /* searching only when NRXDOMAIN was previous result */
+ }
+
+ fail:
+
+ if (*query_p)
+ free_resolv_query_item(query_p);
+
+ DPRINT(Debug,16,(&Debug,
+ "end_query_helper: %s: handled%s%s%s%s\n",
+ name,
+ flags_p->end_search ? ", end search" : "",
+ flags_p->no_name ? ", no name" : "",
+ flags_p->have_error ? ", have error" : "",
+ *ret_p ? ", answer set" : ""));
+ }
+
+ S_(lookup_resolv_cache_qm_f lookup_resolv_cache_nonblocked)
+ struct resolv_cache * lookup_resolv_cache_nonblocked
+ P_((struct resolv_cache * record,
+ const char * name,
+ const struct schedule_timelimit * now,
+ const ns_type q_type,
+ const int is_search,
+ enum looking_up * looking_up,
+ char ** search_name,
+ int * have_error,
+ int * other,
+ struct cancel_data ** cancel_p));
+ static struct resolv_cache * lookup_resolv_cache_nonblocked(record,name,now, + q_type,is_search,
+ looking_up_p,search_name_p,
+ have_error_p,other_p,
+ cancel_p)
+ struct resolv_cache * record;
+ const char * name;
+ const struct schedule_timelimit * now;
[continued in next message]
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)