mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-25 22:15:20 +00:00
util: add API for resolving socket service names
The getservent() APIs are not re-entrant safe so cannot be used in any threaded program. Add a wrapper around getaddrinfo() for resolving the service names to a port number. Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
836f4e0659
commit
012e0d40bf
@ -2903,6 +2903,7 @@ virSocketAddrParseIPv4;
|
|||||||
virSocketAddrParseIPv6;
|
virSocketAddrParseIPv6;
|
||||||
virSocketAddrPrefixToNetmask;
|
virSocketAddrPrefixToNetmask;
|
||||||
virSocketAddrPTRDomain;
|
virSocketAddrPTRDomain;
|
||||||
|
virSocketAddrResolveService;
|
||||||
virSocketAddrSetIPv4Addr;
|
virSocketAddrSetIPv4Addr;
|
||||||
virSocketAddrSetIPv4AddrNetOrder;
|
virSocketAddrSetIPv4AddrNetOrder;
|
||||||
virSocketAddrSetIPv6Addr;
|
virSocketAddrSetIPv6Addr;
|
||||||
|
@ -235,6 +235,57 @@ virSocketAddrParseIPv6(virSocketAddrPtr addr, const char *val)
|
|||||||
return virSocketAddrParse(addr, val, AF_INET6);
|
return virSocketAddrParse(addr, val, AF_INET6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virSocketAddrResolveService:
|
||||||
|
* @service: a service name or port number
|
||||||
|
*
|
||||||
|
* Resolve a service, which might be a plain port or service name,
|
||||||
|
* into a port number for IPv4/IPv6 usage
|
||||||
|
*
|
||||||
|
* Returns a numeric port number, or -1 on error
|
||||||
|
*/
|
||||||
|
int virSocketAddrResolveService(const char *service)
|
||||||
|
{
|
||||||
|
struct addrinfo *res, *tmp;
|
||||||
|
struct addrinfo hints;
|
||||||
|
int err;
|
||||||
|
int port = -1;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
|
||||||
|
if ((err = getaddrinfo(NULL, service, &hints, &res)) != 0) {
|
||||||
|
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||||
|
_("Cannot parse socket service '%s': %s"),
|
||||||
|
service, gai_strerror(err));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = res;
|
||||||
|
while (tmp) {
|
||||||
|
if (tmp->ai_family == AF_INET) {
|
||||||
|
struct sockaddr_in in;
|
||||||
|
memcpy(&in, tmp->ai_addr, sizeof(in));
|
||||||
|
port = in.sin_port;
|
||||||
|
goto cleanup;
|
||||||
|
} else if (tmp->ai_family == AF_INET6) {
|
||||||
|
struct sockaddr_in6 in;
|
||||||
|
memcpy(&in, tmp->ai_addr, sizeof(in));
|
||||||
|
port = in.sin6_port;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
tmp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||||
|
_("No matches for socket service '%s': %s"),
|
||||||
|
service, gai_strerror(err));
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
freeaddrinfo(res);
|
||||||
|
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* virSocketAddrSetIPv4AddrNetOrder:
|
* virSocketAddrSetIPv4AddrNetOrder:
|
||||||
* @addr: the location to store the result
|
* @addr: the location to store the result
|
||||||
|
@ -98,6 +98,8 @@ int virSocketAddrParseIPv4(virSocketAddrPtr addr,
|
|||||||
int virSocketAddrParseIPv6(virSocketAddrPtr addr,
|
int virSocketAddrParseIPv6(virSocketAddrPtr addr,
|
||||||
const char *val);
|
const char *val);
|
||||||
|
|
||||||
|
int virSocketAddrResolveService(const char *service);
|
||||||
|
|
||||||
void virSocketAddrSetIPv4AddrNetOrder(virSocketAddrPtr s, uint32_t addr);
|
void virSocketAddrSetIPv4AddrNetOrder(virSocketAddrPtr s, uint32_t addr);
|
||||||
void virSocketAddrSetIPv4Addr(virSocketAddrPtr s, uint32_t addr);
|
void virSocketAddrSetIPv4Addr(virSocketAddrPtr s, uint32_t addr);
|
||||||
void virSocketAddrSetIPv6AddrNetOrder(virSocketAddrPtr s, uint32_t addr[4]);
|
void virSocketAddrSetIPv6AddrNetOrder(virSocketAddrPtr s, uint32_t addr[4]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user