mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-22 21:58:08 +00:00
Move get_local_ip_for() to bctoolbox.
This commit is contained in:
parent
b0f08ed967
commit
3e924ef6f5
1 changed files with 1 additions and 150 deletions
151
coreapi/misc.c
151
coreapi/misc.c
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue