Skip to content
Permalink
Browse files

CLOUD: Fix LocalWebserver::resolveAddress() on Android

No <ifaddrs.h> available on Android, thus fixed similarly to zlargon/lssdp@9b4568
  • Loading branch information
Tkachov committed Mar 4, 2017
1 parent d0fc883 commit 302f6e6bccb606429da4f33df445d33313469936
Showing with 71 additions and 46 deletions.
  1. +71 −46 backends/networking/sdl_net/localwebserver.cpp
@@ -33,10 +33,20 @@
#include <common/config-manager.h>

#ifdef POSIX
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>

#ifndef _SIZEOF_ADDR_IFREQ
#define _SIZEOF_ADDR_IFREQ sizeof
#endif

#define LSSDP_BUFFER_LEN 2048
#endif

namespace Common {
@@ -298,53 +308,68 @@ void LocalWebserver::resolveAddress(void *ipAddress) {
struct ifaddrs *ifAddrStruct = NULL;
void *tmpAddrPtr = NULL;

getifaddrs(&ifAddrStruct);

for (struct ifaddrs *i = ifAddrStruct; i != NULL; i = i->ifa_next) {
if (!i->ifa_addr) {
continue;
}

Common::String addr;

// IPv4
if (i->ifa_addr->sa_family == AF_INET) {
tmpAddrPtr = &((struct sockaddr_in *)i->ifa_addr)->sin_addr;
char addressBuffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
debug(9, "%s IP Address %s", i->ifa_name, addressBuffer);
addr = addressBuffer;
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
warning("LocalWebserver: failed to create socket: %s (%d)", strerror(errno), errno);
} else {
// get ifconfig
char buffer[LSSDP_BUFFER_LEN] = {};
struct ifconf ifc;
ifc.ifc_len = sizeof(buffer);
ifc.ifc_buf = (caddr_t) buffer;

if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
warning("LocalWebserver: ioctl SIOCGIFCONF failed: %s (%d)", strerror(errno), errno);
} else {
struct ifreq *i;
for (size_t index = 0; index < ifc.ifc_len; index += _SIZEOF_ADDR_IFREQ(*i)) {
i = (struct ifreq *)(buffer + index);

Common::String addr;

// IPv4
if (i->ifr_addr.sa_family == AF_INET) {
tmpAddrPtr = &((struct sockaddr_in *)&i->ifr_addr)->sin_addr;
char addressBuffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
debug(9, "%s IP Address %s", i->ifr_name, addressBuffer);
addr = addressBuffer;
}

// IPv6
/*
if (i->ifr_addr.sa_family == AF_INET6) {
tmpAddrPtr = &((struct sockaddr_in6 *)&i->ifr_addr)->sin6_addr;
char addressBuffer[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
debug(9, "%s IP Address %s", i->ifr_name, addressBuffer);
addr = addressBuffer;
}
*/

if (addr.empty())
continue;

// ignored IPv4 addresses
if (addr.equals("127.0.0.1") || addr.equals("0.0.0.0") || addr.equals("localhost"))
continue;

// ignored IPv6 addresses
/*
if (addr.equals("::1"))
continue;
*/

// use the address found
_address = "http://" + addr + Common::String::format(":%u/", _serverPort);
}
}

// IPv6
/*
if (i->ifa_addr->sa_family == AF_INET6) {
tmpAddrPtr = &((struct sockaddr_in6 *)i->ifa_addr)->sin6_addr;
char addressBuffer[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
debug(9, "%s IP Address %s", i->ifa_name, addressBuffer);
addr = addressBuffer;
// close socket
if (close(fd) != 0) {
warning("LocalWebserver: failed to close socket [fd %d]: %s (%d)", fd, strerror(errno), errno);
}
*/

if (addr.empty())
continue;

// ignored IPv4 addresses
if (addr.equals("127.0.0.1") || addr.equals("0.0.0.0") || addr.equals("localhost"))
continue;

// ignored IPv6 addresses
/*
if (addr.equals("::1"))
continue;
*/

// use the address found
_address = "http://" + addr + Common::String::format(":%u/", _serverPort);
}

if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct);
#endif
}

0 comments on commit 302f6e6

Please sign in to comment.
You can’t perform that action at this time.