Commit 3e924ef6 authored by Ghislain MARY's avatar Ghislain MARY

Move get_local_ip_for() to bctoolbox.

parent b0f08ed9
......@@ -1131,157 +1131,8 @@ bool_t linphone_core_tone_indications_enabled(LinphoneCore*lc){
return lp_config_get_int(lc->config,"sound","tone_indications",1);
}
#ifdef HAVE_GETIFADDRS
#include <ifaddrs.h>
static int get_local_ip_with_getifaddrs(int type, char *address, int size){
struct ifaddrs *ifp;
struct ifaddrs *ifpstart;
char retaddr[LINPHONE_IPADDR_SIZE]={0};
bool_t found=FALSE;
if (getifaddrs(&ifpstart) < 0) {
return -1;
}
#ifndef __linux
#define UP_FLAG IFF_UP /* interface is up */
#else
#define UP_FLAG IFF_RUNNING /* resources allocated */
#endif
for (ifp = ifpstart; ifp != NULL; ifp = ifp->ifa_next) {
if (ifp->ifa_addr && ifp->ifa_addr->sa_family == type
&& (ifp->ifa_flags & UP_FLAG) && !(ifp->ifa_flags & IFF_LOOPBACK))
{
if(getnameinfo(ifp->ifa_addr,
(type == AF_INET6) ?
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
retaddr, size, NULL, 0, NI_NUMERICHOST) == 0) {
if (strchr(retaddr, '%') == NULL) { /*avoid ipv6 link-local addresses */
/*ms_message("getifaddrs() found %s",address);*/
found=TRUE;
break;
}
}
}
}
freeifaddrs(ifpstart);
if (found) strncpy(address,retaddr,size);
return found;
}
#endif
static const char *ai_family_to_string(int af){
switch(af){
case AF_INET: return "AF_INET";
case AF_INET6: return "AF_INET6";
case AF_UNSPEC: return "AF_UNSPEC";
default:
return "invalid address family";
}
return "";
}
static int get_local_ip_for_with_connect(int type, const char *dest, char *result){
int err,tmp;
struct addrinfo hints;
struct addrinfo *res=NULL;
struct sockaddr_storage addr;
struct sockaddr *p_addr=(struct sockaddr*)&addr;
ortp_socket_t sock;
socklen_t s;
memset(&hints,0,sizeof(hints));
hints.ai_family=type;
hints.ai_socktype=SOCK_DGRAM;
/*hints.ai_flags=AI_NUMERICHOST|AI_CANONNAME;*/
err=getaddrinfo(dest,"5060",&hints,&res);
if (err!=0){
ms_error("getaddrinfo() error for %s : %s",dest, gai_strerror(err));
return -1;
}
if (res==NULL){
ms_error("bug: getaddrinfo returned nothing.");
return -1;
}
sock=socket(res->ai_family,SOCK_DGRAM,0);
if (sock == (ortp_socket_t)-1){
ms_error("get_local_ip_for_with_connect() could not create [%s] socket: %s",
ai_family_to_string(res->ai_family), getSocketError());
return -1;
}
tmp=1;
err=setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(SOCKET_OPTION_VALUE)&tmp,sizeof(int));
if (err == -1){
ms_warning("Error in setsockopt: %s",strerror(errno));
}
err=connect(sock,res->ai_addr,(int)res->ai_addrlen);
if (err == -1) {
/*the network isn't reachable*/
if (getSocketErrorCode()!=ENETUNREACH) ms_error("Error in connect: %s",strerror(errno));
freeaddrinfo(res);
close_socket(sock);
return -1;
}
freeaddrinfo(res);
res=NULL;
s=sizeof(addr);
err=getsockname(sock,(struct sockaddr*)&addr,&s);
if (err!=0) {
ms_error("Error in getsockname: %s",strerror(errno));
close_socket(sock);
return -1;
}
if (p_addr->sa_family==AF_INET){
struct sockaddr_in *p_sin=(struct sockaddr_in*)p_addr;
if (p_sin->sin_addr.s_addr==0){
close_socket(sock);
return -1;
}
}
err=getnameinfo((struct sockaddr *)&addr,s,result,LINPHONE_IPADDR_SIZE,NULL,0,NI_NUMERICHOST);
if (err!=0){
ms_error("getnameinfo error: %s",strerror(errno));
}
/*avoid ipv6 link-local addresses*/
if (p_addr->sa_family==AF_INET6 && strchr(result,'%')!=NULL){
strcpy(result,"::1");
close_socket(sock);
return -1;
}
close_socket(sock);
return 0;
}
int linphone_core_get_local_ip_for(int type, const char *dest, char *result){
int err;
#ifdef HAVE_GETIFADDRS
int found_ifs;
#endif
strcpy(result,type==AF_INET ? "127.0.0.1" : "::1");
if (dest==NULL){
if (type==AF_INET)
dest="87.98.157.38"; /*a public IP address*/
else dest="2a00:1450:8002::68";
}
err=get_local_ip_for_with_connect(type,dest,result);
if (err==0) return 0;
/* if the connect method failed, which happens when no default route is set,
* try to find 'the' running interface with getifaddrs*/
#ifdef HAVE_GETIFADDRS
/*we use getifaddrs for lookup of default interface */
found_ifs=get_local_ip_with_getifaddrs(type,result,LINPHONE_IPADDR_SIZE);
if (found_ifs==1){
return 0;
}else if (found_ifs<=0){
/*absolutely no network on this machine */
return -1;
}
#endif
return 0;
return bctbx_get_local_ip_for(type, dest, 5060, result, LINPHONE_IPADDR_SIZE);
}
void linphone_core_get_local_ip(LinphoneCore *lc, int af, const char *dest, char *result) {
......
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