mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 22:35:15 +00:00
socket-util: Use getaddrinfo() instead of gethostbyname() for thread safety.
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
@@ -178,30 +178,57 @@ lookup_ipv6(const char *host_name, struct in6_addr *addr)
|
||||
* successful, otherwise a positive errno value.
|
||||
*
|
||||
* Most Open vSwitch code should not use this because it causes deadlocks:
|
||||
* gethostbyname() sends out a DNS request but that starts a new flow for which
|
||||
* getaddrinfo() sends out a DNS request but that starts a new flow for which
|
||||
* OVS must set up a flow, but it can't because it's waiting for a DNS reply.
|
||||
* The synchronous lookup also delays other activity. (Of course we can solve
|
||||
* this but it doesn't seem worthwhile quite yet.) */
|
||||
int
|
||||
lookup_hostname(const char *host_name, struct in_addr *addr)
|
||||
{
|
||||
struct hostent *h;
|
||||
struct addrinfo *result;
|
||||
struct addrinfo hints;
|
||||
|
||||
if (inet_aton(host_name, addr)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
h = gethostbyname(host_name);
|
||||
if (h) {
|
||||
*addr = *(struct in_addr *) h->h_addr;
|
||||
return 0;
|
||||
}
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_INET;
|
||||
|
||||
return (h_errno == HOST_NOT_FOUND ? ENOENT
|
||||
: h_errno == TRY_AGAIN ? EAGAIN
|
||||
: h_errno == NO_RECOVERY ? EIO
|
||||
: h_errno == NO_ADDRESS ? ENXIO
|
||||
: EINVAL);
|
||||
switch (getaddrinfo(host_name, NULL, &hints, &result)) {
|
||||
case 0:
|
||||
*addr = ((struct sockaddr_in *) result->ai_addr)->sin_addr;
|
||||
freeaddrinfo(result);
|
||||
return 0;
|
||||
|
||||
case EAI_ADDRFAMILY:
|
||||
case EAI_NONAME:
|
||||
case EAI_SERVICE:
|
||||
return ENOENT;
|
||||
|
||||
case EAI_AGAIN:
|
||||
return EAGAIN;
|
||||
|
||||
case EAI_BADFLAGS:
|
||||
case EAI_FAMILY:
|
||||
case EAI_SOCKTYPE:
|
||||
return EINVAL;
|
||||
|
||||
case EAI_FAIL:
|
||||
return EIO;
|
||||
|
||||
case EAI_MEMORY:
|
||||
return ENOMEM;
|
||||
|
||||
case EAI_NODATA:
|
||||
return ENXIO;
|
||||
|
||||
case EAI_SYSTEM:
|
||||
return errno;
|
||||
|
||||
default:
|
||||
return EPROTO;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
Reference in New Issue
Block a user