浏览代码

properly fill out ifcfg files. also removed route re-add code for synology

Joseph Henry 8 年之前
父节点
当前提交
946e413997
共有 4 个文件被更改,包括 64 次插入14 次删除
  1. 2 6
      osdep/Binder.hpp
  2. 56 2
      osdep/LinuxEthernetTap.cpp
  3. 1 0
      osdep/LinuxEthernetTap.hpp
  4. 5 6
      service/OneService.cpp

+ 2 - 6
osdep/Binder.hpp

@@ -63,12 +63,8 @@
  *
  *
  * OneService also does this on detected restarts.
  * 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 {
 namespace ZeroTier {
 
 
 /**
 /**

+ 56 - 2
osdep/LinuxEthernetTap.cpp

@@ -109,7 +109,12 @@ LinuxEthernetTap::LinuxEthernetTap(
 	if (!recalledDevice) {
 	if (!recalledDevice) {
 		int devno = 0;
 		int devno = 0;
 		do {
 		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++);
 			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);
 			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
 		} 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<InetAddress> 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<ips.size(); i++) {
+			if (ips[i].isV4())
+				ip4_tot++;
+			else
+				ip6_tot++;
+		}
+		// Assemble and write contents of ifcfg-dev file
+		for(int i=0; i<ips.size(); i++) {
+			if (ips[i].isV4()) {
+				std::string numstr4 = ip4_tot > 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<ips.size(); i++){
+			if (ips[i].isV4())
+				::execlp("ip","ip","addr","add",ips[i].toString().c_str(),"broadcast",ips[i].broadcast().toIpString().c_str(),"dev",_dev.c_str(),(const char *)0);
+			else
+				::execlp("ip","ip","addr","add",ips[i].toString().c_str(),"dev",_dev.c_str(),(const char *)0);			
+		}
+		::_exit(-1);
+	} else if (cpid > 0) {
+		int exitcode = -1;
+		::waitpid(cpid,&exitcode,0);
+		return (exitcode == 0);
+	}
+	return true;
+}
+
 bool LinuxEthernetTap::addIp(const InetAddress &ip)
 bool LinuxEthernetTap::addIp(const InetAddress &ip)
 {
 {
 	if (!ip)
 	if (!ip)
 		return false;
 		return false;
 
 
 	std::vector<InetAddress> allIps(ips());
 	std::vector<InetAddress> allIps(ips());
-#ifndef __SYNOLOGY__
 	if (std::binary_search(allIps.begin(),allIps.end(),ip))
 	if (std::binary_search(allIps.begin(),allIps.end(),ip))
 		return true;
 		return true;
-#endif
 
 
 	// Remove and reconfigure if address is the same but netmask is different
 	// Remove and reconfigure if address is the same but netmask is different
 	for(std::vector<InetAddress>::iterator i(allIps.begin());i!=allIps.end();++i) {
 	for(std::vector<InetAddress>::iterator i(allIps.begin());i!=allIps.end();++i) {

+ 1 - 0
osdep/LinuxEthernetTap.hpp

@@ -52,6 +52,7 @@ public:
 	void setEnabled(bool en);
 	void setEnabled(bool en);
 	bool enabled() const;
 	bool enabled() const;
 	bool addIp(const InetAddress &ip);
 	bool addIp(const InetAddress &ip);
+	bool addIpSyn(std::vector<InetAddress> ips);
 	bool removeIp(const InetAddress &ip);
 	bool removeIp(const InetAddress &ip);
 	std::vector<InetAddress> ips() const;
 	std::vector<InetAddress> ips() const;
 	void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);
 	void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);

+ 5 - 6
service/OneService.cpp

@@ -1087,18 +1087,17 @@ public:
 						fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString().c_str());
 						fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString().c_str());
 				}
 				}
 			}
 			}
-			for(std::vector<InetAddress>::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) {
 #ifdef __SYNOLOGY__
 #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
 #else
+			for(std::vector<InetAddress>::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) {
 				if (std::find(n.managedIps.begin(),n.managedIps.end(),*ip) == n.managedIps.end()) {
 				if (std::find(n.managedIps.begin(),n.managedIps.end(),*ip) == n.managedIps.end()) {
-
 					if (!n.tap->addIp(*ip))
 					if (!n.tap->addIp(*ip))
 						fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString().c_str());
 						fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString().c_str());
-				}
-#endif
+				}			
 			}
 			}
+#endif
 			n.managedIps.swap(newManagedIps);
 			n.managedIps.swap(newManagedIps);
 		}
 		}