ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/irc_res.c
(Generate patch)

Comparing:
ircd-hybrid/src/irc_res.c (file contents), Revision 33 by knight, Sun Oct 2 20:50:00 2005 UTC vs.
ircd-hybrid/trunk/src/irc_res.c (file contents), Revision 1654 by michael, Fri Nov 16 19:39:37 2012 UTC

# Line 20 | Line 20
20   */
21  
22   #include "stdinc.h"
23 #include "tools.h"
24 #include "client.h"
23   #include "list.h"
24 < #include "common.h"
24 > #include "client.h"
25   #include "event.h"
26   #include "irc_string.h"
27   #include "sprintf_irc.h"
28   #include "ircd.h"
29   #include "numeric.h"
30 < #include "restart.h"
30 > #include "rng_mt.h"
31   #include "fdlist.h"
34 #include "fileio.h" /* for fbopen / fbclose / fbputs */
32   #include "s_bsd.h"
33 < #include "s_log.h"
33 > #include "log.h"
34 > #include "s_misc.h"
35   #include "send.h"
36   #include "memory.h"
37 + #include "mempool.h"
38   #include "irc_res.h"
39   #include "irc_reslib.h"
41 #include "irc_getnameinfo.h"
40  
41   #if (CHAR_BIT != 8)
42   #error this code needs to be able to address individual octets
# Line 69 | Line 67 | typedef enum
67   #ifdef IPV6
68    REQ_AAAA,  /* Looking up an AAAA */
69   #endif
70 <  REQ_CNAME, /* We got a CNAME in response, we better get a real answer next */
73 <  REQ_INT    /* ip6.arpa failed, falling back to ip6.int */
70 >  REQ_CNAME  /* We got a CNAME in response, we better get a real answer next */
71   } request_state;
72  
73   struct reslist
# Line 88 | Line 85 | struct reslist
85    time_t timeout;
86    struct irc_ssaddr addr;
87    char *name;
88 <  struct DNSQuery *query;  /* query callback for this request */
88 >  dns_callback_fnc callback;
89 >  void *callback_ctx;
90   };
91  
92   static fde_t ResolverFileDescriptor;
93 < static dlink_list request_list    = { NULL, NULL, 0 };
93 > static dlink_list request_list = { NULL, NULL, 0 };
94 > static mp_pool_t *dns_pool = NULL;
95  
96 < static void rem_request(struct reslist *request);
97 < static struct reslist *make_request(struct DNSQuery *query);
98 < static void do_query_name(struct DNSQuery *query,
99 <                          const char* name, struct reslist *request, int);
100 < static void do_query_number(struct DNSQuery *query,
96 > static void rem_request(struct reslist *);
97 > static struct reslist *make_request(dns_callback_fnc, void *);
98 > static void do_query_name(dns_callback_fnc, void *,
99 >                          const char *, struct reslist *, int);
100 > static void do_query_number(dns_callback_fnc, void *,
101                              const struct irc_ssaddr *,
102 <                            struct reslist *request);
103 < static void query_name(const char *name, int query_class, int query_type,
104 <                       struct reslist *request);
105 < static int send_res_msg(const char *buf, int len, int count);
106 < static void resend_query(struct reslist *request);
107 < static int proc_answer(struct reslist *request, HEADER *header, char *, char *);
109 < static struct reslist *find_id(int id);
110 < static struct DNSReply *make_dnsreply(struct reslist *request);
111 <
112 < extern struct irc_ssaddr irc_nsaddr_list[IRCD_MAXNS];
113 < extern int irc_nscount;
114 < extern char irc_domain[HOSTLEN+1];
102 >                            struct reslist *);
103 > static void query_name(const char *, int, int, struct reslist *);
104 > static int send_res_msg(const char *, int, int);
105 > static void resend_query(struct reslist *);
106 > static int proc_answer(struct reslist *, HEADER *, char *, char *);
107 > static struct reslist *find_id(int);
108  
109  
110   /*
# Line 129 | Line 122 | static int
122   res_ourserver(const struct irc_ssaddr *inp)
123   {
124   #ifdef IPV6
125 <  struct sockaddr_in6 *v6;
126 <  struct sockaddr_in6 *v6in = (struct sockaddr_in6 *)inp;
125 >  const struct sockaddr_in6 *v6;
126 >  const struct sockaddr_in6 *v6in = (const struct sockaddr_in6 *)inp;
127   #endif
128 <  struct sockaddr_in *v4;
129 <  struct sockaddr_in *v4in = (struct sockaddr_in *)inp;
128 >  const struct sockaddr_in *v4;
129 >  const struct sockaddr_in *v4in = (const struct sockaddr_in *)inp;
130    int ns;
131  
132 <  for (ns = 0;  ns < irc_nscount;  ns++)
132 >  for (ns = 0; ns < irc_nscount; ++ns)
133    {
134      const struct irc_ssaddr *srv = &irc_nsaddr_list[ns];
135   #ifdef IPV6
136 <    v6 = (struct sockaddr_in6 *)srv;
136 >    v6 = (const struct sockaddr_in6 *)srv;
137   #endif
138 <    v4 = (struct sockaddr_in *)srv;
138 >    v4 = (const struct sockaddr_in *)srv;
139  
140      /* could probably just memcmp(srv, inp, srv.ss_len) here
141       * but we'll air on the side of caution - stu
# Line 154 | Line 147 | res_ourserver(const struct irc_ssaddr *i
147        case AF_INET6:
148          if (srv->ss.ss_family == inp->ss.ss_family)
149            if (v6->sin6_port == v6in->sin6_port)
150 <            if ((memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr,
151 <                    sizeof(struct in6_addr)) == 0) ||
152 <                (memcmp(&v6->sin6_addr.s6_addr, &in6addr_any,
160 <                        sizeof(struct in6_addr)) == 0))
161 <              return(1);
150 >            if (!memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr,
151 >                        sizeof(struct in6_addr)))
152 >              return 1;
153          break;
154   #endif
155        case AF_INET:
156          if (srv->ss.ss_family == inp->ss.ss_family)
157            if (v4->sin_port == v4in->sin_port)
158 <            if ((v4->sin_addr.s_addr == INADDR_ANY) ||
159 <                (v4->sin_addr.s_addr == v4in->sin_addr.s_addr))
169 <              return(1);
158 >            if (v4->sin_addr.s_addr == v4in->sin_addr.s_addr)
159 >              return 1;
160          break;
161        default:
162          break;
163      }
164    }
165  
166 <  return(0);
166 >  return 0;
167   }
168  
169   /*
# Line 198 | Line 188 | timeout_query_list(time_t now)
188      {
189        if (--request->retries <= 0)
190        {
191 <        (*request->query->callback)(request->query->ptr, NULL);
191 >        (*request->callback)(request->callback_ctx, NULL, NULL);
192          rem_request(request);
193          continue;
194        }
# Line 211 | Line 201 | timeout_query_list(time_t now)
201      }
202  
203      if ((next_time == 0) || timeout < next_time)
214    {
204        next_time = timeout;
216    }
205    }
206  
207 <  return((next_time > now) ? next_time : (now + AR_TTL));
207 >  return (next_time > now) ? next_time : (now + AR_TTL);
208   }
209  
210   /*
# Line 256 | Line 244 | start_resolver(void)
244   void
245   init_resolver(void)
246   {
247 < #ifdef HAVE_SRAND48
260 <  srand48(CurrentTime);
261 < #endif
247 >  dns_pool = mp_pool_new(sizeof(struct reslist), MP_CHUNK_SIZE_DNS);
248    memset(&ResolverFileDescriptor, 0, sizeof(fde_t));
249    start_resolver();
250   }
# Line 275 | Line 261 | restart_resolver(void)
261   }
262  
263   /*
278 * add_local_domain - Add the domain to hostname, if it is missing
279 * (as suggested by eps@TOASTER.SFSU.EDU)
280 */
281 void
282 add_local_domain(char *hname, size_t size)
283 {
284  /* try to fix up unqualified names
285   */
286  if (strchr(hname, '.') == NULL)
287  {
288    if (irc_domain[0])
289    {
290      size_t len = strlen(hname);
291
292      if ((strlen(irc_domain) + len + 2) < size)
293      {
294        hname[len++] = '.';
295        strcpy(hname + len, irc_domain);
296      }
297    }
298  }
299 }
300
301 /*
264   * rem_request - remove a request from the list.
265   * This must also free any memory that has been allocated for
266   * temporary storage of DNS results.
# Line 307 | Line 269 | static void
269   rem_request(struct reslist *request)
270   {
271    dlinkDelete(&request->node, &request_list);
272 +
273    MyFree(request->name);
274 <  MyFree(request);
274 >  mp_pool_release(request);
275   }
276  
277   /*
278   * make_request - Create a DNS request record for the server.
279   */
280   static struct reslist *
281 < make_request(struct DNSQuery* query)
281 > make_request(dns_callback_fnc callback, void *ctx)
282   {
283 <  struct reslist *request;
283 >  struct reslist *request = mp_pool_get(dns_pool);
284  
285 <  request = (struct reslist *)MyMalloc(sizeof(struct reslist));
286 <  memset(request, 0, sizeof(struct reslist));
287 <
288 <  request->sentat  = CurrentTime;
289 <  request->retries = 3;
290 <  request->resend  = 1;
291 <  request->timeout = 4;    /* start at 4 and exponential inc. */
292 <  memset(&request->addr, 0, sizeof(request->addr));
330 <  request->query   = query;
331 <  request->state   = REQ_IDLE;
285 >  memset(request, 0, sizeof(*request));
286 >  request->sentat       = CurrentTime;
287 >  request->retries      = 3;
288 >  request->resend       = 1;
289 >  request->timeout      = 4;    /* start at 4 and exponential inc. */
290 >  request->state        = REQ_IDLE;
291 >  request->callback     = callback;
292 >  request->callback_ctx = ctx;
293  
294    dlinkAdd(request, &request->node, &request_list);
295 <  return(request);
295 >  return request;
296   }
297  
298   /*
# Line 339 | Line 300 | make_request(struct DNSQuery* query)
300   * for which there no longer exist clients or conf lines.
301   */
302   void
303 < delete_resolver_queries(const struct DNSQuery *query)
303 > delete_resolver_queries(const void *vptr)
304   {
305 <  dlink_node *ptr;
345 <  dlink_node *next_ptr;
346 <  struct reslist *request;
305 >  dlink_node *ptr = NULL, *next_ptr = NULL;
306  
307    DLINK_FOREACH_SAFE(ptr, next_ptr, request_list.head)
308    {
309 <    if ((request = ptr->data) != NULL)
310 <    {
311 <      if (query == request->query)
312 <        rem_request(request);
354 <    }
309 >    struct reslist *request = ptr->data;
310 >
311 >    if (request->callback_ctx == vptr)
312 >      rem_request(request);
313    }
314   }
315  
# Line 383 | Line 341 | send_res_msg(const char *msg, int len, i
341        ++sent;
342    }
343  
344 <  return(sent);
344 >  return sent;
345   }
346  
347   /*
# Line 392 | Line 350 | send_res_msg(const char *msg, int len, i
350   static struct reslist *
351   find_id(int id)
352   {
353 <  dlink_node *ptr;
396 <  struct reslist *request;
353 >  dlink_node *ptr = NULL;
354  
355    DLINK_FOREACH(ptr, request_list.head)
356    {
357 <    request = ptr->data;
357 >    struct reslist *request = ptr->data;
358  
359      if (request->id == id)
360 <      return(request);
360 >      return request;
361    }
362  
363 <  return(NULL);
363 >  return NULL;
364   }
365  
366   /*
# Line 411 | Line 368 | find_id(int id)
368   *
369   */
370   void
371 < gethost_byname_type(const char *name, struct DNSQuery *query, int type)
371 > gethost_byname_type(dns_callback_fnc callback, void *ctx, const char *name, int type)
372   {
373 <  assert(name != 0);
374 <  do_query_name(query, name, NULL, type);
373 >  assert(name != NULL);
374 >  do_query_name(callback, ctx, name, NULL, type);
375   }
376  
377   /*
378   * gethost_byname - wrapper for _type - send T_AAAA first if IPV6 supported
379   */
380   void
381 < gethost_byname(const char *name, struct DNSQuery *query)
381 > gethost_byname(dns_callback_fnc callback, void *ctx, const char *name)
382   {
383   #ifdef IPV6
384 <  gethost_byname_type(name, query, T_AAAA);
384 >  gethost_byname_type(callback, ctx, name, T_AAAA);
385   #else
386 <  gethost_byname_type(name, query, T_A);
386 >  gethost_byname_type(callback, ctx, name, T_A);
387   #endif
388   }
389  
# Line 434 | Line 391 | gethost_byname(const char *name, struct
391   * gethost_byaddr - get host name from address
392   */
393   void
394 < gethost_byaddr(const struct irc_ssaddr *addr, struct DNSQuery *query)
394 > gethost_byaddr(dns_callback_fnc callback, void *ctx, const struct irc_ssaddr *addr)
395   {
396 <  do_query_number(query, addr, NULL);
396 >  do_query_number(callback, ctx, addr, NULL);
397   }
398  
399   /*
400   * do_query_name - nameserver lookup name
401   */
402   static void
403 < do_query_name(struct DNSQuery *query, const char *name,
403 > do_query_name(dns_callback_fnc callback, void *ctx, const char *name,
404                struct reslist *request, int type)
405   {
406    char host_name[HOSTLEN + 1];
407  
408 <  strlcpy(host_name, name, HOSTLEN);
452 <  add_local_domain(host_name, HOSTLEN);
408 >  strlcpy(host_name, name, sizeof(host_name));
409  
410    if (request == NULL)
411    {
412 <    request       = make_request(query);
413 <    request->name = (char *)MyMalloc(strlen(host_name) + 1);
412 >    request       = make_request(callback, ctx);
413 >    request->name = MyMalloc(strlen(host_name) + 1);
414      request->type = type;
415      strcpy(request->name, host_name);
416   #ifdef IPV6
417 <    if (type == T_A)
462 <      request->state = REQ_A;
463 <    else
417 >    if (type != T_A)
418        request->state = REQ_AAAA;
419 < #else
466 <    request->state = REQ_A;
419 >    else
420   #endif
421 +    request->state = REQ_A;
422    }
423  
424    request->type = type;
# Line 475 | Line 429 | do_query_name(struct DNSQuery *query, co
429   * do_query_number - Use this to do reverse IP# lookups.
430   */
431   static void
432 < do_query_number(struct DNSQuery *query, const struct irc_ssaddr *addr,
432 > do_query_number(dns_callback_fnc callback, void *ctx,
433 >                const struct irc_ssaddr *addr,
434                  struct reslist *request)
435   {
436    char ipbuf[128];
437    const unsigned char *cp;
438 < #ifdef IPV6
484 <  const char *intarpa;
485 < #endif
438 >
439    if (addr->ss.ss_family == AF_INET)
440    {
441 <    struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
442 <    cp = (const unsigned char*)&v4->sin_addr.s_addr;
441 >    const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
442 >    cp = (const unsigned char *)&v4->sin_addr.s_addr;
443  
444 <    ircsprintf(ipbuf, "%u.%u.%u.%u.in-addr.arpa.",
445 <               (unsigned int)(cp[3]), (unsigned int)(cp[2]),
446 <               (unsigned int)(cp[1]), (unsigned int)(cp[0]));
444 >    snprintf(ipbuf, sizeof(ipbuf), "%u.%u.%u.%u.in-addr.arpa.",
445 >             (unsigned int)(cp[3]), (unsigned int)(cp[2]),
446 >             (unsigned int)(cp[1]), (unsigned int)(cp[0]));
447    }
448   #ifdef IPV6
449    else if (addr->ss.ss_family == AF_INET6)
450    {
451 <    struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
451 >    const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
452      cp = (const unsigned char *)&v6->sin6_addr.s6_addr;
453  
454 <    if (request != NULL && request->state == REQ_INT)
455 <      intarpa = "int";
456 <    else
457 <      intarpa = "arpa";
458 <
459 <    (void)sprintf(ipbuf, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
460 <                  "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.%s.",
461 <                  (unsigned int)(cp[15]&0xf), (unsigned int)(cp[15]>>4),
462 <                  (unsigned int)(cp[14]&0xf), (unsigned int)(cp[14]>>4),
463 <                  (unsigned int)(cp[13]&0xf), (unsigned int)(cp[13]>>4),
464 <                  (unsigned int)(cp[12]&0xf), (unsigned int)(cp[12]>>4),
465 <                  (unsigned int)(cp[11]&0xf), (unsigned int)(cp[11]>>4),
466 <                  (unsigned int)(cp[10]&0xf), (unsigned int)(cp[10]>>4),
467 <                  (unsigned int)(cp[9]&0xf), (unsigned int)(cp[9]>>4),
468 <                  (unsigned int)(cp[8]&0xf), (unsigned int)(cp[8]>>4),
469 <                  (unsigned int)(cp[7]&0xf), (unsigned int)(cp[7]>>4),
470 <                  (unsigned int)(cp[6]&0xf), (unsigned int)(cp[6]>>4),
471 <                  (unsigned int)(cp[5]&0xf), (unsigned int)(cp[5]>>4),
472 <                  (unsigned int)(cp[4]&0xf), (unsigned int)(cp[4]>>4),
520 <                  (unsigned int)(cp[3]&0xf), (unsigned int)(cp[3]>>4),
521 <                  (unsigned int)(cp[2]&0xf), (unsigned int)(cp[2]>>4),
522 <                  (unsigned int)(cp[1]&0xf), (unsigned int)(cp[1]>>4),
523 <                  (unsigned int)(cp[0]&0xf), (unsigned int)(cp[0]>>4), intarpa);
454 >    snprintf(ipbuf, sizeof(ipbuf),
455 >             "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
456 >             "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa.",
457 >             (unsigned int)(cp[15] & 0xf), (unsigned int)(cp[15] >> 4),
458 >             (unsigned int)(cp[14] & 0xf), (unsigned int)(cp[14] >> 4),
459 >             (unsigned int)(cp[13] & 0xf), (unsigned int)(cp[13] >> 4),
460 >             (unsigned int)(cp[12] & 0xf), (unsigned int)(cp[12] >> 4),
461 >             (unsigned int)(cp[11] & 0xf), (unsigned int)(cp[11] >> 4),
462 >             (unsigned int)(cp[10] & 0xf), (unsigned int)(cp[10] >> 4),
463 >             (unsigned int)(cp[9] & 0xf), (unsigned int)(cp[9] >> 4),
464 >             (unsigned int)(cp[8] & 0xf), (unsigned int)(cp[8] >> 4),
465 >             (unsigned int)(cp[7] & 0xf), (unsigned int)(cp[7] >> 4),
466 >             (unsigned int)(cp[6] & 0xf), (unsigned int)(cp[6] >> 4),
467 >             (unsigned int)(cp[5] & 0xf), (unsigned int)(cp[5] >> 4),
468 >             (unsigned int)(cp[4] & 0xf), (unsigned int)(cp[4] >> 4),
469 >             (unsigned int)(cp[3] & 0xf), (unsigned int)(cp[3] >> 4),
470 >             (unsigned int)(cp[2] & 0xf), (unsigned int)(cp[2] >> 4),
471 >             (unsigned int)(cp[1] & 0xf), (unsigned int)(cp[1] >> 4),
472 >             (unsigned int)(cp[0] & 0xf), (unsigned int)(cp[0] >> 4));
473    }
474   #endif
475    if (request == NULL)
476    {
477 <    request       = make_request(query);
477 >    request       = make_request(callback, ctx);
478      request->type = T_PTR;
479      memcpy(&request->addr, addr, sizeof(struct irc_ssaddr));
480 <    request->name = (char *)MyMalloc(HOSTLEN + 1);
480 >    request->name = MyMalloc(HOSTLEN + 1);
481    }
482  
483    query_name(ipbuf, C_IN, T_PTR, request);
# Line 550 | Line 499 | query_name(const char *name, int query_c
499        (unsigned char *)buf, sizeof(buf))) > 0)
500    {
501      HEADER *header = (HEADER *)buf;
502 < #ifndef HAVE_LRAND48
554 <    int k = 0;
555 <    struct timeval tv;
556 < #endif
502 >
503      /*
504       * generate an unique id
505       * NOTE: we don't have to worry about converting this to and from
506       * network byte order, the nameserver does not interpret this value
507       * and returns it unchanged
508       */
563 #ifdef HAVE_LRAND48
564    do
565    {
566      header->id = (header->id + lrand48()) & 0xffff;
567    } while (find_id(header->id));
568 #else
569    gettimeofday(&tv, NULL);
509      do
510 <    {
511 <      header->id = (header->id + k + tv.tv_usec) & 0xffff;
512 <      k++;
574 <    } while (find_id(header->id));
575 < #endif /* HAVE_LRAND48 */
510 >      header->id = (header->id + genrand_int32()) & 0xffff;
511 >    while (find_id(header->id));
512 >
513      request->id = header->id;
514      ++request->sends;
515  
# Line 586 | Line 523 | resend_query(struct reslist *request)
523    if (request->resend == 0)
524      return;
525  
526 <  switch(request->type)
526 >  switch (request->type)
527    {
528      case T_PTR:
529 <      do_query_number(NULL, &request->addr, request);
529 >      do_query_number(NULL, NULL, &request->addr, request);
530        break;
531      case T_A:
532 <      do_query_name(NULL, request->name, request, request->type);
532 >      do_query_name(NULL, NULL, request->name, request, request->type);
533        break;
534   #ifdef IPV6
535      case T_AAAA:
536        /* didnt work, try A */
537        if (request->state == REQ_AAAA)
538 <        do_query_name(NULL, request->name, request, T_A);
538 >        do_query_name(NULL, NULL, request->name, request, T_A);
539   #endif
540      default:
541        break;
# Line 609 | Line 546 | resend_query(struct reslist *request)
546   * proc_answer - process name server reply
547   */
548   static int
549 < proc_answer(struct reslist *request, HEADER* header, char* buf, char* eob)
549 > proc_answer(struct reslist *request, HEADER *header, char *buf, char *eob)
550   {
551    char hostbuf[HOSTLEN + 100]; /* working buffer */
552    unsigned char *current;      /* current position in buf */
# Line 628 | Line 565 | proc_answer(struct reslist *request, HEA
565      if ((n = irc_dn_skipname(current, (unsigned char *)eob)) < 0)
566        break;
567  
568 <    current += (size_t) n + QFIXEDSZ;
568 >    current += (size_t)n + QFIXEDSZ;
569    }
570  
571    /*
# Line 641 | Line 578 | proc_answer(struct reslist *request, HEA
578      n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current,
579          hostbuf, sizeof(hostbuf));
580  
581 <    if (n < 0)
582 <    {
646 <      /*
647 <       * broken message
648 <       */
649 <      return(0);
650 <    }
651 <    else if (n == 0)
652 <    {
653 <      /*
654 <       * no more answers left
655 <       */
656 <      return(0);
657 <    }
581 >    if (n < 0 /* broken message */ || n == 0 /* no more answers left */)
582 >      return 0;
583  
584      hostbuf[HOSTLEN] = '\0';
585  
# Line 686 | Line 611 | proc_answer(struct reslist *request, HEA
611      {
612        case T_A:
613          if (request->type != T_A)
614 <          return(0);
614 >          return 0;
615  
616          /*
617           * check for invalid rd_length or too many addresses
618           */
619          if (rd_length != sizeof(struct in_addr))
620 <          return(0);
620 >          return 0;
621 >
622          v4 = (struct sockaddr_in *)&request->addr;
623          request->addr.ss_len = sizeof(struct sockaddr_in);
624          v4->sin_family = AF_INET;
625          memcpy(&v4->sin_addr, current, sizeof(struct in_addr));
626 <        return(1);
626 >        return 1;
627          break;
628   #ifdef IPV6
629        case T_AAAA:
630          if (request->type != T_AAAA)
631 <          return(0);
631 >          return 0;
632 >
633          if (rd_length != sizeof(struct in6_addr))
634 <          return(0);
634 >          return 0;
635 >
636          request->addr.ss_len = sizeof(struct sockaddr_in6);
637          v6 = (struct sockaddr_in6 *)&request->addr;
638          v6->sin6_family = AF_INET6;
639          memcpy(&v6->sin6_addr, current, sizeof(struct in6_addr));
640 <        return(1);
640 >        return 1;
641          break;
642   #endif
643        case T_PTR:
644          if (request->type != T_PTR)
645 <          return(0);
645 >          return 0;
646 >
647          n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob,
648              current, hostbuf, sizeof(hostbuf));
649 <        if (n < 0)
650 <          return(0); /* broken message */
722 <        else if (n == 0)
723 <          return(0); /* no more answers left */
724 <
725 <        strlcpy(request->name, hostbuf, HOSTLEN);
649 >        if (n < 0 /* broken message */ || n == 0 /* no more answers left */)
650 >          return 0;
651  
652 <        return(1);
652 >        strlcpy(request->name, hostbuf, HOSTLEN + 1);
653 >        return 1;
654          break;
655        case T_CNAME: /* first check we already havent started looking
656                         into a cname */
657          if (request->type != T_PTR)
658 <          return(0);
658 >          return 0;
659  
660          if (request->state == REQ_CNAME)
661          {
# Line 737 | Line 663 | proc_answer(struct reslist *request, HEA
663                              current, hostbuf, sizeof(hostbuf));
664  
665            if (n < 0)
666 <            return(0);
667 <          return(1);
666 >            return 0;
667 >          return 1;
668          }
669  
670          request->state = REQ_CNAME;
# Line 750 | Line 676 | proc_answer(struct reslist *request, HEA
676           * but its possible its just a broken nameserver with still
677           * valid answers. But lets do some rudimentary logging for now...
678           */
679 <        ilog(L_ERROR, "irc_res.c bogus type %d", type);
679 >        ilog(LOG_TYPE_IRCD, "irc_res.c bogus type %d", type);
680          break;
681      }
682    }
683  
684 <  return(1);
684 >  return 1;
685   }
686  
687   /*
# Line 764 | Line 690 | proc_answer(struct reslist *request, HEA
690   static void
691   res_readreply(fde_t *fd, void *data)
692   {
693 <  char buf[sizeof(HEADER) + MAXPACKET];
693 >  char buf[sizeof(HEADER) + MAXPACKET]
694 >        /* Sparc and alpha need 16bit-alignment for accessing header->id
695 >         * (which is uint16_t). Because of the header = (HEADER*) buf;
696 >         * lateron, this is neeeded. --FaUl
697 >         */
698 > #if defined(__sparc__) || defined(__alpha__)  
699 >          __attribute__((aligned (16)))
700 > #endif
701 >          ;
702    HEADER *header;
703    struct reslist *request = NULL;
770  struct DNSReply *reply  = NULL;
704    int rc;
772  int answer_count;
705    socklen_t len = sizeof(struct irc_ssaddr);
706    struct irc_ssaddr lsin;
707  
# Line 779 | Line 711 | res_readreply(fde_t *fd, void *data)
711     * interest where it'll instantly be ready for read :-) -- adrian
712     */
713    comm_setselect(fd, COMM_SELECT_READ, res_readreply, NULL, 0);
714 +
715    /* Better to cast the sizeof instead of rc */
716    if (rc <= (int)(sizeof(HEADER)))
717      return;
# Line 793 | Line 726 | res_readreply(fde_t *fd, void *data)
726    header->arcount = ntohs(header->arcount);
727  
728    /*
729 <   * response for an id which we have already received an answer for
797 <   * just ignore this response.
729 >   * check against possibly fake replies
730     */
731 <  if (0 == (request = find_id(header->id)))
731 >  if (!res_ourserver(&lsin))
732      return;
733  
734    /*
735 <   * check against possibly fake replies
735 >   * response for an id which we have already received an answer for
736 >   * just ignore this response.
737     */
738 <  if (!res_ourserver(&lsin))
738 >  if (!(request = find_id(header->id)))
739      return;
740  
741    if ((header->rcode != NO_ERRORS) || (header->ancount == 0))
742    {
743 <    if (SERVFAIL == header->rcode)
744 <      resend_query(request);
743 >    if (header->rcode == SERVFAIL || header->rcode == NXDOMAIN)
744 >    {
745 >      /*
746 >       * If a bad error was returned, stop here and don't
747 >       * send any more (no retries granted).
748 >       */
749 >      (*request->callback)(request->callback_ctx, NULL, NULL);
750 >      rem_request(request);
751 >    }
752 > #ifdef IPV6
753      else
754      {
755        /*
756         * If we havent already tried this, and we're looking up AAAA, try A
757         * now
758         */
818
819 #ifdef IPV6
759        if (request->state == REQ_AAAA && request->type == T_AAAA)
760        {
761          request->timeout += 4;
762          resend_query(request);
763        }
825      else if (request->type == T_PTR && request->state != REQ_INT &&
826               request->addr.ss.ss_family == AF_INET6)
827      {
828        request->state = REQ_INT;
829        request->timeout += 4;
830        request->retries--;
831        resend_query(request);
832      }
833      else
834 #endif
835      {
836        /*
837         * If a bad error was returned, we stop here and dont send
838         * send any more (no retries granted).
839         */
840        (*request->query->callback)(request->query->ptr, NULL);
841        rem_request(request);
842      }
764      }
765 + #endif
766  
767      return;
768    }
769 +
770    /*
771     * If this fails there was an error decoding the received packet,
772     * try it again and hope it works the next time.
773     */
774 <  answer_count = proc_answer(request, header, buf, buf + rc);
852 <
853 <  if (answer_count)
774 >  if (proc_answer(request, header, buf, buf + rc))
775    {
776      if (request->type == T_PTR)
777      {
# Line 860 | Line 781 | res_readreply(fde_t *fd, void *data)
781           * got a PTR response with no name, something bogus is happening
782           * don't bother trying again, the client address doesn't resolve
783           */
784 <        (*request->query->callback)(request->query->ptr, reply);
784 >        (*request->callback)(request->callback_ctx, NULL, NULL);
785          rem_request(request);
786          return;
787        }
# Line 872 | Line 793 | res_readreply(fde_t *fd, void *data)
793         */
794   #ifdef IPV6
795        if (request->addr.ss.ss_family == AF_INET6)
796 <        gethost_byname_type(request->name, request->query, T_AAAA);
796 >        gethost_byname_type(request->callback, request->callback_ctx, request->name, T_AAAA);
797        else
798   #endif
799 <      gethost_byname_type(request->name, request->query, T_A);
799 >      gethost_byname_type(request->callback, request->callback_ctx, request->name, T_A);
800        rem_request(request);
801      }
802      else
# Line 883 | Line 804 | res_readreply(fde_t *fd, void *data)
804        /*
805         * got a name and address response, client resolved
806         */
807 <      reply = make_dnsreply(request);
887 <      (*request->query->callback)(request->query->ptr, reply);
888 <      MyFree(reply);
807 >      (*request->callback)(request->callback_ctx, &request->addr, request->name);
808        rem_request(request);
809      }
810    }
# Line 901 | Line 820 | res_readreply(fde_t *fd, void *data)
820    }
821   }
822  
904 static struct DNSReply *
905 make_dnsreply(struct reslist *request)
906 {
907  struct DNSReply *cp;
908  assert(request != 0);
909
910  cp = (struct DNSReply *)MyMalloc(sizeof(struct DNSReply));
911
912  cp->h_name = request->name;
913  memcpy(&cp->addr, &request->addr, sizeof(cp->addr));
914  return(cp);
915 }
916
823   void
824   report_dns_servers(struct Client *source_p)
825   {
826    int i;
827 <  char ipaddr[HOSTIPLEN];
827 >  char ipaddr[HOSTIPLEN + 1];
828  
829    for (i = 0; i < irc_nscount; i++)
830    {
831 <    irc_getnameinfo((struct sockaddr *)&(irc_nsaddr_list[i]),
832 <                    irc_nsaddr_list[i].ss_len, ipaddr, HOSTIPLEN, NULL, 0,
833 <                    NI_NUMERICHOST);
831 >    getnameinfo((struct sockaddr *)&(irc_nsaddr_list[i]),
832 >                irc_nsaddr_list[i].ss_len, ipaddr,
833 >                sizeof(ipaddr), NULL, 0, NI_NUMERICHOST);
834      sendto_one(source_p, form_str(RPL_STATSALINE),
835                 me.name, source_p->name, ipaddr);
836    }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)