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

Comparing:
ircd-hybrid/src/irc_res.c (file contents), Revision 32 by knight, Sun Oct 2 20:41:23 2005 UTC vs.
ircd-hybrid-7.2/src/irc_res.c (file contents), Revision 995 by michael, Fri Aug 21 10:11:14 2009 UTC

# Line 30 | Line 30
30   #include "ircd.h"
31   #include "numeric.h"
32   #include "restart.h"
33 + #include "rng_mt.h"
34   #include "fdlist.h"
35   #include "fileio.h" /* for fbopen / fbclose / fbputs */
36   #include "s_bsd.h"
# Line 69 | Line 70 | typedef enum
70   #ifdef IPV6
71    REQ_AAAA,  /* Looking up an AAAA */
72   #endif
73 <  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 */
73 >  REQ_CNAME  /* We got a CNAME in response, we better get a real answer next */
74   } request_state;
75  
76   struct reslist
# Line 88 | Line 88 | struct reslist
88    time_t timeout;
89    struct irc_ssaddr addr;
90    char *name;
91 <  struct DNSQuery *query;  /* query callback for this request */
91 >  dns_callback_fnc callback;
92 >  void *callback_ctx;
93   };
94  
95   static fde_t ResolverFileDescriptor;
96 < static dlink_list request_list    = { NULL, NULL, 0 };
96 > static dlink_list request_list = { NULL, NULL, 0 };
97  
98   static void rem_request(struct reslist *request);
99 < static struct reslist *make_request(struct DNSQuery *query);
100 < static void do_query_name(struct DNSQuery *query,
101 <                          const char* name, struct reslist *request, int);
102 < static void do_query_number(struct DNSQuery *query,
99 > static struct reslist *make_request(dns_callback_fnc callback, void *);
100 > static void do_query_name(dns_callback_fnc callback, void *,
101 >                          const char *, struct reslist *, int);
102 > static void do_query_number(dns_callback_fnc callback, void *ctx,
103                              const struct irc_ssaddr *,
104                              struct reslist *request);
105   static void query_name(const char *name, int query_class, int query_type,
# Line 107 | Line 108 | static int send_res_msg(const char *buf,
108   static void resend_query(struct reslist *request);
109   static int proc_answer(struct reslist *request, HEADER *header, char *, char *);
110   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];
111  
112  
113   /*
# Line 129 | Line 125 | static int
125   res_ourserver(const struct irc_ssaddr *inp)
126   {
127   #ifdef IPV6
128 <  struct sockaddr_in6 *v6;
129 <  struct sockaddr_in6 *v6in = (struct sockaddr_in6 *)inp;
128 >  const struct sockaddr_in6 *v6;
129 >  const struct sockaddr_in6 *v6in = (const struct sockaddr_in6 *)inp;
130   #endif
131 <  struct sockaddr_in *v4;
132 <  struct sockaddr_in *v4in = (struct sockaddr_in *)inp;
131 >  const struct sockaddr_in *v4;
132 >  const struct sockaddr_in *v4in = (const struct sockaddr_in *)inp;
133    int ns;
134  
135 <  for (ns = 0;  ns < irc_nscount;  ns++)
135 >  for (ns = 0; ns < irc_nscount; ns++)
136    {
137      const struct irc_ssaddr *srv = &irc_nsaddr_list[ns];
138   #ifdef IPV6
139 <    v6 = (struct sockaddr_in6 *)srv;
139 >    v6 = (const struct sockaddr_in6 *)srv;
140   #endif
141 <    v4 = (struct sockaddr_in *)srv;
141 >    v4 = (const struct sockaddr_in *)srv;
142  
143      /* could probably just memcmp(srv, inp, srv.ss_len) here
144       * but we'll air on the side of caution - stu
# Line 198 | Line 194 | timeout_query_list(time_t now)
194      {
195        if (--request->retries <= 0)
196        {
197 <        (*request->query->callback)(request->query->ptr, NULL);
197 >        (*request->callback)(request->callback_ctx, NULL, NULL);
198          rem_request(request);
199          continue;
200        }
# Line 256 | Line 252 | start_resolver(void)
252   void
253   init_resolver(void)
254   {
259 #ifdef HAVE_SRAND48
260  srand48(CurrentTime);
261 #endif
255    memset(&ResolverFileDescriptor, 0, sizeof(fde_t));
256    start_resolver();
257   }
# Line 275 | Line 268 | restart_resolver(void)
268   }
269  
270   /*
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 /*
271   * rem_request - remove a request from the list.
272   * This must also free any memory that has been allocated for
273   * temporary storage of DNS results.
# Line 315 | Line 284 | rem_request(struct reslist *request)
284   * make_request - Create a DNS request record for the server.
285   */
286   static struct reslist *
287 < make_request(struct DNSQuery* query)
287 > make_request(dns_callback_fnc callback, void *ctx)
288   {
289    struct reslist *request;
290  
291    request = (struct reslist *)MyMalloc(sizeof(struct reslist));
323  memset(request, 0, sizeof(struct reslist));
292  
293 <  request->sentat  = CurrentTime;
294 <  request->retries = 3;
295 <  request->resend  = 1;
296 <  request->timeout = 4;    /* start at 4 and exponential inc. */
297 <  memset(&request->addr, 0, sizeof(request->addr));
298 <  request->query   = query;
299 <  request->state   = REQ_IDLE;
293 >  request->sentat       = CurrentTime;
294 >  request->retries      = 3;
295 >  request->resend       = 1;
296 >  request->timeout      = 4;    /* start at 4 and exponential inc. */
297 >  request->state        = REQ_IDLE;
298 >  request->callback     = callback;
299 >  request->callback_ctx = ctx;
300  
301    dlinkAdd(request, &request->node, &request_list);
302    return(request);
# Line 339 | Line 307 | make_request(struct DNSQuery* query)
307   * for which there no longer exist clients or conf lines.
308   */
309   void
310 < delete_resolver_queries(const struct DNSQuery *query)
310 > delete_resolver_queries(const void *vptr)
311   {
312    dlink_node *ptr;
313    dlink_node *next_ptr;
# Line 349 | Line 317 | delete_resolver_queries(const struct DNS
317    {
318      if ((request = ptr->data) != NULL)
319      {
320 <      if (query == request->query)
320 >      if (request->callback_ctx == vptr)
321          rem_request(request);
322      }
323    }
# Line 411 | Line 379 | find_id(int id)
379   *
380   */
381   void
382 < gethost_byname_type(const char *name, struct DNSQuery *query, int type)
382 > gethost_byname_type(dns_callback_fnc callback, void *ctx, const char *name, int type)
383   {
384    assert(name != 0);
385 <  do_query_name(query, name, NULL, type);
385 >  do_query_name(callback, ctx, name, NULL, type);
386   }
387  
388   /*
389   * gethost_byname - wrapper for _type - send T_AAAA first if IPV6 supported
390   */
391   void
392 < gethost_byname(const char *name, struct DNSQuery *query)
392 > gethost_byname(dns_callback_fnc callback, void *ctx, const char *name)
393   {
394   #ifdef IPV6
395 <  gethost_byname_type(name, query, T_AAAA);
395 >  gethost_byname_type(callback, ctx, name, T_AAAA);
396   #else
397 <  gethost_byname_type(name, query, T_A);
397 >  gethost_byname_type(callback, ctx, name, T_A);
398   #endif
399   }
400  
# Line 434 | Line 402 | gethost_byname(const char *name, struct
402   * gethost_byaddr - get host name from address
403   */
404   void
405 < gethost_byaddr(const struct irc_ssaddr *addr, struct DNSQuery *query)
405 > gethost_byaddr(dns_callback_fnc callback, void *ctx, const struct irc_ssaddr *addr)
406   {
407 <  do_query_number(query, addr, NULL);
407 >  do_query_number(callback, ctx, addr, NULL);
408   }
409  
410   /*
411   * do_query_name - nameserver lookup name
412   */
413   static void
414 < do_query_name(struct DNSQuery *query, const char *name,
414 > do_query_name(dns_callback_fnc callback, void *ctx, const char *name,
415                struct reslist *request, int type)
416   {
417    char host_name[HOSTLEN + 1];
418  
419 <  strlcpy(host_name, name, HOSTLEN);
452 <  add_local_domain(host_name, HOSTLEN);
419 >  strlcpy(host_name, name, sizeof(hostname));
420  
421    if (request == NULL)
422    {
423 <    request       = make_request(query);
424 <    request->name = (char *)MyMalloc(strlen(host_name) + 1);
423 >    request       = make_request(callback, ctx);
424 >    request->name = MyMalloc(strlen(host_name) + 1);
425      request->type = type;
426      strcpy(request->name, host_name);
427   #ifdef IPV6
428 <    if (type == T_A)
462 <      request->state = REQ_A;
463 <    else
428 >    if (type != T_A)
429        request->state = REQ_AAAA;
430 < #else
466 <    request->state = REQ_A;
430 >    else
431   #endif
432 +    request->state = REQ_A;
433    }
434  
435    request->type = type;
# Line 475 | Line 440 | do_query_name(struct DNSQuery *query, co
440   * do_query_number - Use this to do reverse IP# lookups.
441   */
442   static void
443 < do_query_number(struct DNSQuery *query, const struct irc_ssaddr *addr,
443 > do_query_number(dns_callback_fnc callback, void *ctx,
444 >                const struct irc_ssaddr *addr,
445                  struct reslist *request)
446   {
447    char ipbuf[128];
448    const unsigned char *cp;
449 < #ifdef IPV6
484 <  const char *intarpa;
485 < #endif
449 >
450    if (addr->ss.ss_family == AF_INET)
451    {
452 <    struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
452 >    const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
453      cp = (const unsigned char*)&v4->sin_addr.s_addr;
454  
455      ircsprintf(ipbuf, "%u.%u.%u.%u.in-addr.arpa.",
# Line 495 | Line 459 | do_query_number(struct DNSQuery *query,
459   #ifdef IPV6
460    else if (addr->ss.ss_family == AF_INET6)
461    {
462 <    struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
462 >    const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
463      cp = (const unsigned char *)&v6->sin6_addr.s6_addr;
464  
465 <    if (request != NULL && request->state == REQ_INT)
466 <      intarpa = "int";
503 <    else
504 <      intarpa = "arpa";
505 <
506 <    (void)sprintf(ipbuf, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
507 <                  "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.%s.",
465 >    sprintf(ipbuf, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
466 >                   "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa.",
467                    (unsigned int)(cp[15]&0xf), (unsigned int)(cp[15]>>4),
468                    (unsigned int)(cp[14]&0xf), (unsigned int)(cp[14]>>4),
469                    (unsigned int)(cp[13]&0xf), (unsigned int)(cp[13]>>4),
# Line 520 | Line 479 | do_query_number(struct DNSQuery *query,
479                    (unsigned int)(cp[3]&0xf), (unsigned int)(cp[3]>>4),
480                    (unsigned int)(cp[2]&0xf), (unsigned int)(cp[2]>>4),
481                    (unsigned int)(cp[1]&0xf), (unsigned int)(cp[1]>>4),
482 <                  (unsigned int)(cp[0]&0xf), (unsigned int)(cp[0]>>4), intarpa);
482 >                  (unsigned int)(cp[0]&0xf), (unsigned int)(cp[0]>>4));
483    }
484   #endif
485    if (request == NULL)
486    {
487 <    request       = make_request(query);
487 >    request       = make_request(callback, ctx);
488      request->type = T_PTR;
489      memcpy(&request->addr, addr, sizeof(struct irc_ssaddr));
490 <    request->name = (char *)MyMalloc(HOSTLEN + 1);
490 >    request->name = MyMalloc(HOSTLEN + 1);
491    }
492  
493    query_name(ipbuf, C_IN, T_PTR, request);
# Line 550 | Line 509 | query_name(const char *name, int query_c
509        (unsigned char *)buf, sizeof(buf))) > 0)
510    {
511      HEADER *header = (HEADER *)buf;
512 < #ifndef HAVE_LRAND48
554 <    int k = 0;
555 <    struct timeval tv;
556 < #endif
512 >
513      /*
514       * generate an unique id
515       * NOTE: we don't have to worry about converting this to and from
516       * network byte order, the nameserver does not interpret this value
517       * and returns it unchanged
518       */
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);
519      do
520 <    {
521 <      header->id = (header->id + k + tv.tv_usec) & 0xffff;
522 <      k++;
574 <    } while (find_id(header->id));
575 < #endif /* HAVE_LRAND48 */
520 >      header->id = (header->id + genrand_int32()) & 0xffff;
521 >    while (find_id(header->id));
522 >
523      request->id = header->id;
524      ++request->sends;
525  
# Line 586 | Line 533 | resend_query(struct reslist *request)
533    if (request->resend == 0)
534      return;
535  
536 <  switch(request->type)
536 >  switch (request->type)
537    {
538      case T_PTR:
539 <      do_query_number(NULL, &request->addr, request);
539 >      do_query_number(NULL, NULL, &request->addr, request);
540        break;
541      case T_A:
542 <      do_query_name(NULL, request->name, request, request->type);
542 >      do_query_name(NULL, NULL, request->name, request, request->type);
543        break;
544   #ifdef IPV6
545      case T_AAAA:
546        /* didnt work, try A */
547        if (request->state == REQ_AAAA)
548 <        do_query_name(NULL, request->name, request, T_A);
548 >        do_query_name(NULL, NULL, request->name, request, T_A);
549   #endif
550      default:
551        break;
# Line 722 | Line 669 | proc_answer(struct reslist *request, HEA
669          else if (n == 0)
670            return(0); /* no more answers left */
671  
672 <        strlcpy(request->name, hostbuf, HOSTLEN);
672 >        strlcpy(request->name, hostbuf, HOSTLEN + 1);
673  
674          return(1);
675          break;
# Line 764 | Line 711 | proc_answer(struct reslist *request, HEA
711   static void
712   res_readreply(fde_t *fd, void *data)
713   {
714 <  char buf[sizeof(HEADER) + MAXPACKET];
714 >  char buf[sizeof(HEADER) + MAXPACKET]
715 >        /* Sparc and alpha need 16bit-alignment for accessing header->id
716 >         * (which is uint16_t). Because of the header = (HEADER*) buf;
717 >         * lateron, this is neeeded. --FaUl
718 >         */
719 > #if defined(__sparc__) || defined(__alpha__)  
720 >          __attribute__((aligned (16)))
721 > #endif
722 >          ;
723    HEADER *header;
724    struct reslist *request = NULL;
770  struct DNSReply *reply  = NULL;
725    int rc;
772  int answer_count;
726    socklen_t len = sizeof(struct irc_ssaddr);
727    struct irc_ssaddr lsin;
728  
# Line 779 | Line 732 | res_readreply(fde_t *fd, void *data)
732     * interest where it'll instantly be ready for read :-) -- adrian
733     */
734    comm_setselect(fd, COMM_SELECT_READ, res_readreply, NULL, 0);
735 +
736    /* Better to cast the sizeof instead of rc */
737    if (rc <= (int)(sizeof(HEADER)))
738      return;
# Line 793 | Line 747 | res_readreply(fde_t *fd, void *data)
747    header->arcount = ntohs(header->arcount);
748  
749    /*
750 <   * response for an id which we have already received an answer for
797 <   * just ignore this response.
750 >   * check against possibly fake replies
751     */
752 <  if (0 == (request = find_id(header->id)))
752 >  if (!res_ourserver(&lsin))
753      return;
754  
755    /*
756 <   * check against possibly fake replies
756 >   * response for an id which we have already received an answer for
757 >   * just ignore this response.
758     */
759 <  if (!res_ourserver(&lsin))
759 >  if (!(request = find_id(header->id)))
760      return;
761  
762    if ((header->rcode != NO_ERRORS) || (header->ancount == 0))
763    {
764 <    if (SERVFAIL == header->rcode)
765 <      resend_query(request);
764 >    if (header->rcode == SERVFAIL || header->rcode == NXDOMAIN)
765 >    {
766 >      /*
767 >       * If a bad error was returned, stop here and don't
768 >       * send any more (no retries granted).
769 >       */
770 >      (*request->callback)(request->callback_ctx, NULL, NULL);
771 >      rem_request(request);
772 >    }
773 > #ifdef IPV6
774      else
775      {
776        /*
777         * If we havent already tried this, and we're looking up AAAA, try A
778         * now
779         */
818
819 #ifdef IPV6
780        if (request->state == REQ_AAAA && request->type == T_AAAA)
781        {
782          request->timeout += 4;
783          resend_query(request);
784        }
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      }
785      }
786 + #endif
787  
788      return;
789    }
790 +
791    /*
792     * If this fails there was an error decoding the received packet,
793     * try it again and hope it works the next time.
794     */
795 <  answer_count = proc_answer(request, header, buf, buf + rc);
852 <
853 <  if (answer_count)
795 >  if (proc_answer(request, header, buf, buf + rc))
796    {
797      if (request->type == T_PTR)
798      {
# Line 860 | Line 802 | res_readreply(fde_t *fd, void *data)
802           * got a PTR response with no name, something bogus is happening
803           * don't bother trying again, the client address doesn't resolve
804           */
805 <        (*request->query->callback)(request->query->ptr, reply);
805 >        (*request->callback)(request->callback_ctx, NULL, NULL);
806          rem_request(request);
807          return;
808        }
# Line 872 | Line 814 | res_readreply(fde_t *fd, void *data)
814         */
815   #ifdef IPV6
816        if (request->addr.ss.ss_family == AF_INET6)
817 <        gethost_byname_type(request->name, request->query, T_AAAA);
817 >        gethost_byname_type(request->callback, request->callback_ctx, request->name, T_AAAA);
818        else
819   #endif
820 <      gethost_byname_type(request->name, request->query, T_A);
820 >      gethost_byname_type(request->callback, request->callback_ctx, request->name, T_A);
821        rem_request(request);
822      }
823      else
# Line 883 | Line 825 | res_readreply(fde_t *fd, void *data)
825        /*
826         * got a name and address response, client resolved
827         */
828 <      reply = make_dnsreply(request);
887 <      (*request->query->callback)(request->query->ptr, reply);
888 <      MyFree(reply);
828 >      (*request->callback)(request->callback_ctx, &request->addr, request->name);
829        rem_request(request);
830      }
831    }
# Line 901 | Line 841 | res_readreply(fde_t *fd, void *data)
841    }
842   }
843  
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
844   void
845   report_dns_servers(struct Client *source_p)
846   {
847    int i;
848 <  char ipaddr[HOSTIPLEN];
848 >  char ipaddr[HOSTIPLEN + 1];
849  
850    for (i = 0; i < irc_nscount; i++)
851    {
852      irc_getnameinfo((struct sockaddr *)&(irc_nsaddr_list[i]),
853 <                    irc_nsaddr_list[i].ss_len, ipaddr, HOSTIPLEN, NULL, 0,
854 <                    NI_NUMERICHOST);
853 >                    irc_nsaddr_list[i].ss_len, ipaddr,
854 >                    sizeof(ipaddr), NULL, 0, NI_NUMERICHOST);
855      sendto_one(source_p, form_str(RPL_STATSALINE),
856                 me.name, source_p->name, ipaddr);
857    }

Comparing:
ircd-hybrid/src/irc_res.c (property svn:keywords), Revision 32 by knight, Sun Oct 2 20:41:23 2005 UTC vs.
ircd-hybrid-7.2/src/irc_res.c (property svn:keywords), Revision 995 by michael, Fri Aug 21 10:11:14 2009 UTC

# Line 1 | Line 1
1 < Revision
1 > Id Revision

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines