avoid an overflow if an excessive amount of servers are used
[platform/upstream/c-ares.git] / ares_getsock.c
1 /* $Id$ */
2
3 /* Copyright (C) 2005 - 2006, Daniel Stenberg
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation for any purpose and without fee is hereby granted, provided
7  * that the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the name of M.I.T. not be used in advertising or
10  * publicity pertaining to distribution of the software without specific,
11  * written prior permission.  M.I.T. makes no representations about the
12  * suitability of this software for any purpose.  It is provided "as is"
13  * without express or implied warranty.
14  */
15
16 #include "setup.h"
17 #include <sys/types.h>
18
19 #ifdef HAVE_SYS_TIME_H
20 #include <sys/time.h>
21 #endif
22
23 #include "ares.h"
24 #include "ares_private.h"
25
26 int ares_getsock(ares_channel channel,
27                  int *s,
28                  int numsocks) /* size of the 'socks' array */
29 {
30   struct server_state *server;
31   int i;
32   int sockindex=0;
33   int bitmap = 0;
34   unsigned int setbits = 0xffffffff;
35
36   ares_socket_t *socks = (ares_socket_t *)s;
37
38   /* No queries, no file descriptors. */
39   if (!channel->queries)
40     return 0;
41
42   for (i = 0;
43        (i < channel->nservers) && (sockindex < ARES_GETSOCK_MAXNUM);
44        i++)
45     {
46       server = &channel->servers[i];
47       if (server->udp_socket != ARES_SOCKET_BAD)
48         {
49           if(sockindex >= numsocks)
50             break;
51           socks[sockindex] = server->udp_socket;
52           bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
53           sockindex++;
54         }
55       if (server->tcp_socket != ARES_SOCKET_BAD)
56        {
57          if(sockindex >= numsocks)
58            break;
59          socks[sockindex] = server->tcp_socket;
60          bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
61
62          if (server->qhead)
63            /* then the tcp socket is also writable! */
64            bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex);
65
66          sockindex++;
67        }
68     }
69   return bitmap;
70 }