summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--osdep/BSDEthernetTap.cpp58
-rw-r--r--osdep/BSDEthernetTap.hpp1
-rw-r--r--osdep/LinuxEthernetTap.cpp22
-rw-r--r--osdep/LinuxEthernetTap.hpp1
-rw-r--r--osdep/OSXEthernetTap.cpp24
-rw-r--r--osdep/OSXEthernetTap.hpp1
-rw-r--r--osdep/TestEthernetTap.hpp4
-rw-r--r--osdep/WindowsEthernetTap.cpp41
-rw-r--r--osdep/WindowsEthernetTap.hpp5
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;