diff options
-rw-r--r-- | extra/Configs/Config.in | 9 | ||||
-rw-r--r-- | include/resolv.h | 2 | ||||
-rw-r--r-- | libc/inet/Makefile.in | 7 | ||||
-rw-r--r-- | libc/inet/resolv.c | 149 |
4 files changed, 92 insertions, 75 deletions
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 58a5883b0..8eab394ee 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -672,6 +672,15 @@ config UCLIBC_USE_NETLINK Most people can safely answer N. +config UCLIBC_HAS_BSD_RES_CLOSE + bool "Support res_close() (bsd-compat)" + default n + help + Answer Y if you desperately want to support BSD compatibility in + the network code. + + Most people will say N. + endmenu diff --git a/include/resolv.h b/include/resolv.h index e3c25da36..3434f5d8c 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -274,7 +274,9 @@ void fp_nquery (const u_char *, int, FILE *) __THROW; void fp_query (const u_char *, FILE *) __THROW; const char * hostalias (const char *) __THROW; void p_query (const u_char *) __THROW; +#ifdef __UCLIBC_HAS_BSD_RES_CLOSE__ void res_close (void) __THROW; +#endif int res_init (void) __THROW; int res_isourserver (const struct sockaddr_in *) __THROW; int res_mkquery (int, const char *, int, int, const u_char *, diff --git a/libc/inet/Makefile.in b/libc/inet/Makefile.in index 5545d640e..8cb8661c4 100644 --- a/libc/inet/Makefile.in +++ b/libc/inet/Makefile.in @@ -17,14 +17,17 @@ CSRC += inet_aton.c inet_addr.c inet_ntoa.c inet_makeaddr.c inet_lnaof.c \ # multi source resolv.c CSRC += encodeh.c decodeh.c encoded.c decoded.c lengthd.c encodeq.c \ - decodeq.c lengthq.c encodea.c decodea.c encodep.c decodep.c \ - formquery.c dnslookup.c resolveaddress.c opennameservers.c \ + decodeq.c lengthq.c encodea.c decodea.c \ + dnslookup.c resolveaddress.c opennameservers.c \ closenameservers.c resolvename.c gethostbyname.c res_init.c \ res_query.c gethostbyaddr.c read_etc_hosts_r.c get_hosts_byname_r.c \ get_hosts_byaddr_r.c gethostbyname2.c getnameinfo.c gethostent.c \ gethostbyname_r.c gethostbyname2_r.c gethostbyaddr_r.c \ res_comp.c ns_name.c +# unused ATM +CSRC += encodep.c decodep.c formquery.c + # multi source socketcalls.c CSRC += accept.c bind.c connect.c getpeername.c getsockname.c getsockopt.c \ listen.c recv.c recvfrom.c recvmsg.c send.c sendmsg.c sendto.c \ diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index c2ff58242..b53d0a0f2 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -265,7 +265,7 @@ struct resolv_answer { int aclass; int ttl; int rdlength; - unsigned char * rdata; + const unsigned char * rdata; int rdoffset; char* buf; size_t buflen; @@ -300,21 +300,21 @@ extern int __dns_lookup(const char * name, int type, int nscount, char ** nsip, unsigned char ** outpacket, struct resolv_answer * a) attribute_hidden; extern int __encode_dotted(const char * dotted, unsigned char * dest, int maxlen) attribute_hidden; -extern int __decode_dotted(const unsigned char * message, int offset, +extern int __decode_dotted(const unsigned char * const message, int offset, char * dest, int maxlen) attribute_hidden; -extern int __length_dotted(const unsigned char * message, int offset) attribute_hidden; +extern int __length_dotted(const unsigned char * const message, int offset) attribute_hidden; extern int __encode_header(struct resolv_header * h, unsigned char * dest, int maxlen) attribute_hidden; extern int __decode_header(unsigned char * data, struct resolv_header * h) attribute_hidden; -extern int __encode_question(struct resolv_question * q, +extern int __encode_question(const struct resolv_question * const q, unsigned char * dest, int maxlen) attribute_hidden; -extern int __decode_question(unsigned char * message, int offset, +extern int __decode_question(const unsigned char * const message, int offset, struct resolv_question * q) attribute_hidden; extern int __encode_answer(struct resolv_answer * a, unsigned char * dest, int maxlen) attribute_hidden; -extern int __decode_answer(unsigned char * message, int offset, +extern int __decode_answer(const unsigned char * message, int offset, struct resolv_answer * a) attribute_hidden; -extern int __length_question(unsigned char * message, int offset) attribute_hidden; -extern int __open_nameservers(void) attribute_hidden; +extern int __length_question(const unsigned char * const message, int offset) attribute_hidden; +extern void __open_nameservers(void) attribute_hidden; extern void __close_nameservers(void) attribute_hidden; extern int __dn_expand(const u_char *, const u_char *, const u_char *, char *, int); @@ -373,7 +373,7 @@ int attribute_hidden __decode_header(unsigned char *data, struct resolv_header * int attribute_hidden __encode_dotted(const char *dotted, unsigned char *dest, int maxlen) { - int used = 0; + unsigned used = 0; while (dotted && *dotted) { char *c = strchr(dotted, '.'); @@ -405,13 +405,13 @@ int attribute_hidden __encode_dotted(const char *dotted, unsigned char *dest, in /* Decode a dotted string from nameserver transport-level encoding. This routine understands compressed data. */ -int attribute_hidden __decode_dotted(const unsigned char *data, int offset, +int attribute_hidden __decode_dotted(const unsigned char * const data, int offset, char *dest, int maxlen) { int l; - int measure = 1; - int total = 0; - int used = 0; + bool measure = 1; + unsigned total = 0; + unsigned used = 0; if (!data) return -1; @@ -455,7 +455,7 @@ int attribute_hidden __decode_dotted(const unsigned char *data, int offset, #endif #ifdef L_lengthd -int attribute_hidden __length_dotted(const unsigned char *data, int offset) +int attribute_hidden __length_dotted(const unsigned char * const data, int offset) { int orig_offset = offset; int l; @@ -478,7 +478,7 @@ int attribute_hidden __length_dotted(const unsigned char *data, int offset) #endif #ifdef L_encodeq -int attribute_hidden __encode_question(struct resolv_question *q, +int attribute_hidden __encode_question(const struct resolv_question * const q, unsigned char *dest, int maxlen) { int i; @@ -503,7 +503,7 @@ int attribute_hidden __encode_question(struct resolv_question *q, #endif #ifdef L_decodeq -int attribute_hidden __decode_question(unsigned char *message, int offset, +int attribute_hidden __decode_question(const unsigned char * const message, int offset, struct resolv_question *q) { char temp[256]; @@ -524,7 +524,7 @@ int attribute_hidden __decode_question(unsigned char *message, int offset, #endif #ifdef L_lengthq -int attribute_hidden __length_question(unsigned char *message, int offset) +int attribute_hidden __length_question(const unsigned char * const message, int offset) { int i; @@ -568,7 +568,7 @@ int attribute_hidden __encode_answer(struct resolv_answer *a, unsigned char *des #endif #ifdef L_decodea -int attribute_hidden __decode_answer(unsigned char *message, int offset, +int attribute_hidden __decode_answer(const unsigned char *message, int offset, struct resolv_answer *a) { char temp[256]; @@ -614,7 +614,7 @@ int __encode_packet(struct resolv_header *h, unsigned char *dest, int maxlen) { int i, total = 0; - int j; + unsigned j; i = __encode_header(h, dest, maxlen); if (i < 0) @@ -717,15 +717,15 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char struct resolv_header h; struct resolv_question q; struct resolv_answer ma; - int first_answer = 1; - int retries = 0; + bool first_answer = 1; + unsigned retries = 0; unsigned char * packet = malloc(PACKETSZ); char *dns, *lookup = malloc(MAXDNAME); int variant = -1; struct sockaddr_in sa; int local_ns = -1, local_id = -1; #ifdef __UCLIBC_HAS_IPV6__ - int v6; + bool v6; struct sockaddr_in6 sa6; #endif @@ -1032,14 +1032,14 @@ __UCLIBC_MUTEX_INIT(__resolv_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); * unix systems, we can have a list of nameservers after the keyword. */ -int attribute_hidden __open_nameservers() +void attribute_hidden __open_nameservers() { FILE *fp; int i; #define RESOLV_ARGS 5 char szBuffer[128], *p, *argv[RESOLV_ARGS]; int argc; - int rv = 0; + /* int rv = 0; */ __UCLIBC_MUTEX_LOCK(__resolv_lock); if (__nameservers > 0) { @@ -1091,11 +1091,11 @@ int attribute_hidden __open_nameservers() DPRINTF("failed to open %s\n", "resolv.conf"); h_errno = NO_RECOVERY; - rv = -1; + /* rv = -1; */ DONE: __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - return rv; + /* return rv; */ } #endif @@ -1207,10 +1207,13 @@ int res_init(void) } libc_hidden_def(res_init) +#ifdef __UCLIBC_HAS_BSD_RES_CLOSE__ void res_close( void ) { - return; + __close_nameservers(); + memset(&_res, 0, sizeof(_res)); } +#endif #endif @@ -1270,6 +1273,10 @@ libc_hidden_def(res_query) * If enabled, implement search rules until answer or unrecoverable failure * is detected. Error code, if any, is left in h_errno. */ +#define __TRAILING_DOT (1<<0) +#define __GOT_NODATA (1<<1) +#define __GOT_SERVFAIL (1<<2) +#define __TRIED_AS_IS (1<<3) int res_search(name, class, type, answer, anslen) const char *name; /* domain name */ int class, type; /* class and type of query */ @@ -1279,8 +1286,8 @@ int res_search(name, class, type, answer, anslen) const char *cp, * const *domain; HEADER *hp = (HEADER *)(void *)answer; u_int dots; - int trailing_dot, ret, saved_herrno; - int got_nodata = 0, got_servfail = 0, tried_as_is = 0; + unsigned _state = 0; + int ret, saved_herrno; u_long _res_options; unsigned _res_ndots; char **_res_dnsrch; @@ -1298,9 +1305,9 @@ int res_search(name, class, type, answer, anslen) dots = 0; for (cp = name; *cp; cp++) dots += (*cp == '.'); - trailing_dot = 0; + if (cp > name && *--cp == '.') - trailing_dot++; + _state |= __TRAILING_DOT; /* * If there are dots in the name already, let's just give it a try @@ -1315,7 +1322,7 @@ int res_search(name, class, type, answer, anslen) if (ret > 0) return (ret); saved_herrno = h_errno; - tried_as_is++; + _state |= __TRIED_AS_IS; } /* @@ -1329,8 +1336,8 @@ int res_search(name, class, type, answer, anslen) _res_dnsrch = _res.dnsrch; __UCLIBC_MUTEX_UNLOCK(__resolv_lock); if ((!dots && (_res_options & RES_DEFNAMES)) || - (dots && !trailing_dot && (_res_options & RES_DNSRCH))) { - int done = 0; + (dots && !(_state & __TRAILING_DOT) && (_res_options & RES_DNSRCH))) { + bool done = 0; for (domain = (const char * const *)_res_dnsrch; *domain && !done; @@ -1361,7 +1368,7 @@ int res_search(name, class, type, answer, anslen) switch (h_errno) { case NO_DATA: - got_nodata++; + _state |= __GOT_NODATA; /* FALLTHROUGH */ case HOST_NOT_FOUND: /* keep trying */ @@ -1369,13 +1376,13 @@ int res_search(name, class, type, answer, anslen) case TRY_AGAIN: if (hp->rcode == SERVFAIL) { /* try next search element, if any */ - got_servfail++; + _state |= __GOT_SERVFAIL; break; } /* FALLTHROUGH */ default: /* anything else implies that we're done */ - done++; + done = 1; } /* * if we got here for some reason other than DNSRCH, @@ -1385,7 +1392,7 @@ int res_search(name, class, type, answer, anslen) _res_options = _res.options; __UCLIBC_MUTEX_UNLOCK(__resolv_lock); if (!(_res_options & RES_DNSRCH)) - done++; + done = 1; } } @@ -1394,7 +1401,7 @@ int res_search(name, class, type, answer, anslen) * note that we do this regardless of how many dots were in the * name or whether it ends with a dot. */ - if (!tried_as_is) { + if (!(_state & __TRIED_AS_IS)) { ret = res_querydomain(name, NULL, class, type, answer, anslen); if (ret > 0) return (ret); @@ -1410,13 +1417,16 @@ int res_search(name, class, type, answer, anslen) */ if (saved_herrno != -1) h_errno = saved_herrno; - else if (got_nodata) + else if (_state & __GOT_NODATA) h_errno = NO_DATA; - else if (got_servfail) + else if (_state & __GOT_SERVFAIL) h_errno = TRY_AGAIN; return (-1); } - +#undef __TRAILING_DOT +#undef __GOT_NODATA +#undef __GOT_SERVFAIL +#undef __TRIED_AS_IS /* * Perform a call on res_query on the concatenation of name and domain, * removing a trailing dot from name if domain is NULL. @@ -1695,15 +1705,15 @@ int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen, if (__gethostent_fp == NULL) { __open_etc_hosts(&__gethostent_fp); if (__gethostent_fp == NULL) { - *result=NULL; - ret=TRY_AGAIN; + *result = NULL; + ret = TRY_AGAIN; goto DONE; } } ret = __read_etc_hosts_r(__gethostent_fp, NULL, AF_INET, GETHOSTENT, result_buf, buf, buflen, result, h_errnop); - if (__stay_open==0) { + if (__stay_open == 0) { fclose(__gethostent_fp); } DONE: @@ -1793,7 +1803,7 @@ int getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, unsigned int flags) { int serrno = errno; - int ok = 0; + unsigned ok; struct hostent *h = NULL; char domain[256]; @@ -1801,25 +1811,23 @@ int getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, return EAI_BADFLAGS; if (sa == NULL || addrlen < sizeof (sa_family_t)) - return EAI_FAMILY; + goto BAD_FAM; - switch (sa->sa_family) { - case AF_LOCAL: - break; - case AF_INET: + ok = sa->sa_family; + if (ok == AF_LOCAL) /* valid */; + else if (ok == AF_INET) { if (addrlen < sizeof (struct sockaddr_in)) - return EAI_FAMILY; - break; + goto BAD_FAM; #ifdef __UCLIBC_HAS_IPV6__ - case AF_INET6: + } else if (ok == AF_INET6) { if (addrlen < sizeof (struct sockaddr_in6)) - return EAI_FAMILY; - break; + goto BAD_FAM; #endif /* __UCLIBC_HAS_IPV6__ */ - default: + } else +BAD_FAM: return EAI_FAMILY; - } + ok = 0; if (host != NULL && hostlen > 0) switch (sa->sa_family) { case AF_INET: @@ -1939,34 +1947,29 @@ int getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, strncpy (host, "localhost", hostlen); break; - default: +/*Already checked above default: return EAI_FAMILY; +*/ } if (serv && (servlen > 0)) { - switch (sa->sa_family) { - case AF_INET: -#ifdef __UCLIBC_HAS_IPV6__ - case AF_INET6: -#endif /* __UCLIBC_HAS_IPV6__ */ + if (sa->sa_family == AF_LOCAL) { + strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen); + } else { /* AF_INET || AF_INET6 */ if (!(flags & NI_NUMERICSERV)) { struct servent *s; s = getservbyport (((const struct sockaddr_in *) sa)->sin_port, ((flags & NI_DGRAM) ? "udp" : "tcp")); if (s) { strncpy (serv, s->s_name, servlen); - break; + goto DONE; } } snprintf (serv, servlen, "%d", ntohs (((const struct sockaddr_in *) sa)->sin_port)); - break; - - case AF_LOCAL: - strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen); - break; } } +DONE: if (host && (hostlen > 0)) host[hostlen-1] = 0; if (serv && (servlen > 0)) @@ -2399,8 +2402,8 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type, for (i = len - 1; i >= 0; i--) { qp += sprintf(qp, "%x.%x.", in6->s6_addr[i] & 0xf, (in6->s6_addr[i] >> 4) & 0xf); - } - strcpy(qp, "ip6.int"); + } + strcpy(qp, "ip6.int"); #endif /* __UCLIBC_HAS_IPV6__ */ } @@ -2452,7 +2455,7 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type, } else { result_buf->h_length = sizeof(*in6); #endif /* __UCLIBC_HAS_IPV6__ */ - } + } result_buf->h_addr_list = (char **) addr_list; result_buf->h_aliases = alias; |