aboutsummaryrefslogtreecommitdiff
path: root/ares
diff options
context:
space:
mode:
Diffstat (limited to 'ares')
-rw-r--r--ares/CHANGES13
-rw-r--r--ares/ares_init.c133
-rw-r--r--ares/nameser.h2
3 files changed, 105 insertions, 43 deletions
diff --git a/ares/CHANGES b/ares/CHANGES
index d1f2de800..1266fb854 100644
--- a/ares/CHANGES
+++ b/ares/CHANGES
@@ -1,5 +1,18 @@
Changelog for the c-ares project
+* Jun 30 2008 (Daniel Stenberg)
+
+- As was pointed out to me by Andreas Schuldei, the MAXHOSTNAMELEN define is
+ not posix or anything and thus c-ares failed to build on hurd (and possibly
+ elsewhere). The define was also somewhat artificially used in the windows
+ port. Now, I instead rewrote the use of gethostbyname to enlarge the host
+ name buffer in case of need and totally avoid the use of the MAXHOSTNAMELEN
+ define. I thus also removed the defien from the namser.h file where it was
+ once added for the windows build.
+
+ I also fixed init_by_defaults() function to not leak memory in case if
+ error.
+
* Jun 9 2008 (Yang Tse)
- Make libcares.pc generated file for pkg-config include information relative
diff --git a/ares/ares_init.c b/ares/ares_init.c
index 0b9637105..e33c3973a 100644
--- a/ares/ares_init.c
+++ b/ares/ares_init.c
@@ -912,7 +912,8 @@ okay:
static int init_by_defaults(ares_channel channel)
{
- char hostname[MAXHOSTNAMELEN + 1];
+ char *hostname = NULL;
+ int rc = ARES_SUCCESS;
if (channel->flags == -1)
channel->flags = 0;
@@ -927,53 +928,103 @@ static int init_by_defaults(ares_channel channel)
if (channel->tcp_port == -1)
channel->tcp_port = htons(NAMESERVER_PORT);
- if (channel->nservers == -1)
- {
- /* If nobody specified servers, try a local named. */
- channel->servers = malloc(sizeof(struct server_state));
- if (!channel->servers)
- return ARES_ENOMEM;
- channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
- channel->nservers = 1;
+ if (channel->nservers == -1) {
+ /* If nobody specified servers, try a local named. */
+ channel->servers = malloc(sizeof(struct server_state));
+ if (!channel->servers) {
+ rc = ARES_ENOMEM;
+ goto error;
}
+ channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
+ channel->nservers = 1;
+ }
- if (channel->ndomains == -1)
- {
- /* Derive a default domain search list from the kernel hostname,
- * or set it to empty if the hostname isn't helpful.
- */
- if (gethostname(hostname, sizeof(hostname)) == -1
- || !strchr(hostname, '.'))
- {
- channel->ndomains = 0;
- }
- else
- {
- channel->domains = malloc(sizeof(char *));
- if (!channel->domains)
- return ARES_ENOMEM;
- channel->ndomains = 0;
- channel->domains[0] = strdup(strchr(hostname, '.') + 1);
- if (!channel->domains[0])
- return ARES_ENOMEM;
- channel->ndomains = 1;
- }
- }
+#ifdef ENAMETOOLONG
+#define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
+#else
+#define toolong(x) (x == -1) && (EINVAL == errno)
+#endif
- if (channel->nsort == -1)
- {
- channel->sortlist = NULL;
- channel->nsort = 0;
+ if (channel->ndomains == -1) {
+ /* Derive a default domain search list from the kernel hostname,
+ * or set it to empty if the hostname isn't helpful.
+ */
+ size_t len = 64;
+ int res;
+
+ hostname = (char *)malloc(len);
+ if(!hostname) {
+ rc = ARES_ENOMEM;
+ goto error;
}
- if (!channel->lookups)
- {
- channel->lookups = strdup("fb");
- if (!channel->lookups)
- return ARES_ENOMEM;
+ do {
+ res = gethostname(hostname, len);
+
+ if(toolong(res)) {
+ char *p;
+ len *= 2;
+ p = realloc(hostname, len);
+ if(!p) {
+ rc = ARES_ENOMEM;
+ goto error;
+ }
+ hostname = p;
+ continue;
+ }
+ else if(res) {
+ rc = ARES_EBADNAME;
+ goto error;
+ }
+
+ } while(0);
+
+ channel->ndomains = 0; /* default to none */
+ if (strchr(hostname, '.')) {
+ /* a dot was found */
+
+ channel->domains = malloc(sizeof(char *));
+ if (!channel->domains) {
+ rc = ARES_ENOMEM;
+ goto error;
+ }
+ channel->domains[0] = strdup(strchr(hostname, '.') + 1);
+ if (!channel->domains[0]) {
+ rc = ARES_ENOMEM;
+ goto error;
+ }
+ channel->ndomains = 1;
}
+ }
- return ARES_SUCCESS;
+ if (channel->nsort == -1) {
+ channel->sortlist = NULL;
+ channel->nsort = 0;
+ }
+
+ if (!channel->lookups) {
+ channel->lookups = strdup("fb");
+ if (!channel->lookups)
+ rc = ARES_ENOMEM;
+ }
+
+ error:
+ if(rc) {
+ if(channel->servers)
+ free(channel->servers);
+
+ if(channel->domains && channel->domains[0])
+ free(channel->domains[0]);
+ if(channel->domains)
+ free(channel->domains);
+ if(channel->lookups)
+ free(channel->lookups);
+ }
+
+ if(hostname)
+ free(hostname);
+
+ return rc;
}
#ifndef WIN32
diff --git a/ares/nameser.h b/ares/nameser.h
index dc8c86e34..b5add9334 100644
--- a/ares/nameser.h
+++ b/ares/nameser.h
@@ -13,8 +13,6 @@
#ifndef NETWARE
-#define MAXHOSTNAMELEN 256
-
/* Structure for scatter/gather I/O. */
struct iovec
{