Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

ares_init.c

Go to the documentation of this file.
00001 /* Copyright 1998 by the Massachusetts Institute of Technology.
00002  *
00003  * Permission to use, copy, modify, and distribute this
00004  * software and its documentation for any purpose and without
00005  * fee is hereby granted, provided that the above copyright
00006  * notice appear in all copies and that both that copyright
00007  * notice and this permission notice appear in supporting
00008  * documentation, and that the name of M.I.T. not be used in
00009  * advertising or publicity pertaining to distribution of the
00010  * software without specific, written prior permission.
00011  * M.I.T. makes no representations about the suitability of
00012  * this software for any purpose.  It is provided "as is"
00013  * without express or implied warranty.
00014  *
00015  * CHANGELOG: this file has been modified by Sergio Perez Alcañiz <serpeal@disca.upv.es> 
00016  *            Departamento de Informática de Sistemas y Computadores          
00017  *            Universidad Politécnica de Valencia                             
00018  *            Valencia (Spain)    
00019  *            Date: April 2003                                          
00020  *
00021  */
00022 
00023 #include "ares_private.h"
00024 
00025 #define htons HTONS
00026 #define htonl HTONL
00027 
00028 extern int gettimeofday(struct timeval *tv, struct timezone *tz);
00029 
00030 static int init_by_options(ares_channel channel, struct ares_options *options,
00031                            int optmask);
00032 static int init_by_defaults(ares_channel channel);
00033 
00034 int ares_init(ares_channel *channelptr)
00035 {
00036   return ares_init_options(channelptr, NULL, 0);
00037 }
00038 
00039 
00040 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
00041                       int optmask)
00042 {
00043   ares_channel channel;
00044   int i, status;
00045   struct server_state *server;
00046 
00047   channel = malloc(sizeof(struct ares_channeldata));
00048   if (!channel)
00049     return ARES_ENOMEM;
00050 
00051   /* Set everything to distinguished values so we know they haven't
00052    * been set yet.
00053    */
00054   channel->flags = -1;
00055   channel->timeout = -1;
00056   channel->tries = -1;
00057   channel->ndots = -1;
00058   channel->udp_port = -1;
00059   channel->tcp_port = -1;
00060   channel->nservers = -1;
00061   channel->ndomains = -1;
00062   channel->nsort = -1;
00063   channel->lookups = NULL;
00064 
00065   /* Initialize configuration by each of the four sources, from highest
00066    * precedence to lowest.
00067    */
00068   status = init_by_options(channel, options, optmask);
00069   if (status == ARES_SUCCESS)
00070     status = init_by_defaults(channel);
00071   if (status != ARES_SUCCESS)
00072     {
00073       /* Something failed; clean up memory we may have allocated. */
00074       if (channel->nservers != -1)
00075         free(channel->servers);
00076       if (channel->ndomains != -1)
00077         {
00078           for (i = 0; i < channel->ndomains; i++)
00079             free(channel->domains[i]);
00080           free(channel->domains);
00081         }
00082       if (channel->nsort != -1)
00083         free(channel->sortlist);
00084       free(channel->lookups);
00085       free(channel);
00086       return status;
00087     }
00088 
00089   /* Trim to one server if ARES_FLAG_PRIMARY is set. */
00090   if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
00091     channel->nservers = 1;
00092 
00093   /* Initialize server states. */
00094   for (i = 0; i < channel->nservers; i++)
00095     {
00096       server = &channel->servers[i];
00097       server->udp_socket = -1;
00098       server->tcp_socket = -1;
00099       server->tcp_lenbuf_pos = 0;
00100       server->tcp_buffer = NULL;
00101       server->qhead = NULL;
00102       server->qtail = NULL;
00103     }
00104 
00105   /* Choose a somewhat random query ID.  The main point is to avoid
00106    * collisions with stale queries.  An attacker trying to spoof a DNS
00107    * answer also has to guess the query ID, but it's only a 16-bit
00108    * field, so there's not much to be done about that.
00109    */
00110 
00111 //  channel->next_id = (RetrieveClock() ^ os_current_process()) & 0xffff;
00112   {
00113     struct timeval time;
00114     gettimeofday(&time,NULL);
00115     channel->next_id = (time.tv_usec ^ time.tv_sec) & 0xffff;
00116   }
00117 
00118   channel->queries = NULL;
00119 
00120   *channelptr = channel;
00121   return ARES_SUCCESS;
00122 }
00123 
00124 static int init_by_options(ares_channel channel, struct ares_options *options,
00125                            int optmask)
00126 {
00127   int i;
00128 
00129   /* Easy stuff. */
00130   if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
00131     channel->flags = options->flags;
00132   if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
00133     channel->timeout = options->timeout;
00134   if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
00135     channel->tries = options->tries;
00136   if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
00137     channel->ndots = options->ndots;
00138   if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
00139     channel->udp_port = options->udp_port;
00140   if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
00141     channel->tcp_port = options->tcp_port;
00142 
00143   /* Copy the servers, if given. */
00144   if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
00145     {
00146       channel->servers =
00147         malloc(options->nservers * sizeof(struct server_state));
00148       if (!channel->servers && options->nservers != 0)
00149         return ARES_ENOMEM;
00150       for (i = 0; i < options->nservers; i++)
00151         channel->servers[i].addr = options->servers[i];
00152       channel->nservers = options->nservers;
00153     }
00154 
00155   /* Copy the domains, if given.  Keep channel->ndomains consistent so
00156    * we can clean up in case of error.
00157    */
00158   if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
00159     {
00160       channel->domains = malloc(options->ndomains * sizeof(char *));
00161       if (!channel->domains && options->ndomains != 0)
00162         return ARES_ENOMEM;
00163       for (i = 0; i < options->ndomains; i++)
00164         {
00165           channel->ndomains = i;
00166           channel->domains[i] = strdup(options->domains[i]);
00167           if (!channel->domains[i])
00168             return ARES_ENOMEM;
00169         }
00170       channel->ndomains = options->ndomains;
00171     }
00172 
00173   /* Set lookups, if given. */
00174   if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
00175     {
00176       channel->lookups = strdup(options->lookups);
00177       if (!channel->lookups)
00178         return ARES_ENOMEM;
00179     }
00180 
00181   return ARES_SUCCESS;
00182 }
00183 
00184 static int init_by_defaults(ares_channel channel)
00185 {
00186   if (channel->flags == -1)
00187     channel->flags = 0;
00188   if (channel->timeout == -1)
00189     channel->timeout = DEFAULT_TIMEOUT;
00190   if (channel->tries == -1)
00191     channel->tries = DEFAULT_TRIES;
00192   if (channel->ndots == -1)
00193     channel->ndots = 1;
00194   if (channel->udp_port == -1)
00195     channel->udp_port = htons(NAMESERVER_PORT);
00196   if (channel->tcp_port == -1)
00197     channel->tcp_port = htons(NAMESERVER_PORT);
00198 
00199   if (channel->nservers == -1)
00200     {
00201       /* If nobody specified servers, try a local named. */
00202       channel->servers = malloc(sizeof(struct server_state));
00203       if (!channel->servers)
00204         return ARES_ENOMEM;
00205       channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
00206       channel->nservers = 1;
00207     }
00208 
00209   if (channel->ndomains == -1)
00210     {
00211       channel->domains = malloc(0);
00212       channel->ndomains = 0;
00213     }
00214 
00215   if (channel->nsort == -1)
00216     {
00217       channel->sortlist = NULL;
00218       channel->nsort = 0;
00219     }
00220 
00221   if (!channel->lookups)
00222     {
00223       channel->lookups = strdup("bf");
00224       if (!channel->lookups)
00225         return ARES_ENOMEM;
00226     }
00227 
00228   return ARES_SUCCESS;
00229 }
00230 

Generated on Wed Jan 14 12:58:55 2004 for RTL-lwIP-0.4 by doxygen 1.3.4