freeswitch/libs/sipcc/plat/common/dns_utils.c

166 lines
3.9 KiB
C

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "cpr_ipc.h"
#include "cpr_types.h"
#ifndef SIP_OS_WINDOWS
#include "netdb.h"
#include "arpa/inet.h"
#endif
#include "dns_utils.h"
#include "phone_debug.h"
#include "util_string.h"
#ifdef SIP_OS_WINDOWS
cc_int32_t
dnsGetHostByName (const char *hname,
cpr_ip_addr_t *ipaddr_ptr,
cc_int32_t timeout,
cc_int32_t retries)
{
return DNS_ERR_NOHOST;
}
#else
/*
* dnsGetHostByName
*
* DESCRIPTION: Perform an DNS lookup of the name specified
*
* RETURNS: returns 0 for success or DNS_ERR_NOHOST
*
*/
cc_int32_t
dnsGetHostByName (const char *hname,
cpr_ip_addr_t *ipaddr_ptr,
cc_int32_t timeout,
cc_int32_t retries)
{
uint32_t ip_address;
struct hostent *dns_response;
#ifdef IPV6_STACK_ENABLED
uint32_t err;
uint16_t ip_valid;
char ip_addr[MAX_IPADDR_STR_LEN];
struct addrinfo hints, *result;
struct sockaddr sa;
#endif
#ifdef IPV6_STACK_ENABLED
/* Check if the IPv6 address */
ip_valid = cpr_inet_pton(AF_INET6, hname, ip_addr);
if (ip_valid) {
ipaddr_ptr->type = CPR_IP_ADDR_IPV6;
cpr_memcopy(ipaddr_ptr->u.ip6.addr.base8, ip_addr, 16);
return(0);
}
#endif
ip_address = inet_addr(hname);
if (ip_address != INADDR_NONE) {
ipaddr_ptr->u.ip4 = ip_address;
ipaddr_ptr->type = CPR_IP_ADDR_IPV4;
return 0;
} else {
#ifdef IPV6_STACK_ENABLED
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_INET6;
err = getaddrinfo(hname, NULL, &hints, &result);
if (err) {
return DNS_ERR_NOHOST;
}
while (result) {
sa = result->ai_addr;
if (sa->family == AF_INET) {
ipaddr_ptr->type = CPR_IP_ADDR_IPV4;
ip_addr->u.ip4 = ((cpr_sockaddr_in_t *)from)->sin_addr.s_addr;
} else if (sa->family == AF_INET6) {
//Todo IPv6: Add getaddrinfo() functioncall to get the IPv6 address.
ipaddr_ptr->type = CPR_IP_ADDR_IPV6;
ip_addr->u.ip6 = ((cpr_sockaddr_in6_t *)sa)->sin6_addr;
}
}
freeaddrinfo(result);
#endif
dns_response = gethostbyname(hname);
if (dns_response) {
ipaddr_ptr->u.ip4 = *(uint32_t *) dns_response->h_addr_list[0];
ipaddr_ptr->type = CPR_IP_ADDR_IPV4;
return 0;
}
}
return DNS_ERR_NOHOST;
}
#endif
#ifdef SIP_OS_WINDOWS
cc_int32_t
dnsGetHostBySRV (cc_int8_t *service,
cc_int8_t *protocol,
cc_int8_t *domain,
cpr_ip_addr_t *ipaddr_ptr,
cc_uint16_t *port,
cc_int32_t timeout,
cc_int32_t retries,
srv_handle_t *psrv_handle)
{
return DNS_ERR_NOHOST;
}
#else
/*
* dnsGetHostBySRV
*
* DESCRIPTION: This function calls the dns api to
* perform a dns srv query
*
* RETURNS: returns 0 for success or
* DNS_ERR_NOHOST, DNS_ERR_HOST_UNAVAIL
*
*/
cc_int32_t
dnsGetHostBySRV (cc_int8_t *service,
cc_int8_t *protocol,
cc_int8_t *domain,
cpr_ip_addr_t *ipaddr_ptr,
cc_uint16_t *port,
cc_int32_t timeout,
cc_int32_t retries,
srv_handle_t *psrv_handle)
{
uint32_t ip_address;
ip_address = inet_addr(domain);
if (ip_address != INADDR_NONE) {
ipaddr_ptr->u.ip4 = ip_address;
ipaddr_ptr->type = CPR_IP_ADDR_IPV4;
return 0;
}
return DNS_ERR_NOBUF; /* not yet implemented */
}
#endif
void
dnsFreeSrvHandle (srv_handle_t srv_handle)
{
// this function does nothing
// srv_handle = NULL;
}