Merge pull request #434 from zielmicha/fix-ip

Binder.hpp: gather all IPv4 interface addresses
This commit is contained in:
Adam Ierymenko 2017-01-19 10:47:47 -08:00 committed by GitHub
commit 989cbb4d8d

View File

@ -236,30 +236,46 @@ public:
// Get IPv4 addresses for each device // Get IPv4 addresses for each device
if (ifnames.size() > 0) { if (ifnames.size() > 0) {
const int controlfd = (int)socket(AF_INET,SOCK_DGRAM,0); const int controlfd = (int)socket(AF_INET,SOCK_DGRAM,0);
if (controlfd >= 0) { struct ifconf configuration;
for(std::set<std::string>::iterator devname(ifnames.begin());devname!=ifnames.end();++devname) { configuration.ifc_len = 0;
struct ifreq ifr; configuration.ifc_buf = nullptr;
memset(&ifr,0,sizeof(ifr));
ifr.ifr_addr.sa_family = AF_INET; if (controlfd < 0) goto ip4_address_error;
Utils::scopy(ifr.ifr_name,sizeof(ifr.ifr_name),devname->c_str());
if (ioctl(controlfd,SIOCGIFADDR,&ifr) >= 0) { if (ioctl(controlfd, SIOCGIFCONF, &configuration) < 0) goto ip4_address_error;
InetAddress ip(&(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr),4,0);
if (ifChecker.shouldBindInterface(devname->c_str(),ip)) { configuration.ifc_buf = (char*)malloc(configuration.ifc_len);
switch(ip.ipScope()) {
default: break; if (ioctl(controlfd, SIOCGIFCONF, &configuration) < 0) goto ip4_address_error;
case InetAddress::IP_SCOPE_PSEUDOPRIVATE:
case InetAddress::IP_SCOPE_GLOBAL: for (int i=0; i < (int)(configuration.ifc_len / sizeof(ifreq)); i ++) {
case InetAddress::IP_SCOPE_SHARED: struct ifreq& request = configuration.ifc_req[i];
case InetAddress::IP_SCOPE_PRIVATE: struct sockaddr* addr = &request.ifr_ifru.ifru_addr;
ip.setPort(port); if (addr->sa_family != AF_INET) continue;
localIfAddrs.insert(std::pair<InetAddress,std::string>(ip,*devname)); std::string ifname = request.ifr_ifrn.ifrn_name;
break; // name can either be just interface name or interface name followed by ':' and arbitrary label
} if (ifname.find(':') != std::string::npos) {
} ifname = ifname.substr(0, ifname.find(':'));
}
InetAddress ip(&(((struct sockaddr_in *)addr)->sin_addr),4,0);
if (ifChecker.shouldBindInterface(ifname.c_str(), ip)) {
switch(ip.ipScope()) {
default: break;
case InetAddress::IP_SCOPE_PSEUDOPRIVATE:
case InetAddress::IP_SCOPE_GLOBAL:
case InetAddress::IP_SCOPE_SHARED:
case InetAddress::IP_SCOPE_PRIVATE:
ip.setPort(port);
localIfAddrs.insert(std::pair<InetAddress,std::string>(ip, ifname));
break;
} }
} }
close(controlfd);
} }
ip4_address_error:
free(configuration.ifc_buf);
if (controlfd > 0) close(controlfd);
} }
const bool gotViaProc = (localIfAddrs.size() > 0); const bool gotViaProc = (localIfAddrs.size() > 0);