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 31 by knight, Sun Oct 2 20:34:05 2005 UTC vs.
ircd-hybrid-7.2/src/irc_res.c (file contents), Revision 994 by michael, Fri Aug 21 09:15:31 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 129 | Line 130 | static int
130   res_ourserver(const struct irc_ssaddr *inp)
131   {
132   #ifdef IPV6
133 <  struct sockaddr_in6 *v6;
134 <  struct sockaddr_in6 *v6in = (struct sockaddr_in6 *)inp;
133 >  const struct sockaddr_in6 *v6;
134 >  const struct sockaddr_in6 *v6in = (const struct sockaddr_in6 *)inp;
135   #endif
136 <  struct sockaddr_in *v4;
137 <  struct sockaddr_in *v4in = (struct sockaddr_in *)inp;
136 >  const struct sockaddr_in *v4;
137 >  const struct sockaddr_in *v4in = (const struct sockaddr_in *)inp;
138    int ns;
139  
140 <  for (ns = 0;  ns < irc_nscount;  ns++)
140 >  for (ns = 0; ns < irc_nscount; ns++)
141    {
142      const struct irc_ssaddr *srv = &irc_nsaddr_list[ns];
143   #ifdef IPV6
144 <    v6 = (struct sockaddr_in6 *)srv;
144 >    v6 = (const struct sockaddr_in6 *)srv;
145   #endif
146 <    v4 = (struct sockaddr_in *)srv;
146 >    v4 = (const struct sockaddr_in *)srv;
147  
148      /* could probably just memcmp(srv, inp, srv.ss_len) here
149       * but we'll air on the side of caution - stu
# Line 198 | Line 199 | timeout_query_list(time_t now)
199      {
200        if (--request->retries <= 0)
201        {
202 <        (*request->query->callback)(request->query->ptr, NULL);
202 >        (*request->callback)(request->callback_ctx, NULL, NULL);
203          rem_request(request);
204          continue;
205        }
# Line 256 | Line 257 | start_resolver(void)
257   void
258   init_resolver(void)
259   {
259 #ifdef HAVE_SRAND48
260  srand48(CurrentTime);
261 #endif
260    memset(&ResolverFileDescriptor, 0, sizeof(fde_t));
261    start_resolver();
262   }
# Line 315 | Line 313 | rem_request(struct reslist *request)
313   * make_request - Create a DNS request record for the server.
314   */
315   static struct reslist *
316 < make_request(struct DNSQuery* query)
316 > make_request(dns_callback_fnc callback, void *ctx)
317   {
318    struct reslist *request;
319  
320    request = (struct reslist *)MyMalloc(sizeof(struct reslist));
323  memset(request, 0, sizeof(struct reslist));
321  
322 <  request->sentat  = CurrentTime;
323 <  request->retries = 3;
324 <  request->resend  = 1;
325 <  request->timeout = 4;    /* start at 4 and exponential inc. */
326 <  memset(&request->addr, 0, sizeof(request->addr));
327 <  request->query   = query;
328 <  request->state   = REQ_IDLE;
322 >  request->sentat       = CurrentTime;
323 >  request->retries      = 3;
324 >  request->resend       = 1;
325 >  request->timeout      = 4;    /* start at 4 and exponential inc. */
326 >  request->state        = REQ_IDLE;
327 >  request->callback     = callback;
328 >  request->callback_ctx = ctx;
329  
330    dlinkAdd(request, &request->node, &request_list);
331    return(request);
# Line 339 | Line 336 | make_request(struct DNSQuery* query)
336   * for which there no longer exist clients or conf lines.
337   */
338   void
339 < delete_resolver_queries(const struct DNSQuery *query)
339 > delete_resolver_queries(const void *vptr)
340   {
341    dlink_node *ptr;
342    dlink_node *next_ptr;
# Line 349 | Line 346 | delete_resolver_queries(const struct DNS
346    {
347      if ((request = ptr->data) != NULL)
348      {
349 <      if (query == request->query)
349 >      if (request->callback_ctx == vptr)
350          rem_request(request);
351      }
352    }
# Line 411 | Line 408 | find_id(int id)
408   *
409   */
410   void
411 < gethost_byname_type(const char *name, struct DNSQuery *query, int type)
411 > gethost_byname_type(dns_callback_fnc callback, void *ctx, const char *name, int type)
412   {
413    assert(name != 0);
414 <  do_query_name(query, name, NULL, type);
414 >  do_query_name(callback, ctx, name, NULL, type);
415   }
416  
417   /*
418   * gethost_byname - wrapper for _type - send T_AAAA first if IPV6 supported
419   */
420   void
421 < gethost_byname(const char *name, struct DNSQuery *query)
421 > gethost_byname(dns_callback_fnc callback, void *ctx, const char *name)
422   {
423   #ifdef IPV6
424 <  gethost_byname_type(name, query, T_AAAA);
424 >  gethost_byname_type(callback, ctx, name, T_AAAA);
425   #else
426 <  gethost_byname_type(name, query, T_A);
426 >  gethost_byname_type(callback, ctx, name, T_A);
427   #endif
428   }
429  
# Line 434 | Line 431 | gethost_byname(const char *name, struct
431   * gethost_byaddr - get host name from address
432   */
433   void
434 < gethost_byaddr(const struct irc_ssaddr *addr, struct DNSQuery *query)
434 > gethost_byaddr(dns_callback_fnc callback, void *ctx, const struct irc_ssaddr *addr)
435   {
436 <  do_query_number(query, addr, NULL);
436 >  do_query_number(callback, ctx, addr, NULL);
437   }
438  
439   /*
440   * do_query_name - nameserver lookup name
441   */
442   static void
443 < do_query_name(struct DNSQuery *query, const char *name,
443 > do_query_name(dns_callback_fnc callback, void *ctx, const char *name,
444                struct reslist *request, int type)
445   {
446    char host_name[HOSTLEN + 1];
447  
448 <  strlcpy(host_name, name, HOSTLEN);
449 <  add_local_domain(host_name, HOSTLEN);
448 >  strlcpy(host_name, name, HOSTLEN + 1);
449 >  add_local_domain(host_name, HOSTLEN + 1);
450  
451    if (request == NULL)
452    {
453 <    request       = make_request(query);
454 <    request->name = (char *)MyMalloc(strlen(host_name) + 1);
453 >    request       = make_request(callback, ctx);
454 >    request->name = MyMalloc(strlen(host_name) + 1);
455      request->type = type;
456      strcpy(request->name, host_name);
457   #ifdef IPV6
458 <    if (type == T_A)
462 <      request->state = REQ_A;
463 <    else
458 >    if (type != T_A)
459        request->state = REQ_AAAA;
460 < #else
466 <    request->state = REQ_A;
460 >    else
461   #endif
462 +    request->state = REQ_A;
463    }
464  
465    request->type = type;
# Line 475 | Line 470 | do_query_name(struct DNSQuery *query, co
470   * do_query_number - Use this to do reverse IP# lookups.
471   */
472   static void
473 < do_query_number(struct DNSQuery *query, const struct irc_ssaddr *addr,
473 > do_query_number(dns_callback_fnc callback, void *ctx,
474 >                const struct irc_ssaddr *addr,
475                  struct reslist *request)
476   {
477    char ipbuf[128];
478    const unsigned char *cp;
479 < #ifdef IPV6
484 <  const char *intarpa;
485 < #endif
479 >
480    if (addr->ss.ss_family == AF_INET)
481    {
482 <    struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
482 >    const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
483      cp = (const unsigned char*)&v4->sin_addr.s_addr;
484  
485      ircsprintf(ipbuf, "%u.%u.%u.%u.in-addr.arpa.",
# Line 495 | Line 489 | do_query_number(struct DNSQuery *query,
489   #ifdef IPV6
490    else if (addr->ss.ss_family == AF_INET6)
491    {
492 <    struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
492 >    const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
493      cp = (const unsigned char *)&v6->sin6_addr.s6_addr;
494  
495 <    if (request != NULL && request->state == REQ_INT)
496 <      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.",
495 >    sprintf(ipbuf, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
496 >                   "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa.",
497                    (unsigned int)(cp[15]&0xf), (unsigned int)(cp[15]>>4),
498                    (unsigned int)(cp[14]&0xf), (unsigned int)(cp[14]>>4),
499                    (unsigned int)(cp[13]&0xf), (unsigned int)(cp[13]>>4),
# Line 520 | Line 509 | do_query_number(struct DNSQuery *query,
509                    (unsigned int)(cp[3]&0xf), (unsigned int)(cp[3]>>4),
510                    (unsigned int)(cp[2]&0xf), (unsigned int)(cp[2]>>4),
511                    (unsigned int)(cp[1]&0xf), (unsigned int)(cp[1]>>4),
512 <                  (unsigned int)(cp[0]&0xf), (unsigned int)(cp[0]>>4), intarpa);
512 >                  (unsigned int)(cp[0]&0xf), (unsigned int)(cp[0]>>4));
513    }
514   #endif
515    if (request == NULL)
516    {
517 <    request       = make_request(query);
517 >    request       = make_request(callback, ctx);
518      request->type = T_PTR;
519      memcpy(&request->addr, addr, sizeof(struct irc_ssaddr));
520 <    request->name = (char *)MyMalloc(HOSTLEN + 1);
520 >    request->name = MyMalloc(HOSTLEN + 1);
521    }
522  
523    query_name(ipbuf, C_IN, T_PTR, request);
# Line 550 | Line 539 | query_name(const char *name, int query_c
539        (unsigned char *)buf, sizeof(buf))) > 0)
540    {
541      HEADER *header = (HEADER *)buf;
542 < #ifndef HAVE_LRAND48
554 <    int k = 0;
555 <    struct timeval tv;
556 < #endif
542 >
543      /*
544       * generate an unique id
545       * NOTE: we don't have to worry about converting this to and from
546       * network byte order, the nameserver does not interpret this value
547       * and returns it unchanged
548       */
563 #ifdef HAVE_LRAND48
549      do
550 <    {
551 <      header->id = (header->id + lrand48()) & 0xffff;
552 <    } while (find_id(header->id));
568 < #else
569 <    gettimeofday(&tv, NULL);
570 <    do
571 <    {
572 <      header->id = (header->id + k + tv.tv_usec) & 0xffff;
573 <      k++;
574 <    } while (find_id(header->id));
575 < #endif /* HAVE_LRAND48 */
550 >      header->id = (header->id + genrand_int32()) & 0xffff;
551 >    while (find_id(header->id));
552 >
553      request->id = header->id;
554      ++request->sends;
555  
# Line 586 | Line 563 | resend_query(struct reslist *request)
563    if (request->resend == 0)
564      return;
565  
566 <  switch(request->type)
566 >  switch (request->type)
567    {
568      case T_PTR:
569 <      do_query_number(NULL, &request->addr, request);
569 >      do_query_number(NULL, NULL, &request->addr, request);
570        break;
571      case T_A:
572 <      do_query_name(NULL, request->name, request, request->type);
572 >      do_query_name(NULL, NULL, request->name, request, request->type);
573        break;
574   #ifdef IPV6
575      case T_AAAA:
576        /* didnt work, try A */
577        if (request->state == REQ_AAAA)
578 <        do_query_name(NULL, request->name, request, T_A);
578 >        do_query_name(NULL, NULL, request->name, request, T_A);
579   #endif
580      default:
581        break;
# Line 722 | Line 699 | proc_answer(struct reslist *request, HEA
699          else if (n == 0)
700            return(0); /* no more answers left */
701  
702 <        strlcpy(request->name, hostbuf, HOSTLEN);
702 >        strlcpy(request->name, hostbuf, HOSTLEN + 1);
703  
704          return(1);
705          break;
# Line 764 | Line 741 | proc_answer(struct reslist *request, HEA
741   static void
742   res_readreply(fde_t *fd, void *data)
743   {
744 <  char buf[sizeof(HEADER) + MAXPACKET];
744 >  char buf[sizeof(HEADER) + MAXPACKET]
745 >        /* Sparc and alpha need 16bit-alignment for accessing header->id
746 >         * (which is uint16_t). Because of the header = (HEADER*) buf;
747 >         * lateron, this is neeeded. --FaUl
748 >         */
749 > #if defined(__sparc__) || defined(__alpha__)  
750 >          __attribute__((aligned (16)))
751 > #endif
752 >          ;
753    HEADER *header;
754    struct reslist *request = NULL;
770  struct DNSReply *reply  = NULL;
755    int rc;
772  int answer_count;
756    socklen_t len = sizeof(struct irc_ssaddr);
757    struct irc_ssaddr lsin;
758  
# Line 779 | Line 762 | res_readreply(fde_t *fd, void *data)
762     * interest where it'll instantly be ready for read :-) -- adrian
763     */
764    comm_setselect(fd, COMM_SELECT_READ, res_readreply, NULL, 0);
765 +
766    /* Better to cast the sizeof instead of rc */
767    if (rc <= (int)(sizeof(HEADER)))
768      return;
# Line 793 | Line 777 | res_readreply(fde_t *fd, void *data)
777    header->arcount = ntohs(header->arcount);
778  
779    /*
780 <   * response for an id which we have already received an answer for
797 <   * just ignore this response.
780 >   * check against possibly fake replies
781     */
782 <  if (0 == (request = find_id(header->id)))
782 >  if (!res_ourserver(&lsin))
783      return;
784  
785    /*
786 <   * check against possibly fake replies
786 >   * response for an id which we have already received an answer for
787 >   * just ignore this response.
788     */
789 <  if (!res_ourserver(&lsin))
789 >  if (!(request = find_id(header->id)))
790      return;
791  
792    if ((header->rcode != NO_ERRORS) || (header->ancount == 0))
793    {
794 <    if (SERVFAIL == header->rcode)
795 <      resend_query(request);
794 >    if (header->rcode == SERVFAIL || header->rcode == NXDOMAIN)
795 >    {
796 >      /*
797 >       * If a bad error was returned, stop here and don't
798 >       * send any more (no retries granted).
799 >       */
800 >      (*request->callback)(request->callback_ctx, NULL, NULL);
801 >      rem_request(request);
802 >    }
803 > #ifdef IPV6
804      else
805      {
806        /*
807         * If we havent already tried this, and we're looking up AAAA, try A
808         * now
809         */
818
819 #ifdef IPV6
810        if (request->state == REQ_AAAA && request->type == T_AAAA)
811        {
812          request->timeout += 4;
813          resend_query(request);
814        }
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      }
815      }
816 + #endif
817  
818      return;
819    }
820 +
821    /*
822     * If this fails there was an error decoding the received packet,
823     * try it again and hope it works the next time.
824     */
825 <  answer_count = proc_answer(request, header, buf, buf + rc);
852 <
853 <  if (answer_count)
825 >  if (proc_answer(request, header, buf, buf + rc))
826    {
827      if (request->type == T_PTR)
828      {
# Line 860 | Line 832 | res_readreply(fde_t *fd, void *data)
832           * got a PTR response with no name, something bogus is happening
833           * don't bother trying again, the client address doesn't resolve
834           */
835 <        (*request->query->callback)(request->query->ptr, reply);
835 >        (*request->callback)(request->callback_ctx, NULL, NULL);
836          rem_request(request);
837          return;
838        }
# Line 872 | Line 844 | res_readreply(fde_t *fd, void *data)
844         */
845   #ifdef IPV6
846        if (request->addr.ss.ss_family == AF_INET6)
847 <        gethost_byname_type(request->name, request->query, T_AAAA);
847 >        gethost_byname_type(request->callback, request->callback_ctx, request->name, T_AAAA);
848        else
849   #endif
850 <      gethost_byname_type(request->name, request->query, T_A);
850 >      gethost_byname_type(request->callback, request->callback_ctx, request->name, T_A);
851        rem_request(request);
852      }
853      else
# Line 883 | Line 855 | res_readreply(fde_t *fd, void *data)
855        /*
856         * got a name and address response, client resolved
857         */
858 <      reply = make_dnsreply(request);
887 <      (*request->query->callback)(request->query->ptr, reply);
888 <      MyFree(reply);
858 >      (*request->callback)(request->callback_ctx, &request->addr, request->name);
859        rem_request(request);
860      }
861    }
# Line 901 | Line 871 | res_readreply(fde_t *fd, void *data)
871    }
872   }
873  
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
874   void
875   report_dns_servers(struct Client *source_p)
876   {
877    int i;
878 <  char ipaddr[HOSTIPLEN];
878 >  char ipaddr[HOSTIPLEN + 1];
879  
880    for (i = 0; i < irc_nscount; i++)
881    {
882      irc_getnameinfo((struct sockaddr *)&(irc_nsaddr_list[i]),
883 <                    irc_nsaddr_list[i].ss_len, ipaddr, HOSTIPLEN, NULL, 0,
884 <                    NI_NUMERICHOST);
883 >                    irc_nsaddr_list[i].ss_len, ipaddr,
884 >                    sizeof(ipaddr), NULL, 0, NI_NUMERICHOST);
885      sendto_one(source_p, form_str(RPL_STATSALINE),
886                 me.name, source_p->name, ipaddr);
887    }

Comparing:
ircd-hybrid/src/irc_res.c (property svn:keywords), Revision 31 by knight, Sun Oct 2 20:34:05 2005 UTC vs.
ircd-hybrid-7.2/src/irc_res.c (property svn:keywords), Revision 994 by michael, Fri Aug 21 09:15:31 2009 UTC

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

Diff Legend

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