diff options
author | ume <ume@FreeBSD.org> | 2002-10-06 08:43:35 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2002-10-06 08:43:35 +0000 |
commit | 7e81d9c8895c5a191873642d607ff2af18d95efb (patch) | |
tree | c6f531613d00c8ce1b12a87a76fa19988dc234d4 /lib | |
parent | 6b6614504c30f1641eea24a76e72a1dc37912ef1 (diff) | |
download | FreeBSD-src-7e81d9c8895c5a191873642d607ff2af18d95efb.zip FreeBSD-src-7e81d9c8895c5a191873642d607ff2af18d95efb.tar.gz |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/net/getaddrinfo.c | 23 | ||||
-rw-r--r-- | lib/libc/net/name6.c | 19 |
2 files changed, 41 insertions, 1 deletions
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index 847f162..92c85e8 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -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; diff --git a/lib/libc/net/name6.c b/lib/libc/net/name6.c index 26008d0..3840052 100644 --- a/lib/libc/net/name6.c +++ b/lib/libc/net/name6.c @@ -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; } |