diff options
-rw-r--r-- | osdep/BSDEthernetTap.cpp | 58 | ||||
-rw-r--r-- | osdep/BSDEthernetTap.hpp | 1 | ||||
-rw-r--r-- | osdep/LinuxEthernetTap.cpp | 22 | ||||
-rw-r--r-- | osdep/LinuxEthernetTap.hpp | 1 | ||||
-rw-r--r-- | osdep/OSXEthernetTap.cpp | 24 | ||||
-rw-r--r-- | osdep/OSXEthernetTap.hpp | 1 | ||||
-rw-r--r-- | osdep/TestEthernetTap.hpp | 4 | ||||
-rw-r--r-- | osdep/WindowsEthernetTap.cpp | 41 | ||||
-rw-r--r-- | osdep/WindowsEthernetTap.hpp | 5 |
9 files changed, 82 insertions, 75 deletions
diff --git a/osdep/BSDEthernetTap.cpp b/osdep/BSDEthernetTap.cpp index 87a9aece..5bb5fbd1 100644 --- a/osdep/BSDEthernetTap.cpp +++ b/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. diff --git a/osdep/BSDEthernetTap.hpp b/osdep/BSDEthernetTap.hpp index 3cb9c10e..fd2685f3 100644 --- a/osdep/BSDEthernetTap.hpp +++ b/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(); diff --git a/osdep/LinuxEthernetTap.cpp b/osdep/LinuxEthernetTap.cpp index 2d3891e3..6a3ac4cb 100644 --- a/osdep/LinuxEthernetTap.cpp +++ b/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); diff --git a/osdep/LinuxEthernetTap.hpp b/osdep/LinuxEthernetTap.hpp index ab9d2370..e05dee8c 100644 --- a/osdep/LinuxEthernetTap.hpp +++ b/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(); diff --git a/osdep/OSXEthernetTap.cpp b/osdep/OSXEthernetTap.cpp index 53c9ba98..f5e1c43f 100644 --- a/osdep/OSXEthernetTap.cpp +++ b/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); diff --git a/osdep/OSXEthernetTap.hpp b/osdep/OSXEthernetTap.hpp index ed7f39c3..d0a8a99d 100644 --- a/osdep/OSXEthernetTap.hpp +++ b/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(); diff --git a/osdep/TestEthernetTap.hpp b/osdep/TestEthernetTap.hpp index afd89541..047a19b1 100644 --- a/osdep/TestEthernetTap.hpp +++ b/osdep/TestEthernetTap.hpp @@ -139,6 +139,10 @@ public: { } + inline void setMtu(unsigned int mtu) + { + } + private: uint64_t _nwid; std::string _dev; diff --git a/osdep/WindowsEthernetTap.cpp b/osdep/WindowsEthernetTap.cpp index c37c7410..b4ff739a 100644 --- a/osdep/WindowsEthernetTap.cpp +++ b/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) { diff --git a/osdep/WindowsEthernetTap.hpp b/osdep/WindowsEthernetTap.hpp index a3c1c0c3..2114dfd0 100644 --- a/osdep/WindowsEthernetTap.hpp +++ b/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; |