Patch: Elm ME+ 2.5 PLalpha46 -> Elm ME+ 2.5 PLalpha47 [5/7] (3/7)
From
Kari Hurtta@21:1/5 to
All on Sat Feb 10 14:46:35 2018
[continued from previous message]
+ case rs_continue: SIGDPRINT(Debug,14,(&Debug, " (continue) ")); break;
+ }
+ SIGDPRINT(Debug,14,(&Debug, "\n"));
+
+
+ quitting:
+ hdr.magic = RESOLV_QUERY_HDR_magic;
+ hdr.errno_val = err;
+ hdr.h_errno_val = 0;
+ hdr.msg = qm_shutdown;
+ hdr.buflen = 0;
+ hdr.senderpid = pid;
+ ws = write_message(socket,&hdr,NULL,0,&err,pid,NULL);
+
+ SIGDPRINT(Debug,12,(&Debug, "resolv_send_process: [pid %d] Stopping\n",pid));
+
+ if (query_buffer != query_buffer1)
+ free(query_buffer);
+ if (answer_buffer != answer_buffer1)
+ free(answer_buffer);
+ }
+
+ #endif
+
+
+ #define RESOLV_MESSAGE_magic 0xF918
+
+ static struct resolv_message {
+ unsigned short magic; /* RESOLV_MESSAGE_magic */
+ unsigned short message_len;
+ unsigned char * message;
+ size_t message_size; /* alloced space of message for sizeupdate */
+ ns_msg parsed_message;
+
+ unsigned int message_parsed :1;
+ } * new_resolv_message P_((void)) UNUSED_FUNCOK;
+
+ static struct resolv_message * new_resolv_message()
+ {
+ struct resolv_message * ret =
+ safe_zero_alloc(sizeof (*ret));
+
+ ret->magic = RESOLV_MESSAGE_magic;
+ ret->message_len = 0;
+ ret->message = NULL;
+ ret->message_size = 0;
+ ret->message_parsed = 0;
+
+ return ret;
+ }
+
+ static void resize_resolv_message P_((struct resolv_message *msg,
+ size_t newsize))
+ UNUSED_FUNCOK;
+ static void resize_resolv_message(msg,newsize)
+ struct resolv_message *msg;
+ size_t newsize;
+ {
+ if (RESOLV_MESSAGE_magic != msg->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "resize_resolv_message",
+ "Bad magic number (resolv_message)",0);
+
+ msg->message_size = newsize;
+ msg->message = safe_realloc(msg->message,
+ msg->message_size);
+ msg->message_len = 0;
+ msg->message_parsed = 0;
+ }
+
+
+ static void free_resolv_message P_((struct resolv_message **msg))
+ UNUSED_FUNCOK;
+ static void free_resolv_message(msg)
+ struct resolv_message **msg;
+ {
+ if (RESOLV_MESSAGE_magic != (*msg)->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "free_resolv_message",
+ "Bad magic number (resolv_message)",0);
+
+ if ((*msg)->message) {
+ free ((*msg)->message);
+ (*msg)->message = NULL;
+ }
+
+ (*msg)->magic = 0; /* Invalidate */
+ free(*msg);
+ *msg = NULL;
+ }
+
+ #define RESOLV_QUERY_ITEM_magic 0xF919
+
+ static struct resolv_query_item {
+ unsigned short magic; /* RESOLV_QUERY_ITEM_magic */
+
+ size_t querynum;
+ struct schedule_timelimit query_time;
+ char * name; /* name for error messages */
+ struct resolv_message * query_buffer;
+ struct resolv_query_hdr * query_hdr;
+
+ struct resolv_message * answer_buffer;
+ struct resolv_query_hdr * answer_hdr;
+
+ int last_errno;
+
+ struct resolv_cache * cache_answer_in; /* 'answer' for fill_resolv_cache() */
+ struct resolv_cache * cache_answer_ret; /* Return value of fill_resolv_cache() */
+ char * answer_search_name; /* Return 'search_name' for fill_resolv_cache() */
+ enum looking_up looking_up; /* Return 'looking_up' for fill_resolv_cache() */
+
+ unsigned int fill_have_error:1; /* Return 'have_error' for fill_resolv_cache() */
+ unsigned int transient_error:1; /* Return 'have_error' for fill_resolv_cache() */
+ unsigned int other:1; /* have other data for name */
+
+ unsigned int is_search :1; /* Is search, do not report not found errors yet */
+
+ unsigned int query_sent :1;
+ unsigned int valid_answer :1;
+ unsigned int failed_answer :1;
+ unsigned int invalid_answer :1; /* Answer not stored */
+ unsigned int shutdown :1; /* shutdown seen */
+
+ int refcount;
+
+ } ** query_list = NULL; /* Indezed by querynum , 0 is not used */
+ static size_t query_list_len = 0; /* MAX querynum + 1 */
+
+ static struct resolv_query_item * new_resolv_query_item P_((size_t querynum, const char *name)) UNUSED_FUNCOK;
+ static struct resolv_query_item * new_resolv_query_item(querynum,name)
+ size_t querynum;
+ const char * name;
+ {
+ struct resolv_query_item *ret =
+ safe_zero_alloc(sizeof (*ret));
+
+ if (query_list_len > querynum && query_list[querynum])
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "new_resolv_query_item",
+ "querynum is already used",0);
+
+ ret->magic = RESOLV_QUERY_ITEM_magic;
+ ret->querynum = querynum;
+ ret->query_time = NO_schedule_timelimit;
+ ret->name = name ? safe_strdup(name) : NULL;
+ ret->query_buffer = NULL;
+ ret->query_hdr = NULL;
+ ret->last_errno = 0;
+ ret->cache_answer_in = NULL;
+ ret->cache_answer_ret = NULL;
+ ret->answer_search_name = NULL;
+ ret->looking_up = l_up_none;
+ ret->fill_have_error = 0;
+ ret->transient_error = 0;
+ ret->other = 0;
+ ret->is_search = 0;
+ ret->query_sent = 0;
+ ret->valid_answer = 0;
+ ret->failed_answer = 0;
+ ret->invalid_answer = 0;
+ ret->shutdown = 0;
+
+ ret->refcount = 1;
+
+ return ret;
+ }
+
+ /* Decrements refcount */
+
+ static void free_resolv_query_item P_(( struct resolv_query_item **ptr));
+ static void free_resolv_query_item(ptr)
+ struct resolv_query_item **ptr;
+ {
+ if (RESOLV_QUERY_ITEM_magic != (*ptr)->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "free_resolv_query_item",
+ "Bad magic number (resolv_query_item)",0);
+
+ if ((*ptr)->refcount < 1)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"free_resolv_query_item",
+ "Bad refcount",0);
+
+ (*ptr)->refcount--;
+ if ((*ptr)->refcount > 0) {
+ /* Just reset this reference */
+
+ *ptr = NULL;
+ return;
+ }
+
+ if ((*ptr)->name) {
+ free((*ptr)->name);
+ (*ptr)->name = NULL;
+ }
+
+ if ((*ptr)->query_buffer)
+ free_resolv_message(& ((*ptr)->query_buffer));
+
+ if ((*ptr)->query_hdr) {
+ free ((*ptr)->query_hdr);
+ (*ptr)->query_hdr = NULL;
+ }
+
+ if ((*ptr)->answer_buffer)
+ free_resolv_message(& ((*ptr)->answer_buffer));
+
+ if ((*ptr)->answer_hdr) {
+ free ((*ptr)->answer_hdr);
+ (*ptr)->answer_hdr = NULL;
+ }
+
+ if ((*ptr)->cache_answer_in)
+ free_resolv_cache(& ((*ptr)->cache_answer_in));
+
+ if ((*ptr)->cache_answer_ret)
+ free_resolv_cache(& ((*ptr)->cache_answer_ret));
+
+ if ((*ptr)->answer_search_name) {
+ free((*ptr)->answer_search_name);
+ (*ptr)->answer_search_name = NULL;
+ }
+
+ (*ptr)->magic = 0; /* Invalidate */
+
+ free(*ptr);
+ *ptr = NULL;
+ }
+
+ static void inc_resolv_query_item_recount P_(( struct resolv_query_item *ptr));
+ static void inc_resolv_query_item_recount(ptr)
+ struct resolv_query_item *ptr;
+ {
+ if (RESOLV_QUERY_ITEM_magic != ptr->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "inc_resolv_query_item_recount",
+ "Bad magic number (resolv_query_item)",0);
+
+ ptr->refcount++;
+ }
+
+ /* ------------------------------------------------------------------------------- */
+
+ #define RESOLV_MESSAGE_STATE_magic 0xF91B
+
+ static struct resolv_message_state {
+ unsigned short magic; /* RESOLV_MESSAGE_STATE_magic */
+
+ struct resolv_query_hdr read_hdr;
+ unsigned char * read_buffer;
+ size_t read_buffer_len;
+ size_t read_buffer_size;
+ size_t read_pos;
+
+ struct resolv_query_hdr write_hdr;
+ unsigned char * write_buffer;
+ size_t write_buffer_len;
+ size_t write_buffer_size;
+ size_t write_pos;
+
+ size_t querynum; /* Last or current query */
+
+ unsigned int write_prepared:1;
+ unsigned int broken_pipe:1; /* Broken pipe when writing, + EOF when reading
+ */
+ unsigned int query_in_progress:1; /* Query 'querynum' in progress */
+
+ int refcount;
+ } * new_resolv_message_state P_((int pid)) UNUSED_FUNCOK;
+
+ static struct resolv_message_state * new_resolv_message_state(pid)
+ int pid;
+ {
+ struct resolv_message_state *ret =
+ safe_zero_alloc(sizeof (*ret));
+
+ ret->magic = RESOLV_MESSAGE_STATE_magic;
+
+ ret->read_hdr.magic = RESOLV_QUERY_HDR_magic;
+ ret->read_hdr.buflen = 0;
+ ret->read_hdr.errno_val = 0;
+ ret->read_hdr.h_errno_val = 0;
+ ret->read_hdr.querynum = 0;
+ ret->read_hdr.senderpid = pid;
+ ret->read_hdr.msg = qm_none;
+
+ ret->read_buffer = NULL;
+ ret->read_buffer_size = 0;
+ ret->read_buffer_len = 0;
+ ret->read_pos = 0;
+
+ ret->write_hdr.magic = RESOLV_QUERY_HDR_magic;
+ ret->write_hdr.buflen = 0;
+ ret->write_hdr.errno_val = 0;
+ ret->write_hdr.h_errno_val = 0;
+ ret->write_hdr.querynum = 0;
+ ret->write_hdr.senderpid = pid;
+ ret->write_hdr.msg = qm_none;
+
+ ret->write_buffer = NULL;
+ ret->write_buffer_len = 0;
+ ret->write_buffer_size = 0;
+ ret->write_pos = 0;
+ ret->write_prepared = 0;
+ ret->broken_pipe = 0;
+ ret->query_in_progress = 0;
+ ret->querynum = 0;
+
+ ret->refcount = 1;
+
+ return ret;
+ }
+
+ /* Decrements refcount */
+ static void free_resolv_message_state P_((struct resolv_message_state **ptr));
+ static void free_resolv_message_state(ptr)
+ struct resolv_message_state **ptr;
+ {
+ if (RESOLV_MESSAGE_STATE_magic != (*ptr)->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"free_resolv_message_state",
+ "Bad magic number (resolv_message_state)",0);
+
+ if ((*ptr)->refcount < 1)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"free_resolv_message_state",
+ "Bad refcount",0);
+
+ (*ptr)->refcount--;
+ if ((*ptr)->refcount > 0) {
+ /* Just reset this reference */
+
+ *ptr = NULL;
+ return;
+ }
+
+ if ((*ptr)->read_buffer) {
+ free((*ptr)->read_buffer);
+ (*ptr)->read_buffer = NULL;
+ }
+
+ if ((*ptr)->write_buffer) {
+ free((*ptr)->write_buffer);
+ (*ptr)->write_buffer = NULL;
+ }
+
+ (*ptr)->read_hdr.magic = 0;
+ (*ptr)->write_hdr.magic = 0;
+ (*ptr)->magic = 0; /* Invalidate */
+ free(*ptr);
+ *ptr = NULL;
+ }
+
+ /* Decrements refcount */
+ static void inc_resolv_message_state_refcount P_((struct resolv_message_state *ptr))
+ UNUSED_FUNCOK;
+ static void inc_resolv_message_state_refcount(ptr)
+ struct resolv_message_state *ptr;
+ {
+ if (RESOLV_MESSAGE_STATE_magic != ptr->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"inc_resolv_message_state_refcount",
+ "Bad magic number (resolv_message_state)",0);
+
+ ptr->refcount ++;
+ }
+
+
+
+ /* --------------------------------------------------------------------------------*/
+
+ #define RESOLV_PROCESS_magic 0xF91A
+
+ static struct resolv_process {
+ unsigned short magic; /* RESOLV_PROCESS_magic */
+
+ int pid;
+
+ enum process_state {
+ ps_none = 0,
+ ps_forked = 1,
+ ps_running = 2 /* Got qm_running */,
+ ps_shutdown = 3 /* Got qm_shutdown */,
+ ps_exited = 4 /* Got exit status */,
+ ps_died = 5 /* Got signal */
+ } state;
+
+ struct resolv_message_state * message;
+ int socket;
+
+ int refcount;
+ } ** process_list = NULL;
+ static size_t process_list_len = 0;
+
+
+ static struct resolv_process * new_resolv_process P_((int pid));
+ static struct resolv_process * new_resolv_process(pid)
+ int pid;
+ {
+ struct resolv_process * ret =
+ safe_zero_alloc(sizeof (*ret));
+
+ ret->magic = RESOLV_PROCESS_magic;
+ ret->pid = pid;
+ ret->state = ps_none;
+ ret->message = NULL;
+ ret->socket = -1;
+ ret->refcount = 1;
+
+ return ret;
+ }
+
+ static void free_resolv_process P_((struct resolv_process **ptr));
+ static void free_resolv_process(ptr)
+ struct resolv_process **ptr;
+ {
+ if (RESOLV_PROCESS_magic != (*ptr)->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"free_resolv_process",
+ "Bad magic number (resolv_process)",0);
+
+ if ((*ptr)->refcount < 1)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"free_resolv_process",
+ "Bad refcount",0);
+ (*ptr)->refcount--;
+ if ((*ptr)->refcount > 0) {
+ /* Just reset this reference */
+
+ *ptr = NULL;
+ return;
+ }
+
+ if ((*ptr)->message) {
+ free_resolv_message_state(& ((*ptr)->message));
+ }
+
+ if (-1 != (*ptr)->socket) {
+ int r;
+
+ DPRINT(Debug,12,(&Debug,"free_resolv_process: socket=%d -- clear action\n",
+ (*ptr)->socket));
+
+ /* No longer schedule for this! */
+ clear_action((*ptr)->socket);
+
+ DPRINT(Debug,12,(&Debug,"free_resolv_process: Closing socket %d (to process pid %d)",
+ (*ptr)->socket,(*ptr)->pid));
+
+ r = close((*ptr)->socket);
+ if (-1 == r) {
+ int err UNUSED_VAROK = errno;
+
+ DPRINT(Debug,12,(&Debug,", failed; errno %d (%s)",
+ err,strerror(err)));
+ }
+ DPRINT(Debug,12,(&Debug,"\n"));
+
+ (*ptr)->socket = -1;
+ }
+
+ (*ptr)->magic = 0; /* Invalidate */
+ free(*ptr);
+ *ptr = NULL;
+ }
+
+ static void inc_resolv_process_refcount P_((struct resolv_process *ptr));
+ static void inc_resolv_process_refcount(ptr)
+ struct resolv_process *ptr;
+ {
+ if (RESOLV_PROCESS_magic != ptr->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"inc_resolv_process_refcount",
+ "Bad magic number (resolv_process)",0);
+
+ ptr->refcount++;
+ }
+
+
+
+ #if ANSI_C
+ #define S_(x) static x;
+ #else
+ #define S_(x)
+ #endif
+
+ static int parse_resolv_message1 P_((struct resolv_message * buffer,
+ int * errno_val));
+ static int parse_resolv_message1(buffer,errno_val)
+ struct resolv_message * buffer;
+ int * errno_val;
+ {
+ int ret = 0;
+ int res;
+
+ if (RESOLV_MESSAGE_magic != buffer->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "parse_resolv_message1",
+ "Bad magic number (resolv_message)",0);
+
+ res = ns_initparse(buffer->message,buffer->message_len,
+ & (buffer-> parsed_message));
+
+ if (res < 0) {
+ int err = errno;
+
+ DPRINT(Debug,14,(&Debug,
+ "parse_resolv_message1: ns_initparse() failed, len %u",
+ (unsigned) buffer->message_len));
+
+ if (err) {
+ DPRINT(Debug,14,(&Debug,", errno = %d (%s)",
+ err, strerror(err)));
+ if (errno_val)
+ *errno_val = err;
+ }
+
+ DPRINT(Debug,14,(&Debug,"\n"));
+
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "parse_resolv_message1: ns_initparse() succeed, len %u\n",
+ (unsigned) buffer->message_len));
+ buffer->message_parsed = 1;
+ ret = 1;
+ }
+
+ DPRINT(Debug,14,(&Debug,
+ "parse_resolv_message1=%d",ret));
+ if (errno_val && *errno_val) {
+ DPRINT(Debug,14,(&Debug,
+ "; *errno_val=%d",*errno_val));
+ }
+ DPRINT(Debug,14,(&Debug,"\n"));
+
+ return ret;
+
+ }
+
+ #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
+
+ static int parse_resolv_message P_((struct resolv_message * buffer,
+ const unsigned char answer_buffer[],
+ const size_t answer_buflen,
+ int * errno_val));
+ static int parse_resolv_message(buffer,answer_buffer,answer_buflen,errno_val) + struct resolv_message * buffer;
+ const unsigned char answer_buffer[];
+ const size_t answer_buflen;
+ int * errno_val;
+ {
+ int ret = 0;
+
+ errno = 0;
+ if (errno_val)
+ *errno_val = 0;
+
+ if (RESOLV_MESSAGE_magic != buffer->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ " parse_resolv_message",
+ "Bad magic number (resolv_message)",0);
+
+ if (answer_buflen > 0 && answer_buffer &&
+ answer_buflen <= buffer->message_size &&
+ answer_buflen <= USHRT_MAX &&
+ buffer->message ) {
+
+ memcpy(buffer->message, answer_buffer, answer_buflen);
+ buffer->message_len = answer_buflen;
+
+
+ ret = parse_resolv_message1(buffer,errno_val);
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "parse_resolv_message: len %lu\n",(unsigned long)answer_buflen));
+ if (errno_val)
+ *errno_val = EMSGSIZE;
+
+ }
+
+ return ret;
+ }
+
+ static int same_question_rr P_((ns_rr *rr1, ns_rr *rr2));
+ static int same_question_rr(rr1,rr2)
+ ns_rr *rr1;
+ ns_rr *rr2;
+ {
+ char *name1 = ns_rr_name((*rr1));
+ char *name2 = ns_rr_name((*rr2));
+ ns_class recclass1 = ns_rr_class((*rr1));
+ ns_class recclass2 = ns_rr_class((*rr2));
+ ns_type rectype1 = ns_rr_type((*rr1));
+ ns_type rectype2 = ns_rr_type((*rr2));
+
+ if (! name1 || ! name2) {
+ DPRINT(Debug,14,(&Debug, "same_question_rr: no name\n"));
+ return 0;
+ }
+
+ if (0 != strcmp(name1,name2)) {
+ DPRINT(Debug,14,(&Debug, "same_question_rr: name mismatch: %s <> %s\n", + name1,name2));
+ return 0;
+ }
+
+ if (recclass1 != recclass2) {
+ DPRINT(Debug,14,(&Debug, "same_question_rr: %s: class mismatch: %d <> %d\n",
+ name1,recclass1,recclass2));
+ return 0;
+ }
+
+ if (rectype1 != rectype2) {
+ DPRINT(Debug,14,(&Debug,"same_question_rr: %s: rectype mismatch: %d <> %d\n",
+ name1,rectype1,rectype2));
+ return 0;
+ }
+
+ return 1;
+ }
+
+
+ static void process_answer P_((const int pid,
+ const struct resolv_query_hdr * hdr,
+ const unsigned char answer_buffer[],
+ const size_t answer_buflen, + struct resolv_query_item * qitem));
+ static void process_answer(pid,hdr,answer_buffer,answer_buflen,qitem)
+ const int pid;
+ const struct resolv_query_hdr * hdr;
+ const unsigned char answer_buffer[];
+ const size_t answer_buflen;
+ struct resolv_query_item * qitem;
+ {
+
+ if (RESOLV_QUERY_HDR_magic != hdr->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "process_answer",
+ "Bad magic number (resolv_query_hdr)",0);
+
+ if (qitem) {
+
+ if (RESOLV_QUERY_ITEM_magic != qitem->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"process_answer",
+ "Bad magic number (resolv_query_item)",0);
+
+
+ if (qitem->answer_hdr) {
+ if (RESOLV_QUERY_HDR_magic != qitem->answer_hdr->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "process_answer",
+ "Bad magic number resolv_query_hdr)",0);
+ }
+
+ if (hdr->errno_val) {
+ DPRINT(Debug,14,(&Debug, "process_answer: [pid %d] %lu %s: copying error %d (%s)\n",
+ pid,
+ (unsigned long)(qitem->querynum),
+ qitem->name ? qitem->name : "<NO NAME>",
+ hdr->errno_val,strerror(hdr->errno_val)));
+ qitem->last_errno = hdr->errno_val;
+ }
+
+ if (qitem->answer_buffer) {
+ int err_rmesg = 0;
+ int ok;
+
+ if (RESOLV_MESSAGE_magic != qitem->answer_buffer->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "process_answer",
+ "Bad magic number (resolv_message)",0);
+
+ ok = parse_resolv_message(qitem->answer_buffer,
+ answer_buffer,answer_buflen,&err_rmesg); +
+ if (!ok) {
+ DPRINT(Debug,14,(&Debug, "process_answer: [pid %d] %lu %s: failed to parse message (len %lu)",
+ pid,
+ (unsigned long)(qitem->querynum),
+ qitem->name ? qitem->name : "<NO NAME>",
+ (unsigned long) answer_buflen));
+
+ if (err_rmesg) {
+ DPRINT(Debug,14,(&Debug, ", error %s (errno %d)",
+ strerror(err_rmesg),err_rmesg));
+
+ qitem->last_errno = err_rmesg;
+ }
+
+ DPRINT(Debug,14,(&Debug, "\n"));
+
+ qitem->invalid_answer = 1;
+
+ if (qitem->name) {
+ if (err_rmesg) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookFParseAnswerE,
+ "Looking up %s: Failed to parse answer: %s"),
+ qitem->name,
+ strerror(err_rmesg));
+ } else
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookFParseAnswer,
+ "Looking up %s: Failed to parse answer"),
+ qitem->name);
+
+ qitem->looking_up = l_up_error;
+ }
+
+
+ } else if (qitem->query_buffer) {
+ char * refname = NULL;
+
+ if (RESOLV_MESSAGE_magic != qitem->query_buffer->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "process_answer",
+ "Bad magic number (resolv_message)",0);
+
+ if (ok) {
+ u_int16_t query_id = ns_msg_id(qitem->query_buffer->parsed_message);
+ u_int16_t answer_id = ns_msg_id(qitem->answer_buffer->parsed_message);
+
+ if (query_id != answer_id) {
+
+ DPRINT(Debug,14,(&Debug,
+ "process_answer: [pid %d] %lu %s: query id %d <=> answer id %d\n",
+ pid,
+ (unsigned long)(qitem->querynum),
+ qitem->name ? qitem->name : "<NO NAME>",
+ query_id,answer_id));
+
+ ok = 0;
+ }
+ }
+
+ if (ok) {
+ int count_query_qd = ns_msg_count(qitem->query_buffer->parsed_message,
+ ns_s_qd);
+ int count_answer_qd = ns_msg_count(qitem->answer_buffer->parsed_message,
+ ns_s_qd);
+
+ if (count_query_qd != count_answer_qd) {
+ DPRINT(Debug,14,(&Debug,
+ "process_answer: [pid %d] %lu %s: query %d <=> answer %d records on question section\n",
+ pid,
+ (unsigned long)(qitem->querynum),
+ qitem->name ? qitem->name : "<NO NAME>",
+ count_query_qd,count_answer_qd));
+ ok = 0;
+ } else {
+ int recnum;
+
+ DPRINT(Debug,14,(&Debug,
+ "process_answer: [pid %d] %lu %s: %d records on question section\n",
+ pid,
+ (unsigned long)(qitem->querynum),
+ qitem->name ? qitem->name : "<NO NAME>",
+ count_query_qd));
+
+ for (recnum = 0; recnum < count_query_qd && ok; recnum++) {
+ ns_rr rrquestion;
+ ns_rr rranswer;
+ int res;
+
+ errno = 0;
+ res = ns_parserr(&(qitem->query_buffer->parsed_message),
+ ns_s_qd,recnum,&rrquestion);
+
+ if (res < 0) {
+ int errnum = errno;
+ DPRINT(Debug,14,(&Debug,
+ "process_answer: [pid %d] %lu %s: failed to parse record #%d on question section of query",
+ pid,
+ (unsigned long)(qitem->querynum),
+ qitem->name ? qitem->name : "<NO NAME>",
+ recnum));
+
+ if (errnum) {
+ DPRINT(Debug,14,(&Debug, ", error %s (errno %d)",
+ strerror(errnum),errnum)); + qitem->last_errno = errnum;
+ }
+
+ DPRINT(Debug,14,(&Debug,"\n"));
+ ok = 0;
+ }
+
+ res = ns_parserr(&(qitem->answer_buffer->parsed_message),
+ ns_s_qd,recnum,&rranswer);
+
+ if (res < 0) {
+ int errnum = errno;
+ DPRINT(Debug,14,(&Debug,
+ "process_answer: [pid %d] %lu %s: failed to parse record #%d on question section of answer",
+ pid,
+ (unsigned long)(qitem->querynum),
+ qitem->name ? qitem->name : "<NO NAME>",
+ recnum));
+ if (errnum) {
+ DPRINT(Debug,14,(&Debug, ", error %s (errno %d)",
+ strerror(errnum),errnum)); + qitem->last_errno = errnum;
+ }
+
+ DPRINT(Debug,14,(&Debug,"\n"));
+ ok = 0;
+ }
+
+ if (ok && !same_question_rr(&rrquestion,&rranswer)) {
+ DPRINT(Debug,14,(&Debug,
+ "process_answer: [pid %d] %lu %s: record #%d differ on between question section of query and answer\n",
+ pid,
+ (unsigned long)(qitem->querynum),
+ qitem->name ? qitem->name : "<NO NAME>",
+ recnum));
+ ok = 0;
+ }
+
+ if (ok && 1 == count_query_qd) {
+ const char * X = ns_rr_name(rranswer);
+ if (X) {
+ refname = strmcpy(refname,X);
+ DPRINT(Debug,14,(&Debug,
+ "process_answer: [pid %d] %lu %s: reference name is %s\n",
+ pid,
+ (unsigned long)(qitem->querynum),
+ qitem->name ? qitem->name : "<NO NAME>",
+ refname));
+ }
+ }
+ }
+ }
+ }
+
+ if (ok) {
+ ns_rcode response_code =
+ ns_msg_getflag(qitem->answer_buffer->parsed_message,
+ ns_f_rcode);
+ unsigned short aa =
+ ns_msg_getflag(qitem->answer_buffer->parsed_message,
+ ns_f_aa);
+
+ DPRINT(Debug,14,(&Debug,
+ "process_answer: [pid %d] %lu %s: query name=%s, authorative=%u, response code=%d",
+ pid,
+ (unsigned long)(qitem->querynum),
+ qitem->name ? qitem->name : "<NO NAME>",
+ refname ? refname : "<NO NAME>",
+ (unsigned)aa,
+ response_code));
+ switch (response_code) {
+ case ns_r_noerror: DPRINT(Debug,14,(&Debug," (no error)\n")); break;
+ case ns_r_formerr: DPRINT(Debug,14,(&Debug," (format error)\n"));
+ if (qitem->name) {
+
+ if (refname && 0 != strcmp(qitem->name,refname))
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookFormErrR,
+ "Looking up %s [%s]: format error"),
+ qitem->name,refname);
+ else
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookFormErr,
+ "Looking up %s: format error"),
+ qitem->name);
+ qitem->looking_up = l_up_error;
+ } else if (refname) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookFormErr,
+ "Looking up %s: format error"),
+ refname);
+ qitem->looking_up = l_up_error;
+ }
+
+ qitem->fill_have_error = 1;
+ break;
+ case ns_r_servfail: DPRINT(Debug,14,(&Debug," (server failure)\n"));
+ if (qitem->name) {
+ if (refname && 0 != strcmp(qitem->name,refname))
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookServFailR,
+ "Looking up %s [%s]: server failure"),
+ qitem->name,refname);
+ else
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookServFail,
+ "Looking up %s: server failure"),
+ qitem->name);
+ qitem->looking_up = l_up_error;
+ } else if (refname) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookServFail,
+ "Looking up %s: server failure"), + refname);
+ qitem->looking_up = l_up_error;
+ }
+ break;
+ case ns_r_nxdomain: DPRINT(Debug,14,(&Debug," (name error)"));
+
+ if (qitem->is_search) {
+ DPRINT(Debug,14,(&Debug," -- using search list for name, do not print error yet.\n"));
+ qitem->transient_error = 1;
+ } else {
+ DPRINT(Debug,14,(&Debug,"\n"));
+ if (aa) {
+ if (qitem->name) {
+ if (refname && 0 != strcmp(qitem->name,refname))
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookNotFoundR, + "Looking up %s [%s]: not found"),
+ qitem->name,refname);
+ else
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookNotFound,
+ "Looking up %s: not found"),
+ qitem->name);
+ qitem->looking_up = l_up_error;
+ } else if (refname) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookNotFound,
+ "Looking up %s: not found"),
+ refname);
+ qitem->looking_up = l_up_error;
+ }
+ } else {
+ if (qitem->name) {
+ if (refname && 0 != strcmp(qitem->name,refname))
+ lib_transient(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookTryAgainR,
+ "Looking up %s [%s]: not found yet"),
+ qitem->name,refname);
+ else
+ lib_transient(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookTryAgain,
+ "Looking up %s: not found yet"),
+ qitem->name);
+ qitem->looking_up = l_up_error;
+ } else if (refname) {
+ lib_transient(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookTryAgain,
+ "Looking up %s: not found yet"),
+ refname);
+ }
+ qitem->fill_have_error = 1;
+ }
+ }
+ break;
+ case ns_r_notimpl: DPRINT(Debug,14,(&Debug," (unimplemented)\n"));
+ if (qitem->name) {
+ if (refname && 0 != strcmp(qitem->name,refname))
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookNotImplR,
+ "Looking up %s [%s]: not implemented"),
+ qitem->name,refname);
+ else
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookNotImpl,
+ "Looking up %s: not implemented"),
+ qitem->name);
+ qitem->looking_up = l_up_error;
+ } else if (refname) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookNotImpl,
+ "Looking up %s: not implemented"),
+ refname);
+ qitem->looking_up = l_up_error;
+ }
+
+ qitem->fill_have_error = 1;
+ break;
+ case ns_r_refused: DPRINT(Debug,14,(&Debug," (operation refused)\n"));
+ if (qitem->name) {
+ if (refname && 0 != strcmp(qitem->name,refname))
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookOpRefR,
+ "Looking up %s [%s]: operation refused"),
+ qitem->name,refname);
+ else
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookOpRef,
+ "Looking up %s: operation refused"),
+ qitem->name);
+ qitem->looking_up = l_up_error;
+ } else if (refname) {
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvLookOpRef,
+ "Looking up %s: operation refused"),
+ refname);
+ qitem->looking_up = l_up_error;
+ }
+
+ qitem->fill_have_error = 1;
+ break;
+ default: DPRINT(Debug,14,(&Debug,"\n")); break;
+ }
+
+ if (!qitem->answer_hdr)
+ qitem->answer_hdr = safe_malloc(sizeof (* (qitem->answer_hdr)));
+ * (qitem->answer_hdr) = *hdr;
+
+ if (qitem->cache_answer_ret) {
+ DPRINT(Debug,14,(&Debug,
+ "process_answer: [pid %d] %lu %s: clearing previous answer\n",
+ pid,
+ (unsigned long)(qitem->querynum),
+ qitem->name ? qitem->name : "<NO NAME>"));
+ free_resolv_cache(& (qitem->cache_answer_ret));
+ }
+
+ if (ns_r_noerror == response_code) {
+ int anscount = ns_msg_count(qitem->answer_buffer->parsed_message,
+ ns_s_an);
+
+ if (!anscount) {
+ DPRINT(Debug,14,(&Debug,
+ "process_answer: [pid %d] %lu %s: Didn't got answer but name found\n",
+ pid,
+ (unsigned long)(qitem->querynum), + qitem->name ? qitem->name : "<NO NAME>"));
+ qitem->other = 1;
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "process_answer: [pid %d] %lu %s: %d recors on answer section\n",
+ pid,
+ (unsigned long)(qitem->querynum), + qitem->name ? qitem->name : "<NO NAME>",
+ anscount));
[continued in next message]
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)