Simplify IP assignment logic in OSXEthernetTap, also fix for GitHub issue #249

This commit is contained in:
Adam Ierymenko 2015-11-30 15:39:34 -08:00
parent 40a4ba6e39
commit f260250580

View File

@ -475,37 +475,11 @@ bool OSXEthernetTap::enabled() const
return _enabled; return _enabled;
} }
static bool ___removeIp(const std::string &_dev,const InetAddress &ip)
{
long cpid = (long)vfork();
if (cpid == 0) {
execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"inet",ip.toIpString().c_str(),"-alias",(const char *)0);
_exit(-1);
} else if (cpid > 0) {
int exitcode = -1;
waitpid(cpid,&exitcode,0);
return (exitcode == 0);
}
return false; // never reached, make compiler shut up about return value
}
bool OSXEthernetTap::addIp(const InetAddress &ip) bool OSXEthernetTap::addIp(const InetAddress &ip)
{ {
if (!ip) if (!ip)
return false; return false;
std::vector<InetAddress> allIps(ips());
if (std::binary_search(allIps.begin(),allIps.end(),ip))
return true;
// Remove and reconfigure if address is the same but netmask is different
for(std::vector<InetAddress>::iterator i(allIps.begin());i!=allIps.end();++i) {
if ((i->ipsEqual(ip))&&(i->netmaskBits() != ip.netmaskBits())) {
if (___removeIp(_dev,*i))
break;
}
}
long cpid = (long)vfork(); long cpid = (long)vfork();
if (cpid == 0) { if (cpid == 0) {
::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),ip.isV4() ? "inet" : "inet6",ip.toString().c_str(),"alias",(const char *)0); ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),ip.isV4() ? "inet" : "inet6",ip.toString().c_str(),"alias",(const char *)0);
@ -524,9 +498,18 @@ bool OSXEthernetTap::removeIp(const InetAddress &ip)
if (!ip) if (!ip)
return true; return true;
std::vector<InetAddress> allIps(ips()); std::vector<InetAddress> allIps(ips());
if (!std::binary_search(allIps.begin(),allIps.end(),ip)) { for(std::vector<InetAddress>::iterator i(allIps.begin());i!=allIps.end();++i) {
if (___removeIp(_dev,ip)) if (*i == ip) {
return true; long cpid = (long)vfork();
if (cpid == 0) {
execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"inet",ip.toIpString().c_str(),"-alias",(const char *)0);
_exit(-1);
} else if (cpid > 0) {
int exitcode = -1;
waitpid(cpid,&exitcode,0);
return (exitcode == 0);
}
}
} }
return false; return false;
} }
@ -564,7 +547,7 @@ std::vector<InetAddress> OSXEthernetTap::ips() const
freeifaddrs(ifa); freeifaddrs(ifa);
std::sort(r.begin(),r.end()); std::sort(r.begin(),r.end());
std::unique(r.begin(),r.end()); r.erase(std::unique(r.begin(),r.end()),r.end());
return r; return r;
} }