Merge branch 'intrepidcs:master' into Npcap-fix

This commit is contained in:
vits71
2025-01-11 23:15:28 +01:00
committed by GitHub
124 changed files with 7785 additions and 1271 deletions
+13 -13
View File
@@ -64,7 +64,7 @@ bool FTD3XX::open() {
}
handle.emplace(tmpHandle);
closing = false;
setIsClosing(false);
readThread = std::thread(&FTD3XX::readTask, this);
writeThread = std::thread(&FTD3XX::writeTask, this);
@@ -81,23 +81,23 @@ bool FTD3XX::close() {
return false;
}
closing = true;
disconnected = false;
setIsClosing(true);
setIsDisconnected(false);
if(readThread.joinable())
readThread.join();
if(writeThread.joinable())
writeThread.join();
WriteOperation flushop;
readBuffer.pop(readBuffer.size());
while(writeQueue.try_dequeue(flushop)) {}
clearBuffers();
if(const auto ret = FT_Close(*handle); ret != FT_OK) {
addEvent(ret, APIEvent::Severity::EventWarning);
}
closing = false;
handle.reset();
setIsClosing(false);
return true;
}
@@ -110,7 +110,7 @@ void FTD3XX::readTask() {
FT_SetStreamPipe(*handle, false, false, READ_PIPE_ID, bufferSize);
FT_SetPipeTimeout(*handle, READ_PIPE_ID, 1);
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
ULONG received = 0;
OVERLAPPED overlap = {};
FT_InitializeOverlapped(*handle, &overlap);
@@ -119,13 +119,13 @@ void FTD3XX::readTask() {
#else
FT_ReadPipeAsync(*handle, 0, buffer, bufferSize, &received, &overlap);
#endif
while(!closing) {
while(!isClosing()) {
const auto ret = FT_GetOverlappedResult(*handle, &overlap, &received, true);
if(ret == FT_IO_PENDING)
continue;
if(ret != FT_OK) {
if(ret == FT_IO_ERROR) {
disconnected = true;
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
} else {
addEvent(ret, APIEvent::Severity::Error);
@@ -146,7 +146,7 @@ void FTD3XX::writeTask() {
FT_SetPipeTimeout(*handle, WRITE_PIPE_ID, 100);
WriteOperation writeOp;
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
continue;
@@ -160,13 +160,13 @@ void FTD3XX::writeTask() {
#else
FT_WritePipeAsync(*handle, 0, writeOp.bytes.data(), size, &sent, &overlap);
#endif
while(!closing) {
while(!isClosing()) {
const auto ret = FT_GetOverlappedResult(*handle, &overlap, &sent, true);
if(ret == FT_IO_PENDING)
continue;
if(ret != FT_OK) {
if(ret == FT_IO_ERROR) {
disconnected = true;
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
} else {
addEvent(ret, APIEvent::Severity::Error);
+9 -11
View File
@@ -117,7 +117,7 @@ bool CDCACM::close() {
return false;
}
closing = true;
setIsClosing(true);
if(readThread.joinable())
readThread.join();
@@ -125,8 +125,8 @@ bool CDCACM::close() {
if(writeThread.joinable())
writeThread.join();
closing = false;
disconnected = false;
setIsClosing(false);
setIsDisconnected(false);
if(modeChanging) {
// We're expecting this inode to go away after we close the device
@@ -140,9 +140,7 @@ bool CDCACM::close() {
int ret = ::close(fd);
fd = -1;
WriteOperation flushop;
readBuffer.clear();
while (writeQueue.try_dequeue(flushop)) {}
clearBuffers();
if(modeChanging) {
modeChanging = false;
@@ -173,7 +171,7 @@ void CDCACM::readTask() {
constexpr size_t READ_BUFFER_SIZE = 2048;
uint8_t readbuf[READ_BUFFER_SIZE];
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
fd_set rfds = {0};
struct timeval tv = {0};
FD_SET(fd, &rfds);
@@ -199,8 +197,8 @@ void CDCACM::readTask() {
// Requesting thread is responsible for calling close. This allows for more flexibility
});
break;
} else if(!closing && !fdIsValid() && !isDisconnected()) {
disconnected = true;
} else if(!isClosing() && !fdIsValid() && !isDisconnected()) {
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
}
@@ -210,7 +208,7 @@ void CDCACM::readTask() {
void CDCACM::writeTask() {
WriteOperation writeOp;
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
continue;
@@ -233,7 +231,7 @@ void CDCACM::writeTask() {
} else if (actualWritten < 0) {
if(!fdIsValid()) {
if(!isDisconnected()) {
disconnected = true;
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
} else
+5 -5
View File
@@ -166,13 +166,13 @@ bool FirmIO::close() {
return false;
}
closing = true;
setIsClosing(true);
if(readThread.joinable())
readThread.join();
closing = false;
disconnected = false;
setIsClosing(false);
setIsDisconnected(false);
int ret = 0;
if(vbase != nullptr) {
@@ -202,7 +202,7 @@ void FirmIO::readTask() {
std::cerr << "FirmIO::readTask setpriority failed : " << strerror(errno) << std::endl;
}
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
fd_set rfds = {0};
struct timeval tv = {0};
FD_SET(fd, &rfds);
@@ -244,7 +244,7 @@ void FirmIO::readTask() {
uint8_t* addr = reinterpret_cast<uint8_t*>(msg.payload.data.addr - PHY_ADDR_BASE + vbase);
while (!pushRx(addr, msg.payload.data.len)) {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // back-off so reading thread can empty the buffer
if (closing || isDisconnected()) {
if (isClosing() || isDisconnected()) {
break;
}
}
+9 -11
View File
@@ -81,7 +81,7 @@ bool FTDI::open() {
ftdi.flush();
// Create threads
closing = false;
setIsClosing(false);
readThread = std::thread(&FTDI::readTask, this);
writeThread = std::thread(&FTDI::writeTask, this);
@@ -94,7 +94,7 @@ bool FTDI::close() {
return false;
}
closing = true;
setIsClosing(true);
if(readThread.joinable())
readThread.join();
@@ -109,12 +109,10 @@ bool FTDI::close() {
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
}
WriteOperation flushop;
readBuffer.clear();
while(writeQueue.try_dequeue(flushop)) {}
clearBuffers();
closing = false;
disconnected = false;
setIsClosing(false);
setIsDisconnected(false);
return ret;
}
@@ -202,12 +200,12 @@ void FTDI::readTask() {
constexpr size_t READ_BUFFER_SIZE = 8;
uint8_t readbuf[READ_BUFFER_SIZE];
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
auto readBytes = ftdi.read(readbuf, READ_BUFFER_SIZE);
if(readBytes < 0) {
if(ErrorIsDisconnection(readBytes)) {
if(!isDisconnected()) {
disconnected = true;
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
} else
@@ -220,7 +218,7 @@ void FTDI::readTask() {
void FTDI::writeTask() {
WriteOperation writeOp;
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
continue;
@@ -230,7 +228,7 @@ void FTDI::writeTask() {
if(writeBytes < 0) {
if(ErrorIsDisconnection(writeBytes)) {
if(!isDisconnected()) {
disconnected = true;
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
break;
+5 -7
View File
@@ -258,28 +258,26 @@ bool PCAP::close() {
if(!isOpen())
return false;
closing = true; // Signal the threads that we are closing
setIsClosing(true); // Signal the threads that we are closing
pcap_breakloop(iface.fp);
#ifndef __linux__
pthread_cancel(readThread.native_handle());
#endif
readThread.join();
writeThread.join();
closing = false;
setIsClosing(false);
pcap_close(iface.fp);
iface.fp = nullptr;
WriteOperation flushop;
readBuffer.clear();
while(writeQueue.try_dequeue(flushop)) {}
clearBuffers();
return true;
}
void PCAP::readTask() {
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while (!closing) {
while (!isClosing()) {
pcap_dispatch(iface.fp, -1, [](uint8_t* obj, const struct pcap_pkthdr* header, const uint8_t* data) {
PCAP* driver = reinterpret_cast<PCAP*>(obj);
if(driver->ethPacketizer.inputUp({data, data + header->caplen})) {
@@ -294,7 +292,7 @@ void PCAP::writeTask() {
WriteOperation writeOp;
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing) {
while(!isClosing()) {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
continue;
+48 -42
View File
@@ -6,6 +6,7 @@
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <poll.h>
#include <unistd.h>
#include <ifaddrs.h>
#include <net/if.h>
@@ -72,7 +73,36 @@ TCP::Socket::~Socket() {
#endif
}
void TCP::Socket::poll(uint16_t event, uint32_t msTimeout) {
#ifdef _WIN32
WSAPOLLFD pfd;
pfd.fd = fd;
pfd.events = event;
::WSAPoll(&pfd, 1, msTimeout);
#else
struct pollfd pfd;
pfd.fd = fd;
pfd.events = event;
::poll(&pfd, 1, msTimeout);
#endif
}
void TCP::Find(std::vector<FoundDevice>& found) {
static const auto tcpDisabled = []() -> bool {
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4996)
#endif
const auto disabled = std::getenv("LIBICSNEO_DISABLE_TCP");
return disabled ? std::stoi(disabled) : false;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
};
if(tcpDisabled()) {
return;
}
static const auto MDNS_PORT = htons((unsigned short)5353);
static const auto MDNS_IP = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
@@ -256,16 +286,16 @@ void TCP::Find(std::vector<FoundDevice>& found) {
continue;
}
timeval timeout = {};
timeout.tv_usec = 50000;
fd_set readfs;
FD_ZERO(&readfs);
int nfds = WIN_INT(socket) + 1;
FD_SET(socket, &readfs);
while(true) {
const auto rxTill = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
while(std::chrono::steady_clock::now() < rxTill) {
static constexpr size_t bufferLen = 2048;
uint8_t buffer[bufferLen];
::select(nfds, &readfs, 0, 0, &timeout); // timeout is intentially not reset, we want timeout.tv_usec _total_
// keep trying till the timeout
const auto msWait = std::chrono::duration_cast<std::chrono::milliseconds>(rxTill - std::chrono::steady_clock::now()).count();
if(msWait < 0) {
break;
}
socket.poll(POLLIN, static_cast<uint32_t>(msWait));
const auto recvRet = ::recv(socket, (char*)buffer, bufferLen, 0);
static constexpr auto headerLength = 12;
if(recvRet < headerLength) {
@@ -460,13 +490,7 @@ bool TCP::open() {
}
#endif
timeval timeout = {};
timeout.tv_sec = 1;
fd_set writefs;
FD_ZERO(&writefs);
int nfds = WIN_INT(*partiallyOpenSocket) + 1;
FD_SET(*partiallyOpenSocket, &writefs);
::select(nfds, 0, &writefs, 0, &timeout);
partiallyOpenSocket->poll(POLLOUT, 1000);
if(::connect(*partiallyOpenSocket, (sockaddr*)&addr, sizeof(addr)) < 0) {
#ifdef _WIN32
@@ -502,20 +526,18 @@ bool TCP::close() {
return false;
}
closing = true;
disconnected = false;
setIsClosing(true);
setIsDisconnected(false);
if(readThread.joinable())
readThread.join();
if(writeThread.joinable())
writeThread.join();
WriteOperation flushop;
readBuffer.pop(readBuffer.size());
while(writeQueue.try_dequeue(flushop)) {}
clearBuffers();
socket.reset();
closing = false;
setIsClosing(false);
return true;
}
@@ -523,21 +545,13 @@ bool TCP::close() {
void TCP::readTask() {
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
const int nfds = WIN_INT(*socket) + 1;
fd_set readfs;
FD_ZERO(&readfs);
FD_SET(*socket, &readfs);
timeval timeout;
constexpr size_t READ_BUFFER_SIZE = 2048;
uint8_t readbuf[READ_BUFFER_SIZE];
while(!closing) {
while(!isClosing()) {
if(const auto received = ::recv(*socket, (char*)readbuf, READ_BUFFER_SIZE, 0); received > 0) {
pushRx(readbuf, received);
} else {
timeout.tv_sec = 0;
timeout.tv_usec = 50'000;
::select(nfds, &readfs, 0, 0, &timeout);
socket->poll(POLLIN, 100);
}
}
}
@@ -545,23 +559,15 @@ void TCP::readTask() {
void TCP::writeTask() {
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
const int nfds = WIN_INT(*socket) + 1;
fd_set writefs;
FD_ZERO(&writefs);
FD_SET(*socket, &writefs);
timeval timeout;
WriteOperation writeOp;
while(!closing) {
while(!isClosing()) {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
continue;
while(!closing) {
while(!isClosing()) {
if(::send(*socket, (char*)writeOp.bytes.data(), WIN_INT(writeOp.bytes.size()), 0) > 0)
break;
timeout.tv_sec = 0;
timeout.tv_usec = 100'000;
::select(nfds, 0, &writefs, 0, &timeout);
socket->poll(POLLOUT, 100);
}
}
}
+8 -9
View File
@@ -246,18 +246,17 @@ bool PCAP::close() {
return false;
}
closing = true; // Signal the threads that we are closing
setIsClosing(true); // Signal the threads that we are closing
readThread.join();
writeThread.join();
transmitThread.join();
closing = false;
setIsClosing(false);
pcap.close(iface.fp);
iface.fp = nullptr;
WriteOperation flushop;
readBuffer.clear();
while(writeQueue.try_dequeue(flushop)) {}
clearBuffers();
transmitQueue = nullptr;
return true;
@@ -267,7 +266,7 @@ void PCAP::readTask() {
struct pcap_pkthdr* header;
const uint8_t* data;
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing) {
while(!isClosing()) {
auto readBytes = pcap.next_ex(iface.fp, &header, &data);
if(readBytes < 0) {
report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
@@ -291,7 +290,7 @@ void PCAP::writeTask() {
pcap_send_queue* queue2 = pcap.sendqueue_alloc(128000);
pcap_send_queue* queue = queue1;
while(!closing) {
while(!isClosing()) {
// Potentially, we added frames to a second queue faster than the other thread was able to hand the first
// off to the kernel. In that case, wait for a minimal amount of time before checking whether we can
// transmit it again.
@@ -342,9 +341,9 @@ void PCAP::writeTask() {
}
void PCAP::transmitTask() {
while(!closing) {
while(!isClosing()) {
std::unique_lock<std::mutex> lk(transmitQueueMutex);
if(transmitQueueCV.wait_for(lk, std::chrono::milliseconds(100), [this] { return !!transmitQueue; }) && !closing && transmitQueue) {
if(transmitQueueCV.wait_for(lk, std::chrono::milliseconds(100), [this] { return !!transmitQueue; }) && !isClosing() && transmitQueue) {
pcap_send_queue* current = transmitQueue;
lk.unlock();
pcap.sendqueue_transmit(iface.fp, current, 0);
+7 -9
View File
@@ -326,12 +326,12 @@ bool VCP::close() {
return false;
}
closing = true; // Signal the threads that we are closing
setIsClosing(true); // Signal the threads that we are closing
for(auto& t : threads)
t->join(); // Wait for the threads to close
readThread.join();
writeThread.join();
closing = false;
setIsClosing(false);
if(!CloseHandle(detail->handle)) {
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
@@ -357,9 +357,7 @@ bool VCP::close() {
detail->overlappedWait.hEvent = INVALID_HANDLE_VALUE;
}
WriteOperation flushop;
readBuffer.clear();
while(writeQueue.try_dequeue(flushop)) {}
clearBuffers();
if(!ret)
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
@@ -379,7 +377,7 @@ void VCP::readTask() {
IOTaskState state = LAUNCH;
DWORD bytesRead = 0;
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
switch(state) {
case LAUNCH: {
COMSTAT comStatus;
@@ -401,7 +399,7 @@ void VCP::readTask() {
else if(lastError != ERROR_SUCCESS) {
if(lastError == ERROR_ACCESS_DENIED) {
if(!isDisconnected()) {
disconnected = true;
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
} else
@@ -432,7 +430,7 @@ void VCP::writeTask() {
VCP::WriteOperation writeOp;
DWORD bytesWritten = 0;
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
switch(state) {
case LAUNCH: {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
@@ -448,7 +446,7 @@ void VCP::writeTask() {
}
else if(winerr == ERROR_ACCESS_DENIED) {
if(!isDisconnected()) {
disconnected = true;
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
} else