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

Comparing:
ircd-hybrid/src/irc_res.c (file contents), Revision 1155 by michael, Tue Aug 9 20:27:45 2011 UTC vs.
ircd-hybrid/trunk/src/irc_res.c (file contents), Revision 3268 by michael, Sat Apr 5 19:21:55 2014 UTC

# Line 1 | Line 1
1   /*
2 + *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 + *
4 + *  Copyright (c) 1997-2014 ircd-hybrid development team
5 + *
6 + *  This program is free software; you can redistribute it and/or modify
7 + *  it under the terms of the GNU General Public License as published by
8 + *  the Free Software Foundation; either version 2 of the License, or
9 + *  (at your option) any later version.
10 + *
11 + *  This program is distributed in the hope that it will be useful,
12 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 + *  GNU General Public License for more details.
15 + *
16 + *  You should have received a copy of the GNU General Public License
17 + *  along with this program; if not, write to the Free Software
18 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
19 + *  USA
20 + */
21 +
22 + /*! \file irc_res.c
23 + * \brief ircd resolver functions
24 + * \version $Id$
25 + */
26 +
27 + /*
28   * A rewrite of Darren Reeds original res.c As there is nothing
29   * left of Darrens original code, this is now licensed by the hybrid group.
30   * (Well, some of the function names are the same, and bits of the structs..)
# Line 14 | Line 40
40   *     --Bleep (Thomas Helvey <tomh@inxpress.net>)
41   *
42   * This was all needlessly complicated for irc. Simplified. No more hostent
43 < * All we really care about is the IP -> hostname mappings. Thats all.
43 > * All we really care about is the IP -> hostname mappings. Thats all.
44   *
45   * Apr 28, 2003 --cryogen and Dianora
46   */
47  
48   #include "stdinc.h"
49   #include "list.h"
24 #include "balloc.h"
50   #include "client.h"
51   #include "event.h"
52   #include "irc_string.h"
28 #include "sprintf_irc.h"
53   #include "ircd.h"
54   #include "numeric.h"
55   #include "rng_mt.h"
56   #include "fdlist.h"
33 #include "fileio.h" /* for fbopen / fbclose / fbputs */
57   #include "s_bsd.h"
58 < #include "s_log.h"
58 > #include "log.h"
59 > #include "s_misc.h"
60   #include "send.h"
61   #include "memory.h"
62 + #include "mempool.h"
63   #include "irc_res.h"
64   #include "irc_reslib.h"
40 #include "common.h"
65  
66   #if (CHAR_BIT != 8)
67 < #error this code needs to be able to address individual octets
67 > #error this code needs to be able to address individual octets
68   #endif
69  
70   static PF res_readreply;
# Line 60 | Line 84 | static PF res_readreply;
84   #define RDLENGTH_SIZE     (size_t)2
85   #define ANSWER_FIXED_SIZE (TYPE_SIZE + CLASS_SIZE + TTL_SIZE + RDLENGTH_SIZE)
86  
87 < typedef enum
87 > typedef enum
88   {
89    REQ_IDLE,  /* We're doing not much at all */
90    REQ_PTR,   /* Looking up a PTR */
# Line 71 | Line 95 | typedef enum
95    REQ_CNAME  /* We got a CNAME in response, we better get a real answer next */
96   } request_state;
97  
98 < struct reslist
98 > struct reslist
99   {
100    dlink_node node;
101    int id;
# Line 91 | Line 115 | struct reslist
115   };
116  
117   static fde_t ResolverFileDescriptor;
118 < static dlink_list request_list = { NULL, NULL, 0 };
119 < static BlockHeap *dns_heap = NULL;
118 > static dlink_list request_list;
119 > static mp_pool_t *dns_pool;
120  
121   static void rem_request(struct reslist *);
122   static struct reslist *make_request(dns_callback_fnc, void *);
# Line 120 | Line 144 | static struct reslist *find_id(int);
144   *      revised for ircd, cryogen(stu) may03
145   */
146   static int
147 < res_ourserver(const struct irc_ssaddr *inp)
147 > res_ourserver(const struct irc_ssaddr *inp)
148   {
149   #ifdef IPV6
150    const struct sockaddr_in6 *v6;
151    const struct sockaddr_in6 *v6in = (const struct sockaddr_in6 *)inp;
152   #endif
153    const struct sockaddr_in *v4;
154 <  const struct sockaddr_in *v4in = (const struct sockaddr_in *)inp;
131 <  int ns;
154 >  const struct sockaddr_in *v4in = (const struct sockaddr_in *)inp;
155  
156 <  for (ns = 0; ns < irc_nscount; ns++)
156 >  for (int i = 0; i < irc_nscount; ++i)
157    {
158 <    const struct irc_ssaddr *srv = &irc_nsaddr_list[ns];
158 >    const struct irc_ssaddr *srv = &irc_nsaddr_list[i];
159   #ifdef IPV6
160      v6 = (const struct sockaddr_in6 *)srv;
161   #endif
# Line 148 | Line 171 | res_ourserver(const struct irc_ssaddr *i
171        case AF_INET6:
172          if (srv->ss.ss_family == inp->ss.ss_family)
173            if (v6->sin6_port == v6in->sin6_port)
174 <            if ((memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr,
175 <                    sizeof(struct in6_addr)) == 0) ||
153 <                (memcmp(&v6->sin6_addr.s6_addr, &in6addr_any,
154 <                        sizeof(struct in6_addr)) == 0))
174 >            if (!memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr,
175 >                        sizeof(struct in6_addr)))
176                return 1;
177          break;
178   #endif
179        case AF_INET:
180          if (srv->ss.ss_family == inp->ss.ss_family)
181            if (v4->sin_port == v4in->sin_port)
182 <            if ((v4->sin_addr.s_addr == INADDR_ANY) ||
162 <                (v4->sin_addr.s_addr == v4in->sin_addr.s_addr))
182 >            if (v4->sin_addr.s_addr == v4in->sin_addr.s_addr)
183                return 1;
184          break;
185        default:
# Line 171 | Line 191 | res_ourserver(const struct irc_ssaddr *i
191   }
192  
193   /*
194 < * timeout_query_list - Remove queries from the list which have been
194 > * timeout_query_list - Remove queries from the list which have been
195   * there too long without being resolved.
196   */
197   static time_t
198   timeout_query_list(time_t now)
199   {
200 <  dlink_node *ptr;
181 <  dlink_node *next_ptr;
200 >  dlink_node *ptr = NULL, *ptr_next = NULL;
201    struct reslist *request;
202    time_t next_time = 0;
203    time_t timeout   = 0;
204  
205 <  DLINK_FOREACH_SAFE(ptr, next_ptr, request_list.head)
205 >  DLINK_FOREACH_SAFE(ptr, ptr_next, request_list.head)
206    {
207      request = ptr->data;
208      timeout = request->sentat + request->timeout;
# Line 248 | Line 267 | start_resolver(void)
267   void
268   init_resolver(void)
269   {
270 <  dns_heap = BlockHeapCreate("dns", sizeof(struct reslist), DNS_HEAP_SIZE);
270 >  dns_pool = mp_pool_new(sizeof(struct reslist), MP_CHUNK_SIZE_DNS);
271    memset(&ResolverFileDescriptor, 0, sizeof(fde_t));
272    start_resolver();
273   }
# Line 265 | Line 284 | restart_resolver(void)
284   }
285  
286   /*
287 < * rem_request - remove a request from the list.
288 < * This must also free any memory that has been allocated for
287 > * rem_request - remove a request from the list.
288 > * This must also free any memory that has been allocated for
289   * temporary storage of DNS results.
290   */
291   static void
# Line 275 | Line 294 | rem_request(struct reslist *request)
294    dlinkDelete(&request->node, &request_list);
295  
296    MyFree(request->name);
297 <  BlockHeapFree(dns_heap, request);
297 >  mp_pool_release(request);
298   }
299  
300   /*
# Line 284 | Line 303 | rem_request(struct reslist *request)
303   static struct reslist *
304   make_request(dns_callback_fnc callback, void *ctx)
305   {
306 <  struct reslist *request = BlockHeapAlloc(dns_heap);
306 >  struct reslist *request = mp_pool_get(dns_pool);
307  
308 +  memset(request, 0, sizeof(*request));
309    request->sentat       = CurrentTime;
310 <  request->retries      = 3;
310 >  request->retries      = 2;
311    request->resend       = 1;
312    request->timeout      = 4;    /* start at 4 and exponential inc. */
313    request->state        = REQ_IDLE;
# Line 299 | Line 319 | make_request(dns_callback_fnc callback,
319   }
320  
321   /*
322 < * delete_resolver_queries - cleanup outstanding queries
322 > * delete_resolver_queries - cleanup outstanding queries
323   * for which there no longer exist clients or conf lines.
324   */
325   void
326   delete_resolver_queries(const void *vptr)
327   {
328 <  dlink_node *ptr = NULL, *next_ptr = NULL;
328 >  dlink_node *ptr = NULL, *ptr_next = NULL;
329  
330 <  DLINK_FOREACH_SAFE(ptr, next_ptr, request_list.head)
330 >  DLINK_FOREACH_SAFE(ptr, ptr_next, request_list.head)
331    {
332      struct reslist *request = ptr->data;
333  
# Line 320 | Line 340 | delete_resolver_queries(const void *vptr
340   * send_res_msg - sends msg to all nameservers found in the "_res" structure.
341   * This should reflect /etc/resolv.conf. We will get responses
342   * which arent needed but is easier than checking to see if nameserver
343 < * isnt present. Returns number of messages successfully sent to
343 > * isnt present. Returns number of messages successfully sent to
344   * nameservers or -1 if no successful sends.
345   */
346   static int
347   send_res_msg(const char *msg, int len, int rcount)
348   {
329  int i;
349    int sent = 0;
350    int max_queries = IRCD_MIN(irc_nscount, rcount);
351  
# Line 336 | Line 355 | send_res_msg(const char *msg, int len, i
355    if (max_queries == 0)
356      max_queries = 1;
357  
358 <  for (i = 0; i < max_queries; i++)
358 >  for (int i = 0; i < max_queries; ++i)
359    {
360 <    if (sendto(ResolverFileDescriptor.fd, msg, len, 0,
361 <        (struct sockaddr*)&(irc_nsaddr_list[i]),
362 <        irc_nsaddr_list[i].ss_len) == len)
360 >    if (sendto(ResolverFileDescriptor.fd, msg, len, 0,
361 >        (struct sockaddr*)&(irc_nsaddr_list[i]),
362 >        irc_nsaddr_list[i].ss_len) == len)
363        ++sent;
364    }
365  
# Line 366 | Line 385 | find_id(int id)
385    return NULL;
386   }
387  
388 < /*
388 > /*
389   * gethost_byname_type - get host address from name
390   *
391   */
392   void
393   gethost_byname_type(dns_callback_fnc callback, void *ctx, const char *name, int type)
394   {
395 <  assert(name != NULL);
395 >  assert(name);
396    do_query_name(callback, ctx, name, NULL, type);
397   }
398  
# Line 498 | Line 517 | query_name(const char *name, int query_c
517  
518    memset(buf, 0, sizeof(buf));
519  
520 <  if ((request_len = irc_res_mkquery(name, query_class, type,
520 >  if ((request_len = irc_res_mkquery(name, query_class, type,
521        (unsigned char *)buf, sizeof(buf))) > 0)
522    {
523      HEADER *header = (HEADER *)buf;
# Line 607 | Line 626 | proc_answer(struct reslist *request, HEA
626      rd_length = irc_ns_get16(current);
627      current += RDLENGTH_SIZE;
628  
629 <    /*
630 <     * Wait to set request->type until we verify this structure
629 >    /*
630 >     * Wait to set request->type until we verify this structure
631       */
632      switch (type)
633      {
# Line 655 | Line 674 | proc_answer(struct reslist *request, HEA
674          strlcpy(request->name, hostbuf, HOSTLEN + 1);
675          return 1;
676          break;
677 <      case T_CNAME: /* first check we already havent started looking
677 >      case T_CNAME: /* first check we already havent started looking
678                         into a cname */
679 <        if (request->type != T_PTR)
679 >        if (request->type != T_PTR)
680            return 0;
681  
682          if (request->state == REQ_CNAME)
# Line 673 | Line 692 | proc_answer(struct reslist *request, HEA
692          request->state = REQ_CNAME;
693          current += rd_length;
694          break;
695 <        
695 >
696        default:
697          /* XXX I'd rather just throw away the entire bogus thing
698           * but its possible its just a broken nameserver with still
699           * valid answers. But lets do some rudimentary logging for now...
700           */
701 <        ilog(L_ERROR, "irc_res.c bogus type %d", type);
701 >        ilog(LOG_TYPE_IRCD, "irc_res.c bogus type %d", type);
702          break;
703      }
704    }
# Line 694 | Line 713 | static void
713   res_readreply(fde_t *fd, void *data)
714   {
715    char buf[sizeof(HEADER) + MAXPACKET]
716 <        /* Sparc and alpha need 16bit-alignment for accessing header->id
717 <         * (which is uint16_t). Because of the header = (HEADER*) buf;
716 >        /* Sparc and alpha need 16bit-alignment for accessing header->id
717 >         * (which is uint16_t). Because of the header = (HEADER*) buf;
718           * lateron, this is neeeded. --FaUl
719           */
720 < #if defined(__sparc__) || defined(__alpha__)  
720 > #if defined(__sparc__) || defined(__alpha__)
721            __attribute__((aligned (16)))
722 < #endif
722 > #endif
723            ;
724    HEADER *header;
725    struct reslist *request = NULL;
# Line 755 | Line 774 | res_readreply(fde_t *fd, void *data)
774   #ifdef IPV6
775      else
776      {
777 <      /*
777 >      /*
778         * If we havent already tried this, and we're looking up AAAA, try A
779         * now
780         */
# Line 771 | Line 790 | res_readreply(fde_t *fd, void *data)
790    }
791  
792    /*
793 <   * If this fails there was an error decoding the received packet,
793 >   * If this fails there was an error decoding the received packet,
794     * try it again and hope it works the next time.
795     */
796    if (proc_answer(request, header, buf, buf + rc))
# Line 791 | Line 810 | res_readreply(fde_t *fd, void *data)
810  
811        /*
812         * Lookup the 'authoritative' name that we were given for the
813 <       * ip#.
813 >       * ip#.
814         *
815         */
816   #ifdef IPV6
# Line 826 | Line 845 | res_readreply(fde_t *fd, void *data)
845   void
846   report_dns_servers(struct Client *source_p)
847   {
848 <  int i;
830 <  char ipaddr[HOSTIPLEN + 1];
848 >  char ipaddr[HOSTIPLEN + 1] = "";
849  
850 <  for (i = 0; i < irc_nscount; i++)
850 >  for (int i = 0; i < irc_nscount; ++i)
851    {
852      getnameinfo((struct sockaddr *)&(irc_nsaddr_list[i]),
853                  irc_nsaddr_list[i].ss_len, ipaddr,
854                  sizeof(ipaddr), NULL, 0, NI_NUMERICHOST);
855 <    sendto_one(source_p, form_str(RPL_STATSALINE),
838 <               me.name, source_p->name, ipaddr);
855 >    sendto_one_numeric(source_p, &me, RPL_STATSALINE, ipaddr);
856    }
857   }

Diff Legend

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