mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-19 13:07:55 +00:00
Fix for GitHub issue #25
This commit is contained in:
parent
e514fe2bff
commit
60ac1b77c5
@ -17,7 +17,7 @@ CXXFLAGS=$(CFLAGS) -fno-rtti
|
|||||||
|
|
||||||
include objects.mk
|
include objects.mk
|
||||||
|
|
||||||
all: one cli mac-tap
|
all: one cli
|
||||||
|
|
||||||
one: $(OBJS)
|
one: $(OBJS)
|
||||||
$(CXX) $(CXXFLAGS) -o zerotier-one main.cpp $(OBJS) $(LIBS)
|
$(CXX) $(CXXFLAGS) -o zerotier-one main.cpp $(OBJS) $(LIBS)
|
||||||
|
@ -533,6 +533,7 @@ void EthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const
|
|||||||
*((uint16_t *)(putBuf + 12)) = htons((uint16_t)etherType);
|
*((uint16_t *)(putBuf + 12)) = htons((uint16_t)etherType);
|
||||||
memcpy(putBuf + 14,data,len);
|
memcpy(putBuf + 14,data,len);
|
||||||
len += 14;
|
len += 14;
|
||||||
|
|
||||||
int n = ::write(_fd,putBuf,len);
|
int n = ::write(_fd,putBuf,len);
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
LOG("error writing packet to Ethernet tap device: %s",strerror(errno));
|
LOG("error writing packet to Ethernet tap device: %s",strerror(errno));
|
||||||
@ -658,7 +659,8 @@ void EthernetTap::threadMain()
|
|||||||
{
|
{
|
||||||
fd_set readfds,nullfds;
|
fd_set readfds,nullfds;
|
||||||
MAC to,from;
|
MAC to,from;
|
||||||
char getBuf[4096 + 14];
|
int n,nfds,r;
|
||||||
|
char getBuf[8194];
|
||||||
Buffer<4096> data;
|
Buffer<4096> data;
|
||||||
|
|
||||||
// Wait for a moment after startup -- wait for Network to finish
|
// Wait for a moment after startup -- wait for Network to finish
|
||||||
@ -667,8 +669,9 @@ void EthernetTap::threadMain()
|
|||||||
|
|
||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
FD_ZERO(&nullfds);
|
FD_ZERO(&nullfds);
|
||||||
int nfds = (int)std::max(_shutdownSignalPipe[0],_fd) + 1;
|
nfds = (int)std::max(_shutdownSignalPipe[0],_fd) + 1;
|
||||||
|
|
||||||
|
r = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
FD_SET(_shutdownSignalPipe[0],&readfds);
|
FD_SET(_shutdownSignalPipe[0],&readfds);
|
||||||
FD_SET(_fd,&readfds);
|
FD_SET(_fd,&readfds);
|
||||||
@ -678,20 +681,31 @@ void EthernetTap::threadMain()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (FD_ISSET(_fd,&readfds)) {
|
if (FD_ISSET(_fd,&readfds)) {
|
||||||
int n = (int)::read(_fd,getBuf,_mtu + 14);
|
n = (int)::read(_fd,getBuf + r,sizeof(getBuf) - r);
|
||||||
|
if (n < 0) {
|
||||||
if (n > 14) {
|
|
||||||
for(int i=0;i<6;++i)
|
|
||||||
to.data[i] = (unsigned char)getBuf[i];
|
|
||||||
for(int i=0;i<6;++i)
|
|
||||||
from.data[i] = (unsigned char)getBuf[i + 6];
|
|
||||||
data.copyFrom(getBuf + 14,(unsigned int)n - 14);
|
|
||||||
_handler(_arg,from,to,ntohs(((const uint16_t *)getBuf)[6]),data);
|
|
||||||
} else if (n < 0) {
|
|
||||||
if ((errno != EINTR)&&(errno != ETIMEDOUT)) {
|
if ((errno != EINTR)&&(errno != ETIMEDOUT)) {
|
||||||
TRACE("unexpected error reading from tap: %s",strerror(errno));
|
TRACE("unexpected error reading from tap: %s",strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Some tap drivers like to send the ethernet frame and the
|
||||||
|
// payload in two chunks, so handle that by accumulating
|
||||||
|
// data until we have at least a frame.
|
||||||
|
r += n;
|
||||||
|
if (r > 14) {
|
||||||
|
if (r > (_mtu + 14)) // sanity check for weird TAP behavior on some platforms
|
||||||
|
r = _mtu + 14;
|
||||||
|
for(int i=0;i<6;++i)
|
||||||
|
to.data[i] = (unsigned char)getBuf[i];
|
||||||
|
for(int i=0;i<6;++i)
|
||||||
|
from.data[i] = (unsigned char)getBuf[i + 6];
|
||||||
|
unsigned int etherType = ntohs(((const uint16_t *)getBuf)[6]);
|
||||||
|
if (etherType != 0x8100) { // VLAN tagged frames are not supported!
|
||||||
|
data.copyFrom(getBuf + 14,(unsigned int)r - 14);
|
||||||
|
_handler(_arg,from,to,etherType,data);
|
||||||
|
}
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -648,7 +648,9 @@ tuntap_interface::cdev_write(uio_t uio, int ioflag)
|
|||||||
mb = first;
|
mb = first;
|
||||||
while (uio_resid(uio) > 0) {
|
while (uio_resid(uio) > 0) {
|
||||||
/* copy a chunk. enforce mtu (don't know if this is correct behaviour) */
|
/* copy a chunk. enforce mtu (don't know if this is correct behaviour) */
|
||||||
chunk_len = min(ifnet_mtu(ifp), min(uio_resid(uio), mlen));
|
// ... evidently not :) -- Adam Ierymenko <adam.ierymenko@zerotier.com>
|
||||||
|
//chunk_len = min(ifnet_mtu(ifp), min(uio_resid(uio), mlen));
|
||||||
|
chunk_len = min(uio_resid(uio),mlen);
|
||||||
error = uiomove((caddr_t) mbuf_data(mb), chunk_len, uio);
|
error = uiomove((caddr_t) mbuf_data(mb), chunk_len, uio);
|
||||||
if (error) {
|
if (error) {
|
||||||
log(LOG_ERR, "tuntap: could not copy data from userspace: %d\n", error);
|
log(LOG_ERR, "tuntap: could not copy data from userspace: %d\n", error);
|
||||||
@ -664,7 +666,9 @@ tuntap_interface::cdev_write(uio_t uio, int ioflag)
|
|||||||
copied += chunk_len;
|
copied += chunk_len;
|
||||||
|
|
||||||
/* if done, break the loop */
|
/* if done, break the loop */
|
||||||
if (uio_resid(uio) <= 0 || copied >= ifnet_mtu(ifp))
|
//if (uio_resid(uio) <= 0 || copied >= ifnet_mtu(ifp))
|
||||||
|
// break;
|
||||||
|
if (uio_resid(uio) <= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* allocate a new mbuf if the current is filled */
|
/* allocate a new mbuf if the current is filled */
|
||||||
|
Loading…
Reference in New Issue
Block a user