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 992 by michael, Mon Aug 17 19:19:16 2009 UTC vs.
ircd-hybrid-8/src/irc_res.c (file contents), Revision 1346 by michael, Mon Apr 9 17:35:40 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 "balloc.h"
25 > #include "client.h"
26   #include "event.h"
27   #include "irc_string.h"
28   #include "sprintf_irc.h"
29   #include "ircd.h"
30   #include "numeric.h"
32 – #include "restart.h"
31   #include "rng_mt.h"
32   #include "fdlist.h"
35 – #include "fileio.h" /* for fbopen / fbclose / fbputs */
33   #include "s_bsd.h"
34 < #include "s_log.h"
34 > #include "log.h"
35 > #include "s_misc.h"
36   #include "send.h"
37   #include "memory.h"
38   #include "irc_res.h"
39   #include "irc_reslib.h"
42 – #include "irc_getnameinfo.h"
40  
41   #if (CHAR_BIT != 8)
42   #error this code needs to be able to address individual octets
# Line 94 | Line 91 | struct reslist
91  
92   static fde_t ResolverFileDescriptor;
93   static dlink_list request_list = { NULL, NULL, 0 };
94 + static BlockHeap *dns_heap = NULL;
95  
96 < static void rem_request(struct reslist *request);
97 < static struct reslist *make_request(dns_callback_fnc callback, void *);
98 < static void do_query_name(dns_callback_fnc callback, void *,
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 callback, void *ctx,
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 *);
110 < static struct reslist *find_id(int id);
111 < static struct DNSReply *make_dnsreply(struct reslist *request);
112 <
113 < extern struct irc_ssaddr irc_nsaddr_list[IRCD_MAXNS];
114 < extern int irc_nscount;
115 < 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 137 | Line 129 | res_ourserver(const struct irc_ssaddr *i
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
# Line 155 | 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,
161 <                        sizeof(struct in6_addr)) == 0))
162 <              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))
170 <              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 212 | Line 201 | timeout_query_list(time_t now)
201      }
202  
203      if ((next_time == 0) || timeout < next_time)
215 –    {
204        next_time = timeout;
217 –    }
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 257 | Line 244 | start_resolver(void)
244   void
245   init_resolver(void)
246   {
247 +  dns_heap = BlockHeapCreate("dns", sizeof(struct reslist), DNS_HEAP_SIZE);
248    memset(&ResolverFileDescriptor, 0, sizeof(fde_t));
249    start_resolver();
250   }
# Line 273 | Line 261 | restart_resolver(void)
261   }
262  
263   /*
276 – * add_local_domain - Add the domain to hostname, if it is missing
277 – * (as suggested by eps@TOASTER.SFSU.EDU)
278 – */
279 – void
280 – add_local_domain(char *hname, size_t size)
281 – {
282 –  /* try to fix up unqualified names
283 –   */
284 –  if (strchr(hname, '.') == NULL)
285 –  {
286 –    if (irc_domain[0])
287 –    {
288 –      size_t len = strlen(hname);
289 –
290 –      if ((strlen(irc_domain) + len + 2) < size)
291 –      {
292 –        hname[len++] = '.';
293 –        strcpy(hname + len, irc_domain);
294 –      }
295 –    }
296 –  }
297 – }
298 –
299 – /*
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 305 | 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 >  BlockHeapFree(dns_heap, request);
275   }
276  
277   /*
# Line 315 | Line 280 | rem_request(struct reslist *request)
280   static struct reslist *
281   make_request(dns_callback_fnc callback, void *ctx)
282   {
283 <  struct reslist *request;
319 <
320 <  request = (struct reslist *)MyMalloc(sizeof(struct reslist));
283 >  struct reslist *request = BlockHeapAlloc(dns_heap);
284  
285    request->sentat       = CurrentTime;
286    request->retries      = 3;
# Line 328 | Line 291 | make_request(dns_callback_fnc callback,
291    request->callback_ctx = ctx;
292  
293    dlinkAdd(request, &request->node, &request_list);
294 <  return(request);
294 >  return request;
295   }
296  
297   /*
# Line 338 | Line 301 | make_request(dns_callback_fnc callback,
301   void
302   delete_resolver_queries(const void *vptr)
303   {
304 <  dlink_node *ptr;
342 <  dlink_node *next_ptr;
343 <  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 (request->callback_ctx == vptr)
311 <        rem_request(request);
351 <    }
308 >    struct reslist *request = ptr->data;
309 >
310 >    if (request->callback_ctx == vptr)
311 >      rem_request(request);
312    }
313   }
314  
# Line 380 | 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 389 | 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;
393 <  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 410 | Line 369 | find_id(int id)
369   void
370   gethost_byname_type(dns_callback_fnc callback, void *ctx, const char *name, int type)
371   {
372 <  assert(name != 0);
372 >  assert(name != NULL);
373    do_query_name(callback, ctx, name, NULL, type);
374   }
375  
# Line 445 | Line 404 | do_query_name(dns_callback_fnc callback,
404   {
405    char host_name[HOSTLEN + 1];
406  
407 <  strlcpy(host_name, name, HOSTLEN + 1);
449 <  add_local_domain(host_name, HOSTLEN + 1);
407 >  strlcpy(host_name, name, sizeof(host_name));
408  
409    if (request == NULL)
410    {
# Line 480 | Line 438 | do_query_number(dns_callback_fnc callbac
438    if (addr->ss.ss_family == AF_INET)
439    {
440      const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
441 <    cp = (const unsigned char*)&v4->sin_addr.s_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)
# Line 492 | Line 450 | do_query_number(dns_callback_fnc callbac
450      const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
451      cp = (const unsigned char *)&v6->sin6_addr.s6_addr;
452  
453 <    sprintf(ipbuf, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
454 <                   "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa.",
455 <                  (unsigned int)(cp[15]&0xf), (unsigned int)(cp[15]>>4),
456 <                  (unsigned int)(cp[14]&0xf), (unsigned int)(cp[14]>>4),
457 <                  (unsigned int)(cp[13]&0xf), (unsigned int)(cp[13]>>4),
458 <                  (unsigned int)(cp[12]&0xf), (unsigned int)(cp[12]>>4),
459 <                  (unsigned int)(cp[11]&0xf), (unsigned int)(cp[11]>>4),
460 <                  (unsigned int)(cp[10]&0xf), (unsigned int)(cp[10]>>4),
461 <                  (unsigned int)(cp[9]&0xf), (unsigned int)(cp[9]>>4),
462 <                  (unsigned int)(cp[8]&0xf), (unsigned int)(cp[8]>>4),
463 <                  (unsigned int)(cp[7]&0xf), (unsigned int)(cp[7]>>4),
464 <                  (unsigned int)(cp[6]&0xf), (unsigned int)(cp[6]>>4),
465 <                  (unsigned int)(cp[5]&0xf), (unsigned int)(cp[5]>>4),
466 <                  (unsigned int)(cp[4]&0xf), (unsigned int)(cp[4]>>4),
467 <                  (unsigned int)(cp[3]&0xf), (unsigned int)(cp[3]>>4),
468 <                  (unsigned int)(cp[2]&0xf), (unsigned int)(cp[2]>>4),
469 <                  (unsigned int)(cp[1]&0xf), (unsigned int)(cp[1]>>4),
470 <                  (unsigned int)(cp[0]&0xf), (unsigned int)(cp[0]>>4));
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)
# Line 586 | 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 605 | 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 618 | 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 <    {
623 <      /*
624 <       * broken message
625 <       */
626 <      return(0);
627 <    }
628 <    else if (n == 0)
629 <    {
630 <      /*
631 <       * no more answers left
632 <       */
633 <      return(0);
634 <    }
580 >    if (n < 0 /* broken message */ || n == 0 /* no more answers left */)
581 >      return 0;
582  
583      hostbuf[HOSTLEN] = '\0';
584  
# Line 663 | 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 */
699 <        else if (n == 0)
700 <          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 + 1);
652 <
704 <        return(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 714 | 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 727 | 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 753 | Line 701 | res_readreply(fde_t *fd, void *data)
701    HEADER *header;
702    struct reslist *request = NULL;
703    int rc;
756 –  int answer_count;
704    socklen_t len = sizeof(struct irc_ssaddr);
705    struct irc_ssaddr lsin;
706  
# Line 778 | 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
782 <   * 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))
# Line 823 | Line 770 | res_readreply(fde_t *fd, void *data)
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);
827 <
828 <  if (answer_count)
773 >  if (proc_answer(request, header, buf, buf + rc))
774    {
775      if (request->type == T_PTR)
776      {
# Line 882 | Line 827 | report_dns_servers(struct Client *source
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,
832 <                    sizeof(ipaddr), NULL, 0, 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)