2
0
Adam Ierymenko 8 жил өмнө
parent
commit
b55422a528

+ 14 - 44
osdep/BSDEthernetTap.cpp

@@ -94,9 +94,6 @@ BSDEthernetTap::BSDEthernetTap(
 
 	Mutex::Lock _gl(globalTapCreateLock);
 
-	if (mtu > 2800)
-		throw std::runtime_error("max tap MTU is 2800");
-
 #ifdef __FreeBSD__
 	/* FreeBSD allows long interface names and interface renaming */
 
@@ -321,7 +318,7 @@ std::vector<InetAddress> BSDEthernetTap::ips() const
 
 void BSDEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
 {
-	char putBuf[4096];
+	char putBuf[ZT_MAX_MTU + 64];
 	if ((_fd > 0)&&(len <= _mtu)&&(_enabled)) {
 		to.copyTo(putBuf,6);
 		from.copyTo(putBuf + 6,6);
@@ -381,49 +378,22 @@ void BSDEthernetTap::scanMulticastGroups(std::vector<MulticastGroup> &added,std:
 	_multicastGroups.swap(newGroups);
 }
 
-/*
-bool BSDEthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
+void BSDEthernetTap::setMtu(unsigned int mtu)
 {
-	std::set<MulticastGroup> newGroups;
-	struct ifmaddrs *ifmap = (struct ifmaddrs *)0;
-	if (!getifmaddrs(&ifmap)) {
-		struct ifmaddrs *p = ifmap;
-		while (p) {
-			if (p->ifma_addr->sa_family == AF_LINK) {
-				struct sockaddr_dl *in = (struct sockaddr_dl *)p->ifma_name;
-				struct sockaddr_dl *la = (struct sockaddr_dl *)p->ifma_addr;
-				if ((la->sdl_alen == 6)&&(in->sdl_nlen <= _dev.length())&&(!memcmp(_dev.data(),in->sdl_data,in->sdl_nlen)))
-					newGroups.insert(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen,6),0));
-			}
-			p = p->ifma_next;
-		}
-		freeifmaddrs(ifmap);
-	}
-
-	{
-		std::set<InetAddress> allIps(ips());
-		for(std::set<InetAddress>::const_iterator i(allIps.begin());i!=allIps.end();++i)
-			newGroups.insert(MulticastGroup::deriveMulticastGroupForAddressResolution(*i));
-	}
-
-	bool changed = false;
-
-	for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
-		if (!groups.count(*mg)) {
-			groups.insert(*mg);
-			changed = true;
+	if (mtu != _mtu) {
+		_mtu = mtu;
+		long cpid = (long)vfork();
+		if (cpid == 0) {
+			char tmp[64];
+			Utils::snprintf(tmp,sizeof(tmp),"%u",mtu);
+			execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"mtu",tmp,(const char *)0);
+			_exit(-1);
+		} else if (cpid > 0) {
+			int exitcode = -1;
+			waitpid(cpid,&exitcode,0);
 		}
 	}
-	for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
-		if ((!newGroups.count(*mg))&&(*mg != _blindWildcardMulticastGroup)) {
-			groups.erase(mg++);
-			changed = true;
-		} else ++mg;
-	}
-
-	return changed;
 }
-*/
 
 void BSDEthernetTap::threadMain()
 	throw()
@@ -431,7 +401,7 @@ void BSDEthernetTap::threadMain()
 	fd_set readfds,nullfds;
 	MAC to,from;
 	int n,nfds,r;
-	char getBuf[8194];
+	char getBuf[ZT_MAX_MTU + 64];
 
 	// Wait for a moment after startup -- wait for Network to finish
 	// constructing itself.

+ 1 - 0
osdep/BSDEthernetTap.hpp

@@ -65,6 +65,7 @@ public:
 	std::string deviceName() const;
 	void setFriendlyName(const char *friendlyName);
 	void scanMulticastGroups(std::vector<MulticastGroup> &added,std::vector<MulticastGroup> &removed);
+	void setMtu(unsigned int mtu);
 
 	void threadMain()
 		throw();

+ 17 - 5
osdep/LinuxEthernetTap.cpp

@@ -87,9 +87,6 @@ LinuxEthernetTap::LinuxEthernetTap(
 
 	Mutex::Lock _l(__tapCreateLock); // create only one tap at a time, globally
 
-	if (mtu > 2800)
-		throw std::runtime_error("max tap MTU is 2800");
-
 	_fd = ::open("/dev/net/tun",O_RDWR);
 	if (_fd <= 0) {
 		_fd = ::open("/dev/tun",O_RDWR);
@@ -386,7 +383,7 @@ std::vector<InetAddress> LinuxEthernetTap::ips() const
 
 void LinuxEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
 {
-	char putBuf[8194];
+	char putBuf[ZT_MAX_MTU + 64];
 	if ((_fd > 0)&&(len <= _mtu)&&(_enabled)) {
 		to.copyTo(putBuf,6);
 		from.copyTo(putBuf + 6,6);
@@ -455,13 +452,28 @@ void LinuxEthernetTap::scanMulticastGroups(std::vector<MulticastGroup> &added,st
 	_multicastGroups.swap(newGroups);
 }
 
+void LinuxEthernetTap::setMtu(unsigned int mtu)
+{
+	if (_mtu != mtu) {
+		_mtu = mtu;
+		int sock = socket(AF_INET,SOCK_DGRAM,0);
+		if (sock > 0) {
+			struct ifreq ifr;
+			memset(&ifr,0,sizeof(ifr));
+			ifr.ifr_ifru.ifru_mtu = (int)mtu;
+			ioctl(sock,SIOCSIFMTU,(void *)&ifr);
+			close(sock);
+		}
+	}
+}
+
 void LinuxEthernetTap::threadMain()
 	throw()
 {
 	fd_set readfds,nullfds;
 	MAC to,from;
 	int n,nfds,r;
-	char getBuf[8194];
+	char getBuf[ZT_MAX_MTU + 64];
 
 	Thread::sleep(500);
 

+ 1 - 0
osdep/LinuxEthernetTap.hpp

@@ -69,6 +69,7 @@ public:
 	std::string deviceName() const;
 	void setFriendlyName(const char *friendlyName);
 	void scanMulticastGroups(std::vector<MulticastGroup> &added,std::vector<MulticastGroup> &removed);
+	void setMtu(unsigned int mtu);
 
 	void threadMain()
 		throw();

+ 19 - 5
osdep/OSXEthernetTap.cpp

@@ -338,9 +338,6 @@ OSXEthernetTap::OSXEthernetTap(
 
 	Utils::snprintf(nwids,sizeof(nwids),"%.16llx",nwid);
 
-	if (mtu > 2800)
-		throw std::runtime_error("max tap MTU is 2800");
-
 	Mutex::Lock _gl(globalTapCreateLock);
 
 	if (::stat("/dev/zt0",&stattmp)) {
@@ -574,7 +571,7 @@ std::vector<InetAddress> OSXEthernetTap::ips() const
 
 void OSXEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
 {
-	char putBuf[4096];
+	char putBuf[ZT_MAX_MTU + 64];
 	if ((_fd > 0)&&(len <= _mtu)&&(_enabled)) {
 		to.copyTo(putBuf,6);
 		from.copyTo(putBuf + 6,6);
@@ -632,13 +629,30 @@ void OSXEthernetTap::scanMulticastGroups(std::vector<MulticastGroup> &added,std:
 	_multicastGroups.swap(newGroups);
 }
 
+void OSXEthernetTap::setMtu(unsigned int mtu)
+{
+	if (mtu != _mtu) {
+		_mtu = mtu;
+		long cpid = (long)vfork();
+		if (cpid == 0) {
+			char tmp[64];
+			Utils::snprintf(tmp,sizeof(tmp),"%u",mtu);
+			execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"mtu",tmp,(const char *)0);
+			_exit(-1);
+		} else if (cpid > 0) {
+			int exitcode = -1;
+			waitpid(cpid,&exitcode,0);
+		}
+	}
+}
+
 void OSXEthernetTap::threadMain()
 	throw()
 {
 	fd_set readfds,nullfds;
 	MAC to,from;
 	int n,nfds,r;
-	char getBuf[8194];
+	char getBuf[ZT_MAX_MTU + 64];
 
 	Thread::sleep(500);
 

+ 1 - 0
osdep/OSXEthernetTap.hpp

@@ -70,6 +70,7 @@ public:
 	std::string deviceName() const;
 	void setFriendlyName(const char *friendlyName);
 	void scanMulticastGroups(std::vector<MulticastGroup> &added,std::vector<MulticastGroup> &removed);
+	void setMtu(unsigned int mtu);
 
 	void threadMain()
 		throw();

+ 4 - 0
osdep/TestEthernetTap.hpp

@@ -139,6 +139,10 @@ public:
 	{
 	}
 
+	inline void setMtu(unsigned int mtu)
+	{
+	}
+
 private:
 	uint64_t _nwid;
 	std::string _dev;

+ 21 - 20
osdep/WindowsEthernetTap.cpp

@@ -470,6 +470,7 @@ WindowsEthernetTap::WindowsEthernetTap(
 	_arg(arg),
 	_mac(mac),
 	_nwid(nwid),
+	_mtu(mtu),
 	_tap(INVALID_HANDLE_VALUE),
 	_injectSemaphore(INVALID_HANDLE_VALUE),
 	_pathToHelpers(hp),
@@ -481,10 +482,6 @@ WindowsEthernetTap::WindowsEthernetTap(
 	char subkeyClass[1024];
 	char data[1024];
 	char tag[24];
-	std::string mySubkeyName;
-
-	if (mtu > 2800)
-		throw std::runtime_error("MTU too large.");
 
 	// We "tag" registry entries with the network ID to identify persistent devices
 	Utils::snprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)nwid);
@@ -530,7 +527,7 @@ WindowsEthernetTap::WindowsEthernetTap(
 								_netCfgInstanceId = instanceId;
 								_deviceInstanceId = instanceIdPath;
 
-								mySubkeyName = subkeyName;
+								_mySubkeyName = subkeyName;
 								break; // found it!
 							}
 						}
@@ -573,7 +570,7 @@ WindowsEthernetTap::WindowsEthernetTap(
 									if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS)
 										_deviceInstanceId.assign(data,dataLen);
 
-									mySubkeyName = subkeyName;
+									_mySubkeyName = subkeyName;
 
 									// Disable DHCP by default on new devices
 									HKEY tcpIpInterfaces;
@@ -605,24 +602,24 @@ WindowsEthernetTap::WindowsEthernetTap(
 	if (_netCfgInstanceId.length() > 0) {
 		char tmps[64];
 		unsigned int tmpsl = Utils::snprintf(tmps,sizeof(tmps),"%.2X-%.2X-%.2X-%.2X-%.2X-%.2X",(unsigned int)mac[0],(unsigned int)mac[1],(unsigned int)mac[2],(unsigned int)mac[3],(unsigned int)mac[4],(unsigned int)mac[5]) + 1;
-		RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"NetworkAddress",REG_SZ,tmps,tmpsl);
-		RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"MAC",REG_SZ,tmps,tmpsl);
+		RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"NetworkAddress",REG_SZ,tmps,tmpsl);
+		RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"MAC",REG_SZ,tmps,tmpsl);
         tmpsl = Utils::snprintf(tmps, sizeof(tmps), "%d", mtu);
-		RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"MTU",REG_SZ,tmps,tmpsl);
+		RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"MTU",REG_SZ,tmps,tmpsl);
 
 		DWORD tmp = 0;
-		RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"*NdisDeviceType",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
+		RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"*NdisDeviceType",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
 		tmp = IF_TYPE_ETHERNET_CSMACD;
-		RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"*IfType",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
+		RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"*IfType",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
 
 		if (creatingNewDevice) {
 			// Vista/2008 does not set this
 			if (newDeviceInstanceId.length() > 0)
-				RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"DeviceInstanceID",REG_SZ,newDeviceInstanceId.c_str(),(DWORD)newDeviceInstanceId.length());
+				RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"DeviceInstanceID",REG_SZ,newDeviceInstanceId.c_str(),(DWORD)newDeviceInstanceId.length());
 
 			// Set EnableDHCP to 0 by default on new devices
 			tmp = 0;
-			RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"EnableDHCP",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
+			RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"EnableDHCP",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
 		}
 		RegCloseKey(nwAdapters);
 	} else {
@@ -792,11 +789,11 @@ std::vector<InetAddress> WindowsEthernetTap::ips() const
 
 void WindowsEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
 {
-	if ((!_initialized)||(!_enabled)||(_tap == INVALID_HANDLE_VALUE)||(len > (ZT_IF_MTU)))
+	if ((!_initialized)||(!_enabled)||(_tap == INVALID_HANDLE_VALUE)||(len > _mtu))
 		return;
 
 	Mutex::Lock _l(_injectPending_m);
-	_injectPending.push( std::pair<Array<char,ZT_IF_MTU + 32>,unsigned int>(Array<char,ZT_IF_MTU + 32>(),len + 14) );
+	_injectPending.push( std::pair<Array<char,ZT_MAX_MTU + 32>,unsigned int>(Array<char,ZT_MAX_MTU + 32>(),len + 14) );
 	char *d = _injectPending.back().first.data;
 	to.copyTo(d,6);
 	from.copyTo(d + 6,6);
@@ -875,6 +872,12 @@ void WindowsEthernetTap::scanMulticastGroups(std::vector<MulticastGroup> &added,
 	_multicastGroups.swap(newGroups);
 }
 
+void WindowsEthernetTap::setMtu(unsigned int mtu)
+{
+	if (mtu != _mtu) {
+	}
+}
+
 NET_IFINDEX WindowsEthernetTap::interfaceIndex() const
 {
 	NET_IFINDEX idx = -1;
@@ -886,7 +889,7 @@ NET_IFINDEX WindowsEthernetTap::interfaceIndex() const
 void WindowsEthernetTap::threadMain()
 	throw()
 {
-	char tapReadBuf[ZT_IF_MTU + 32];
+	char tapReadBuf[ZT_MAX_MTU + 32];
 	char tapPath[128];
 	HANDLE wait4[3];
 	OVERLAPPED tapOvlRead,tapOvlWrite;
@@ -1015,9 +1018,7 @@ void WindowsEthernetTap::threadMain()
 			ReadFile(_tap,tapReadBuf,sizeof(tapReadBuf),NULL,&tapOvlRead);
 			bool writeInProgress = false;
 			ULONGLONG timeOfLastBorkCheck = GetTickCount64();
-
-
-            _initialized = true;
+			_initialized = true;
 
 			while (_run) {
 				DWORD waitResult = WaitForMultipleObjectsEx(writeInProgress ? 3 : 2,wait4,FALSE,2500,TRUE);
@@ -1070,7 +1071,7 @@ void WindowsEthernetTap::threadMain()
 							} catch ( ... ) {} // handlers should not throw
 						}
 					}
-					ReadFile(_tap,tapReadBuf,ZT_IF_MTU + 32,NULL,&tapOvlRead);
+					ReadFile(_tap,tapReadBuf,ZT_MAX_MTU + 32,NULL,&tapOvlRead);
 				}
 
 				if (writeInProgress) {

+ 4 - 1
osdep/WindowsEthernetTap.hpp

@@ -109,6 +109,7 @@ public:
 	std::string deviceName() const;
 	void setFriendlyName(const char *friendlyName);
 	void scanMulticastGroups(std::vector<MulticastGroup> &added,std::vector<MulticastGroup> &removed);
+	void setMtu(unsigned int mtu);
 
 	inline const NET_LUID &luid() const { return _deviceLuid; }
 	inline const GUID &guid() const { return _deviceGuid; }
@@ -130,6 +131,7 @@ private:
 	void *_arg;
 	MAC _mac;
 	uint64_t _nwid;
+	unsigned int _mtu;
 	Thread _thread;
 
 	volatile HANDLE _tap;
@@ -139,13 +141,14 @@ private:
 	NET_LUID _deviceLuid;
 	std::string _netCfgInstanceId;
 	std::string _deviceInstanceId;
+	std::string _mySubkeyName;
 
 	std::vector<InetAddress> _assignedIps; // IPs assigned with addIp
 	Mutex _assignedIps_m;
 
 	std::vector<MulticastGroup> _multicastGroups;
 
-	std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending;
+	std::queue< std::pair< Array<char,ZT_MAX_MTU + 32>,unsigned int > > _injectPending;
 	Mutex _injectPending_m;
 
 	std::string _pathToHelpers;