Put giant locks due to make getaddrinfo(), getnameinfo()
and getipnodeby*() thread-safe. Our res_*() is not thread-safe. So, we share lock between getaddrinfo() and getipnodeby*(). Still, we cannot use getaddrinfo() and getipnodeby*() in conjunction with other functions which call res_*(). Requested by: many people
This commit is contained in:
parent
86597d47cb
commit
71918af633
@ -274,6 +274,21 @@ static char *ai_errlist[] = {
|
||||
"Unknown error", /* EAI_MAX */
|
||||
};
|
||||
|
||||
/* Make getaddrinfo() thread-safe in libc for use with kernel threads. */
|
||||
#include "libc_private.h"
|
||||
#include "spinlock.h"
|
||||
/*
|
||||
* XXX: Our res_*() is not thread-safe. So, we share lock between
|
||||
* getaddrinfo() and getipnodeby*(). Still, we cannot use
|
||||
* getaddrinfo() and getipnodeby*() in conjunction with other
|
||||
* functions which call res_*().
|
||||
*/
|
||||
spinlock_t __getaddrinfo_thread_lock = _SPINLOCK_INITIALIZER;
|
||||
#define THREAD_LOCK() \
|
||||
if (__isthreaded) _SPINLOCK(&__getaddrinfo_thread_lock);
|
||||
#define THREAD_UNLOCK() \
|
||||
if (__isthreaded) _SPINUNLOCK(&__getaddrinfo_thread_lock);
|
||||
|
||||
/* XXX macros that make external reference is BAD. */
|
||||
|
||||
#define GET_AI(ai, afd, addr) \
|
||||
@ -599,11 +614,15 @@ explore_fqdn(pai, hostname, servname, res)
|
||||
|
||||
result = NULL;
|
||||
|
||||
THREAD_LOCK();
|
||||
|
||||
/*
|
||||
* if the servname does not match socktype/protocol, ignore it.
|
||||
*/
|
||||
if (get_portmatch(pai, servname) != 0)
|
||||
if (get_portmatch(pai, servname) != 0) {
|
||||
THREAD_UNLOCK();
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo",
|
||||
default_dns_files, hostname, pai)) {
|
||||
@ -624,12 +643,14 @@ explore_fqdn(pai, hostname, servname, res)
|
||||
}
|
||||
break;
|
||||
}
|
||||
THREAD_UNLOCK();
|
||||
|
||||
*res = result;
|
||||
|
||||
return 0;
|
||||
|
||||
free:
|
||||
THREAD_UNLOCK();
|
||||
if (result)
|
||||
freeaddrinfo(result);
|
||||
return error;
|
||||
|
@ -191,6 +191,21 @@ static void _dns_ehent(void);
|
||||
static int _icmp_ghbyaddr(void *, void *, va_list);
|
||||
#endif /* ICMPNL */
|
||||
|
||||
/* Make getipnodeby*() thread-safe in libc for use with kernel threads. */
|
||||
#include "libc_private.h"
|
||||
#include "spinlock.h"
|
||||
/*
|
||||
* XXX: Our res_*() is not thread-safe. So, we share lock between
|
||||
* getaddrinfo() and getipnodeby*(). Still, we cannot use
|
||||
* getaddrinfo() and getipnodeby*() in conjunction with other
|
||||
* functions which call res_*().
|
||||
*/
|
||||
extern spinlock_t __getaddrinfo_thread_lock;
|
||||
#define THREAD_LOCK() \
|
||||
if (__isthreaded) _SPINLOCK(&__getaddrinfo_thread_lock);
|
||||
#define THREAD_UNLOCK() \
|
||||
if (__isthreaded) _SPINUNLOCK(&__getaddrinfo_thread_lock);
|
||||
|
||||
/* Host lookup order if nsswitch.conf is broken or nonexistant */
|
||||
static const ns_src default_src[] = {
|
||||
{ NSSRC_FILES, NS_SUCCESS },
|
||||
@ -277,8 +292,10 @@ _ghbyname(const char *name, int af, int flags, int *errp)
|
||||
}
|
||||
}
|
||||
|
||||
THREAD_LOCK();
|
||||
rval = nsdispatch(&hp, dtab, NSDB_HOSTS, "ghbyname", default_src,
|
||||
name, af, errp);
|
||||
THREAD_UNLOCK();
|
||||
return (rval == NS_SUCCESS) ? hp : NULL;
|
||||
}
|
||||
|
||||
@ -422,8 +439,10 @@ getipnodebyaddr(const void *src, size_t len, int af, int *errp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
THREAD_LOCK();
|
||||
rval = nsdispatch(&hp, dtab, NSDB_HOSTS, "ghbyaddr", default_src,
|
||||
src, len, af, errp);
|
||||
THREAD_UNLOCK();
|
||||
return (rval == NS_SUCCESS) ? hp : NULL;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user