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

Diff Legend

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