00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00052
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
00066
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
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
00090 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
00091 channel->nservers = 1;
00092
00093
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
00106
00107
00108
00109
00110
00111
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
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
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
00156
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
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
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