From 946e413997560d1bb714e6f7099429b18f9fecee Mon Sep 17 00:00:00 2001 From: Joseph Henry Date: Tue, 21 Feb 2017 17:55:00 -0800 Subject: [PATCH] properly fill out ifcfg files. also removed route re-add code for synology --- osdep/Binder.hpp | 8 ++---- osdep/LinuxEthernetTap.cpp | 58 ++++++++++++++++++++++++++++++++++++-- osdep/LinuxEthernetTap.hpp | 1 + service/OneService.cpp | 11 ++++---- 4 files changed, 64 insertions(+), 14 deletions(-) diff --git a/osdep/Binder.hpp b/osdep/Binder.hpp index accff86fa..9829f1703 100644 --- a/osdep/Binder.hpp +++ b/osdep/Binder.hpp @@ -63,12 +63,8 @@ * * OneService also does this on detected restarts. */ -#ifdef __SYNOLOGY___ - // Synology devices like to kill routes, check more often and re-add - #define ZT_BINDER_REFRESH_PERIOD 10000 -#else - #define ZT_BINDER_REFRESH_PERIOD 30000 -#endif +#define ZT_BINDER_REFRESH_PERIOD 30000 + namespace ZeroTier { /** diff --git a/osdep/LinuxEthernetTap.cpp b/osdep/LinuxEthernetTap.cpp index 55a6d9f68..9d3773f0e 100644 --- a/osdep/LinuxEthernetTap.cpp +++ b/osdep/LinuxEthernetTap.cpp @@ -109,7 +109,12 @@ LinuxEthernetTap::LinuxEthernetTap( if (!recalledDevice) { int devno = 0; do { +#ifdef __SYNOLOGY__ + devno+=50; // Arbitrary number to prevent interface name conflicts + Utils::snprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"eth%d",devno++); +#else Utils::snprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"zt%d",devno++); +#endif Utils::snprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name); } while (stat(procpath,&sbuf) == 0); // try zt#++ until we find one that does not exist } @@ -215,16 +220,65 @@ static bool ___removeIp(const std::string &_dev,const InetAddress &ip) } } +bool LinuxEthernetTap::addIpSyn(std::vector ips) +{ + // Here we fill out interface config (ifcfg-dev) to prevent it from being killed + std::string filepath = "/etc/sysconfig/network-scripts/ifcfg-"+_dev; + std::string cfg_contents = "DEVICE="+_dev+"\nBOOTPROTO=static"; + int ip4=0,ip6=0,ip4_tot=0,ip6_tot=0; + + long cpid = (long)vfork(); + if (cpid == 0) { + OSUtils::redirectUnixOutputs("/dev/null",(const char *)0); + setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1); + // We must know if there is at least (one) of each protocol version so we + // can properly enumerate address/netmask combinations in the ifcfg-dev file + for(int i=0; i 1 ? std::to_string(ip4) : ""; + cfg_contents += "\nIPADDR"+numstr4+"="+ips[i].toIpString() + + "\nNETMASK"+numstr4+"="+ips[i].netmask().toIpString()+"\n"; + ip4++; + } + else { + std::string numstr6 = ip6_tot > 1 ? std::to_string(ip6) : ""; + cfg_contents += "\nIPV6ADDR"+numstr6+"="+ips[i].toIpString() + + "\nNETMASK"+numstr6+"="+ips[i].netmask().toIpString()+"\n"; + ip6++; + } + } + OSUtils::writeFile(filepath.c_str(), cfg_contents.c_str(), cfg_contents.length()); + // Finaly, add IPs + for(int i=0; i 0) { + int exitcode = -1; + ::waitpid(cpid,&exitcode,0); + return (exitcode == 0); + } + return true; +} + bool LinuxEthernetTap::addIp(const InetAddress &ip) { if (!ip) return false; std::vector allIps(ips()); -#ifndef __SYNOLOGY__ if (std::binary_search(allIps.begin(),allIps.end(),ip)) return true; -#endif // Remove and reconfigure if address is the same but netmask is different for(std::vector::iterator i(allIps.begin());i!=allIps.end();++i) { diff --git a/osdep/LinuxEthernetTap.hpp b/osdep/LinuxEthernetTap.hpp index cbb58efb0..acdff9dd1 100644 --- a/osdep/LinuxEthernetTap.hpp +++ b/osdep/LinuxEthernetTap.hpp @@ -52,6 +52,7 @@ public: void setEnabled(bool en); bool enabled() const; bool addIp(const InetAddress &ip); + bool addIpSyn(std::vector ips); bool removeIp(const InetAddress &ip); std::vector ips() const; void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); diff --git a/service/OneService.cpp b/service/OneService.cpp index dc3e0ed1b..81950e264 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -1087,18 +1087,17 @@ public: fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString().c_str()); } } - for(std::vector::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) { #ifdef __SYNOLOGY__ - if (!n.tap->addIp(*ip)) - fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString().c_str()); + if (!n.tap->addIpSyn(newManagedIps)) + fprintf(stderr,"ERROR: unable to add ip addresses to ifcfg" ZT_EOL_S); #else + for(std::vector::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) { if (std::find(n.managedIps.begin(),n.managedIps.end(),*ip) == n.managedIps.end()) { - if (!n.tap->addIp(*ip)) fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString().c_str()); - } -#endif + } } +#endif n.managedIps.swap(newManagedIps); }