From 705c749aa1a1d1c14073fba86051ea99fe28387d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 30 Jun 2008 12:48:25 +0000 Subject: [PATCH] - 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. --- CHANGES | 13 +++++ ares_init.c | 133 ++++++++++++++++++++++++++++++++++++---------------- nameser.h | 2 - 3 files changed, 105 insertions(+), 43 deletions(-) diff --git a/CHANGES b/CHANGES index d1f2de80..1266fb85 100644 --- a/CHANGES +++ b/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_init.c b/ares_init.c index 0b963710..e33c3973 100644 --- a/ares_init.c +++ b/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/nameser.h b/nameser.h index dc8c86e3..b5add933 100644 --- a/nameser.h +++ b/nameser.h @@ -13,8 +13,6 @@ #ifndef NETWARE -#define MAXHOSTNAMELEN 256 - /* Structure for scatter/gather I/O. */ struct iovec {