Commit 934612c9 authored by Ghislain MARY's avatar Ghislain MARY

Move belle_sip_getaddrinfo() to bctoolbox.

parent 4eb8564a
......@@ -200,9 +200,6 @@ typedef int belle_sip_fd_t;
#endif
BELLESIP_EXPORT int belle_sip_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
BELLESIP_EXPORT void belle_sip_freeaddrinfo(struct addrinfo *res);
typedef void (*belle_sip_background_task_end_callback_t)(void *);
BELLESIP_EXPORT unsigned long belle_sip_begin_background_task(const char *name, belle_sip_background_task_end_callback_t cb, void *data);
......
......@@ -28,6 +28,7 @@
#include "belle-sip/belle-sip.h"
#include "port.h"
#include <bctoolbox/port.h>
#ifdef HAVE_CONFIG_H
......
......@@ -64,7 +64,7 @@ static void belle_sip_dns_srv_destroy(belle_sip_dns_srv_t *obj){
obj->a_resolver=NULL;
}
if (obj->a_results){
belle_sip_freeaddrinfo(obj->a_results);
bctbx_freeaddrinfo(obj->a_results);
obj->a_results=NULL;
}
}
......@@ -713,7 +713,7 @@ struct addrinfo * belle_sip_ip_address_to_addrinfo(int family, const char *ipadd
if (family==AF_INET6 && strchr(ipaddress,':')==NULL) {
hints.ai_flags|=AI_V4MAPPED;
}
err=belle_sip_getaddrinfo(ipaddress,serv,&hints,&res);
err=bctbx_getaddrinfo(ipaddress,serv,&hints,&res);
if (err!=0){
if (err!=EAI_NONAME)
......@@ -739,7 +739,7 @@ static void belle_sip_combined_resolver_context_destroy(belle_sip_combined_resol
}
static void belle_sip_simple_resolver_context_destroy(belle_sip_simple_resolver_context_t *ctx){
/* Do not free elements of ctx->ai_list with belle_sip_freeaddrinfo(). Let the caller do it, otherwise
/* Do not free elements of ctx->ai_list with bctbx_freeaddrinfo(). Let the caller do it, otherwise
it will not be able to use them after the resolver has been destroyed. */
#ifdef USE_GETADDRINFO_FALLBACK
if (ctx->getaddrinfo_thread != 0) {
......@@ -755,12 +755,12 @@ static void belle_sip_simple_resolver_context_destroy(belle_sip_simple_resolver_
#endif
if (ctx->ai_list != NULL) {
belle_sip_freeaddrinfo(ctx->ai_list);
bctbx_freeaddrinfo(ctx->ai_list);
ctx->ai_list = NULL;
}
#ifdef USE_GETADDRINFO_FALLBACK
if (ctx->getaddrinfo_ai_list != NULL) {
belle_sip_freeaddrinfo(ctx->getaddrinfo_ai_list);
bctbx_freeaddrinfo(ctx->getaddrinfo_ai_list);
ctx->getaddrinfo_ai_list = NULL;
}
#endif
......@@ -792,11 +792,11 @@ static void belle_sip_dual_resolver_context_destroy(belle_sip_dual_resolver_cont
obj->aaaa_ctx=NULL;
}
if (obj->a_results){
belle_sip_freeaddrinfo(obj->a_results);
bctbx_freeaddrinfo(obj->a_results);
obj->a_results=NULL;
}
if (obj->aaaa_results){
belle_sip_freeaddrinfo(obj->aaaa_results);
bctbx_freeaddrinfo(obj->aaaa_results);
obj->aaaa_results=NULL;
}
if (obj->name){
......@@ -1173,7 +1173,7 @@ fail:
if (res != NULL) {
memcpy(src,res->ai_addr,MIN((size_t)*srclen,res->ai_addrlen));
*srclen=res->ai_addrlen;
belle_sip_freeaddrinfo(res);
bctbx_freeaddrinfo(res);
} else {
if (af_type == AF_INET) belle_sip_fatal("belle_sip_get_src_addr_for(): belle_sip_ip_address_to_addrinfo() failed");
}
......
......@@ -99,7 +99,7 @@ static size_t belle_sip_channel_input_stream_get_buff_length(belle_sip_channel_i
static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
belle_sip_channel_input_stream_reset(&obj->input_stream);
if (obj->peer_list) belle_sip_freeaddrinfo(obj->peer_list);
if (obj->peer_list) bctbx_freeaddrinfo(obj->peer_list);
if (obj->peer_cname) belle_sip_free(obj->peer_cname);
belle_sip_free(obj->peer_name);
if (obj->local_ip) belle_sip_free(obj->local_ip);
......@@ -737,7 +737,7 @@ void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack,c
if (peername){
/*check if we are given a real dns name or just an ip address*/
struct addrinfo *ai=belle_sip_ip_address_to_addrinfo(AF_UNSPEC,peername,peer_port);
if (ai) belle_sip_freeaddrinfo(ai);
if (ai) bctbx_freeaddrinfo(ai);
else obj->has_name=TRUE;
}
belle_sip_channel_input_stream_reset(&obj->input_stream);
......@@ -1472,10 +1472,10 @@ belle_sip_channel_t *belle_sip_channel_find_from_list(belle_sip_list_t *l, int a
hints.ai_socktype=SOCK_STREAM; // needed on some platforms that return an error otherwise (QNX)
if (ai_family==AF_INET6) hints.ai_flags|=AI_V4MAPPED|AI_ALL;
snprintf(portstr,sizeof(portstr),"%i",hop->port);
belle_sip_getaddrinfo(hop->host,portstr,&hints,&res);
bctbx_getaddrinfo(hop->host,portstr,&hints,&res);
chan=belle_sip_channel_find_from_list_with_addrinfo(l,hop,res);
if (res) belle_sip_freeaddrinfo(res);
if (res) bctbx_freeaddrinfo(res);
return chan;
}
......
......@@ -261,131 +261,3 @@ int belle_sip_socket_enable_dual_stack(belle_sip_socket_t sock){
}
return err;
}
#if defined(ANDROID) || defined(_WIN32)
/*
* SHAME !!! bionic's getaddrinfo does not implement the AI_V4MAPPED flag !
* It is declared in header file but rejected by the implementation.
* The code below is to emulate a _compliant_ getaddrinfo for android.
**/
/**
* SHAME AGAIN !!! Win32's implementation of getaddrinfo is bogus !
* it is not able to return an IPv6 addrinfo from an IPv4 address when AI_V4MAPPED is set !
**/
struct addrinfo *_belle_sip_alloc_addrinfo(int ai_family, int socktype, int proto){
struct addrinfo *ai=(struct addrinfo*)belle_sip_malloc0(sizeof(struct addrinfo));
ai->ai_family=ai_family;
ai->ai_socktype=socktype;
ai->ai_protocol=proto;
ai->ai_addrlen=AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
ai->ai_addr=(struct sockaddr *) belle_sip_malloc0(ai->ai_addrlen);
return ai;
}
struct addrinfo *convert_to_v4mapped(const struct addrinfo *ai){
struct addrinfo *res=NULL;
const struct addrinfo *it;
struct addrinfo *v4m=NULL;
struct addrinfo *last=NULL;
for (it=ai;it!=NULL;it=it->ai_next){
struct sockaddr_in6 *sin6;
struct sockaddr_in *sin;
v4m=_belle_sip_alloc_addrinfo(AF_INET6, it->ai_socktype, it->ai_protocol);
v4m->ai_flags|=AI_V4MAPPED;
sin6=(struct sockaddr_in6*)v4m->ai_addr;
sin=(struct sockaddr_in*)it->ai_addr;
sin6->sin6_family=AF_INET6;
((uint8_t*)&sin6->sin6_addr)[10]=0xff;
((uint8_t*)&sin6->sin6_addr)[11]=0xff;
memcpy(((uint8_t*)&sin6->sin6_addr)+12,&sin->sin_addr,4);
sin6->sin6_port=sin->sin_port;
if (last){
last->ai_next=v4m;
}else{
res=v4m;
}
last=v4m;
}
return res;
}
struct addrinfo *addrinfo_concat(struct addrinfo *a1, struct addrinfo *a2){
struct addrinfo *it;
struct addrinfo *last=NULL;
for (it=a1;it!=NULL;it=it->ai_next){
last=it;
}
if (last){
last->ai_next=a2;
return a1;
}else
return a2;
}
int belle_sip_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res){
if (hints && hints->ai_family!=AF_INET && hints->ai_flags & AI_V4MAPPED){
struct addrinfo *res6=NULL;
struct addrinfo *res4=NULL;
struct addrinfo lhints={0};
int err;
if (hints) memcpy(&lhints,hints,sizeof(lhints));
lhints.ai_flags &= ~(AI_ALL | AI_V4MAPPED); /*remove the unsupported flags*/
if (hints->ai_flags & AI_ALL){
lhints.ai_family=AF_INET6;
err=getaddrinfo(node, service, &lhints, &res6);
}
lhints.ai_family=AF_INET;
err=getaddrinfo(node, service, &lhints, &res4);
if (err==0){
struct addrinfo *v4m=convert_to_v4mapped(res4);
freeaddrinfo(res4);
res4=v4m;
}
*res=addrinfo_concat(res6,res4);
if (*res) err=0;
return err;
}
return getaddrinfo(node, service, hints, res);
}
void _belle_sip_freeaddrinfo(struct addrinfo *res){
struct addrinfo *it,*next_it;
for(it=res;it!=NULL;it=next_it){
next_it=it->ai_next;
belle_sip_free(it->ai_addr);
belle_sip_free(it);
}
}
void belle_sip_freeaddrinfo(struct addrinfo *res){
struct addrinfo *it,*previt=NULL;
struct addrinfo *allocated_by_belle_sip=NULL;
for(it=res;it!=NULL;it=it->ai_next){
if (it->ai_flags & AI_V4MAPPED){
allocated_by_belle_sip=it;
if (previt) previt->ai_next=NULL;
break;
}
previt=it;
}
if (res!=allocated_by_belle_sip) freeaddrinfo(res);
if (allocated_by_belle_sip) _belle_sip_freeaddrinfo(allocated_by_belle_sip);
}
#else
int belle_sip_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res){
return getaddrinfo(node, service, hints, res);
}
void belle_sip_freeaddrinfo(struct addrinfo *res){
freeaddrinfo(res);
}
#endif
......@@ -423,7 +423,7 @@ static void http_proxy_res_done(void *data, const char *name, struct addrinfo *a
}
if (ai_list){
tls_channel_connect_to((belle_sip_channel_t *)obj,ai_list);
belle_sip_freeaddrinfo(ai_list);
bctbx_freeaddrinfo(ai_list);
}else{
belle_sip_error("%s: DNS resolution failed for %s", __FUNCTION__, name);
channel_set_state((belle_sip_channel_t*)obj,BELLE_SIP_CHANNEL_ERROR);
......
......@@ -69,7 +69,7 @@ static void reset_endpoint(endpoint_t *endpoint) {
endpoint->resolve_done = 0;
endpoint->resolve_ko = 0;
if (endpoint->ai_list != NULL) {
belle_sip_freeaddrinfo(endpoint->ai_list);
bctbx_freeaddrinfo(endpoint->ai_list);
endpoint->ai_list = NULL;
}
if (endpoint->srv_list != NULL) {
......@@ -126,7 +126,7 @@ static void ipv4_a_query(void) {
ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_SIP_IP, SIP_PORT);
if (ai) {
BC_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr, int, "%d");
belle_sip_freeaddrinfo(ai);
bctbx_freeaddrinfo(ai);
}
}
......@@ -153,7 +153,7 @@ static void ipv4_cname_a_query(void) {
ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_CNAME_IP, SIP_PORT);
if (ai) {
BC_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr, int, "%d");
belle_sip_freeaddrinfo(ai);
bctbx_freeaddrinfo(ai);
}
}
......@@ -295,7 +295,7 @@ static void ipv6_aaaa_query(void) {
for (i = 0; i < 8; i++) {
BC_ASSERT_EQUAL(sock_in6->sin6_addr.s6_addr[i], ipv6_address->s6_addr[i], int, "%d");
}
belle_sip_freeaddrinfo(ai);
bctbx_freeaddrinfo(ai);
}
next=client->ai_list->ai_next;
BC_ASSERT_PTR_NOT_NULL(next);
......@@ -313,7 +313,7 @@ static void ipv6_aaaa_query(void) {
for (i = 0; i < 8; i++) {
BC_ASSERT_EQUAL(sock_in6->sin6_addr.s6_addr[i], ipv6_address->s6_addr[i], int, "%d");
}
belle_sip_freeaddrinfo(ai);
bctbx_freeaddrinfo(ai);
}
}
}
......@@ -374,7 +374,7 @@ static void srv_a_query_no_srv_result(void) {
ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_CNAME_IP, SIP_PORT);
if (ai) {
BC_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr, int, "%d");
belle_sip_freeaddrinfo(ai);
bctbx_freeaddrinfo(ai);
}
}
......@@ -416,7 +416,7 @@ static void no_query_needed(void) {
ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_SIP_IP, SIP_PORT);
if (ai) {
BC_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr, int, "%d");
belle_sip_freeaddrinfo(ai);
bctbx_freeaddrinfo(ai);
}
}
......@@ -464,7 +464,7 @@ static void dns_fallback(void) {
ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_SIP_IP, SIP_PORT);
if (ai) {
BC_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr, int, "%d");
belle_sip_freeaddrinfo(ai);
bctbx_freeaddrinfo(ai);
}
}
......@@ -500,7 +500,7 @@ static void ipv6_dns_server(void) {
ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_SIP_IP, SIP_PORT);
if (ai) {
BC_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr, int, "%d");
belle_sip_freeaddrinfo(ai);
bctbx_freeaddrinfo(ai);
}
}
......@@ -536,7 +536,7 @@ static void ipv4_and_ipv6_dns_server(void) {
ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_SIP_IP, SIP_PORT);
if (ai) {
BC_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr, int, "%d");
belle_sip_freeaddrinfo(ai);
bctbx_freeaddrinfo(ai);
}
}
......
......@@ -48,7 +48,7 @@ static int _belle_sip_tester_ipv6_available(void){
src.ai_addr=(struct sockaddr*) &ss;
src.ai_addrlen=slen;
belle_sip_addrinfo_to_ip(&src,localip, sizeof(localip),&port);
belle_sip_freeaddrinfo(ai);
bctbx_freeaddrinfo(ai);
return strcmp(localip,"::1")!=0;
}
return FALSE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment