diff options
Diffstat (limited to 'libc')
| -rw-r--r-- | libc/inet/resolv.c | 102 | 
1 files changed, 80 insertions, 22 deletions
| diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 177424d51..4651896a5 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -83,12 +83,22 @@  #endif /* DEBUG */ -/* Global stuff... */ +/* Global stuff (stuff needing to be locked to be thread safe)... */  extern int __nameservers;  extern char * __nameserver[MAX_SERVERS];  extern int __searchdomains;  extern char * __searchdomain[MAX_SEARCH]; +#ifdef __UCLIBC_HAS_THREADS__ +#include <pthread.h> +extern pthread_mutex_t __resolv_lock; +# define BIGLOCK	pthread_mutex_lock(&__resolv_lock) +# define BIGUNLOCK	pthread_mutex_unlock(&__resolv_lock); +#else +# define BIGLOCK +# define BIGUNLOCK +#endif +  /* Structs */ @@ -573,7 +583,6 @@ int __connect_dns(char *nsip)  #ifdef L_dnslookup  #ifdef __UCLIBC_HAS_THREADS__ -#include <pthread.h>  static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;  # define LOCK	pthread_mutex_lock(&mylock)  # define UNLOCK	pthread_mutex_unlock(&mylock); @@ -636,11 +645,13 @@ int __dns_lookup(const char *name, int type, int nscount, char **nsip,  			goto fail;  		strncpy(lookup,name,MAXDNAME); +		BIGLOCK;  		if (variant < __searchdomains && strchr(lookup, '.') == NULL)  		{  		    strncat(lookup,".", MAXDNAME);  		    strncat(lookup,__searchdomain[variant], MAXDNAME);  		} +		BIGUNLOCK;  		DPRINTF("lookup name: %s\n", lookup);  		q.dotted = (char *)lookup;  		q.qtype = type; @@ -755,21 +766,35 @@ int __dns_lookup(const char *name, int type, int nscount, char **nsip,  	  tryall:  		/* if there are other nameservers, give them a go,  		   otherwise return with error */ -		variant = 0; -		if (retries >= nscount*(__searchdomains+1)) -		    goto fail; +		{ +		    int sdomains; + +		    BIGLOCK; +		    sdomains=__searchdomains; +		    BIGUNLOCK; +		    variant = 0; +		    if (retries >= nscount*(sdomains+1)) +			goto fail; +		}  	  again:  		/* if there are searchdomains, try them or fallback as passed */ -		if (variant < __searchdomains) { -		    /* next search */ -		    variant++; -		} else { -		    /* next server, first search */ -		    LOCK; -		    ns = (ns + 1) % nscount; -		    UNLOCK; -		    variant = 0; +		{ +		    int sdomains; +		    BIGLOCK; +		    sdomains=__searchdomains; +		    BIGUNLOCK; + +		    if (variant < sdomains) { +			/* next search */ +			variant++; +		    } else { +			/* next server, first search */ +			LOCK; +			ns = (ns + 1) % nscount; +			UNLOCK; +			variant = 0; +		    }  		}  	} @@ -786,11 +811,13 @@ fail:  #ifdef L_opennameservers -#warning fixme -- __nameserver, __nameservers, __searchdomain, and __searchdomains need locking  int __nameservers;  char * __nameserver[MAX_SERVERS];  int __searchdomains;  char * __searchdomain[MAX_SEARCH]; +#ifdef __UCLIBC_HAS_THREADS__ +pthread_mutex_t __resolv_lock = PTHREAD_MUTEX_INITIALIZER; +#endif  /*   *	we currently read formats not quite the same as that on normal @@ -805,8 +832,11 @@ int __open_nameservers()  	char szBuffer[128], *p, *argv[RESOLV_ARGS];  	int argc; -	if (__nameservers > 0)  +	BIGLOCK; +	if (__nameservers > 0) {  +	    BIGUNLOCK;  	    return 0; +	}  	if ((fp = fopen("/etc/resolv.conf", "r")) ||  			(fp = fopen("/etc/config/resolv.conf", "r"))) { @@ -850,6 +880,7 @@ int __open_nameservers()  	    DPRINTF("failed to open %s\n", "resolv.conf");  	}  	DPRINTF("nameservers = %d\n", __nameservers); +	BIGUNLOCK;  	return 0;  }  #endif @@ -859,6 +890,7 @@ int __open_nameservers()  void __close_nameservers(void)  { +	BIGLOCK;  	while (__nameservers > 0) {  		free(__nameserver[--__nameservers]);  		__nameserver[__nameservers] = NULL; @@ -867,6 +899,7 @@ void __close_nameservers(void)  		free(__searchdomain[--__searchdomains]);  		__searchdomain[__searchdomains] = NULL;  	} +	BIGUNLOCK;  }  #endif @@ -955,6 +988,7 @@ int res_init(void)  	/** rp->rhook = NULL; **/  	/** rp->_u._ext.nsinit = 0; **/ +	BIGLOCK;  	if(__searchdomains) {  		int i;  		for(i=0; i<__searchdomains; i++) { @@ -974,6 +1008,7 @@ int res_init(void)  		}  	}  	rp->nscount = __nameservers; +	BIGUNLOCK;  	return(0);  } @@ -1007,9 +1042,11 @@ void res_close( void )  int res_query(const char *dname, int class, int type,                unsigned char *answer, int anslen)  { +	int i;  	unsigned char * packet = 0;  	struct resolv_answer a; -	int i; +	int __nameserversXX; +	char ** __nameserverXX;  	__open_nameservers(); @@ -1018,7 +1055,11 @@ int res_query(const char *dname, int class, int type,  	memset((char *) &a, '\0', sizeof(a)); -	i = __dns_lookup(dname, type, __nameservers, __nameserver, &packet, &a); +	BIGLOCK; +	__nameserversXX=__nameservers; +	__nameserverXX=__nameserver; +	BIGUNLOCK; +	i = __dns_lookup(dname, type, __nameserversXX, __nameserverXX, &packet, &a);  	if (i < 0)  		return(-1); @@ -1215,7 +1256,6 @@ int __read_etc_hosts_r(FILE * fp, const char * name, int type,  #ifdef L_gethostent  #ifdef __UCLIBC_HAS_THREADS__ -#include <pthread.h>  static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;  # define LOCK	pthread_mutex_lock(&mylock)  # define UNLOCK	pthread_mutex_unlock(&mylock); @@ -1532,6 +1572,8 @@ int gethostbyname_r(const char * name,  	struct resolv_answer a;  	int i;  	int nest = 0; +	int __nameserversXX; +	char ** __nameserverXX;  	__open_nameservers(); @@ -1591,7 +1633,11 @@ int gethostbyname_r(const char * name,  	for (;;) { -		i = __dns_lookup(buf, T_A, __nameservers, __nameserver, &packet, &a); +	BIGLOCK; +	__nameserversXX=__nameservers; +	__nameserverXX=__nameserver; +	BIGUNLOCK; +		i = __dns_lookup(buf, T_A, __nameserversXX, __nameserverXX, &packet, &a);  		if (i < 0) {  			*h_errnop = HOST_NOT_FOUND; @@ -1665,6 +1711,8 @@ int gethostbyname2_r(const char *name, int family,  	struct resolv_answer a;  	int i;  	int nest = 0; +	int __nameserversXX; +	char ** __nameserverXX;  	if (family == AF_INET)  		return gethostbyname_r(name, result_buf, buf, buflen, result, h_errnop); @@ -1724,8 +1772,12 @@ int gethostbyname2_r(const char *name, int family,  	}  	for (;;) { +	BIGLOCK; +	__nameserversXX=__nameservers; +	__nameserverXX=__nameserver; +	BIGUNLOCK; -		i = __dns_lookup(buf, T_AAAA, __nameservers, __nameserver, &packet, &a); +		i = __dns_lookup(buf, T_AAAA, __nameserversXX, __nameserverXX, &packet, &a);  		if (i < 0) {  			*h_errnop = HOST_NOT_FOUND; @@ -1790,6 +1842,8 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,  	struct resolv_answer a;  	int i;  	int nest = 0; +	int __nameserversXX; +	char ** __nameserverXX;  	*result=NULL;  	if (!addr) @@ -1892,7 +1946,11 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,  	for (;;) { -		i = __dns_lookup(buf, T_PTR, __nameservers, __nameserver, &packet, &a); +	BIGLOCK; +	__nameserversXX=__nameservers; +	__nameserverXX=__nameserver; +	BIGUNLOCK; +		i = __dns_lookup(buf, T_PTR, __nameserversXX, __nameserverXX, &packet, &a);  		if (i < 0) {  			*h_errnop = HOST_NOT_FOUND; | 
