Show error if tun queue grows too large.

This happens because the TAP NDIS6 driver is buggy on Windows 7.
This commit is contained in:
Ludvig Strigeus 2018-10-21 23:35:40 +02:00
parent bdcf04ec93
commit 7afef3865f
3 changed files with 22 additions and 0 deletions

View file

@ -22,6 +22,8 @@ Changes:
9.Resolve DNS queries using a background thread, to make it 9.Resolve DNS queries using a background thread, to make it
possible to interrupt slow DNS queries. possible to interrupt slow DNS queries.
10.IPv6 endpoint was printed incorrectly on the Advanced tab 10.IPv6 endpoint was printed incorrectly on the Advanced tab
11.Show an error message and drop packets if the TUN queue grows
too large. This is a problem with the TAP NDIS6 driver on Win7.
2018-10-08 - TunSafe v1.4 2018-10-08 - TunSafe v1.4

View file

@ -26,6 +26,9 @@ enum {
HARD_MAXIMUM_QUEUE_SIZE = 102400, HARD_MAXIMUM_QUEUE_SIZE = 102400,
MAX_BYTES_IN_UDP_OUT_QUEUE = 256 * 1024, MAX_BYTES_IN_UDP_OUT_QUEUE = 256 * 1024,
MAX_BYTES_IN_UDP_OUT_QUEUE_SMALL = (256 + 64) * 1024, MAX_BYTES_IN_UDP_OUT_QUEUE_SMALL = (256 + 64) * 1024,
// On Windows 7 with NDIS6 sometimes the tun queue blows up.
HARD_MAXIMUM_TUN_QUEUE_SIZE = 16384,
}; };
enum { enum {
@ -1569,11 +1572,13 @@ bool TunWin32Adapter::RunPrePostCommand(const std::vector<std::string> &vec) {
TunWin32Iocp::TunWin32Iocp(DnsBlocker *blocker, TunsafeBackendWin32 *backend) : adapter_(blocker, backend->guid_), backend_(backend) { TunWin32Iocp::TunWin32Iocp(DnsBlocker *blocker, TunsafeBackendWin32 *backend) : adapter_(blocker, backend->guid_), backend_(backend) {
wqueue_end_ = &wqueue_; wqueue_end_ = &wqueue_;
wqueue_ = NULL; wqueue_ = NULL;
wqueue_size_ = 0;
thread_ = NULL; thread_ = NULL;
completion_port_handle_ = NULL; completion_port_handle_ = NULL;
packet_handler_ = NULL; packet_handler_ = NULL;
exit_thread_ = false; exit_thread_ = false;
did_show_tun_queue_warning_ = false;
} }
TunWin32Iocp::~TunWin32Iocp() { TunWin32Iocp::~TunWin32Iocp() {
@ -1716,6 +1721,7 @@ void TunWin32Iocp::ThreadMain() {
pending_writes = wqueue_; pending_writes = wqueue_;
wqueue_end_ = &wqueue_; wqueue_end_ = &wqueue_;
wqueue_ = NULL; wqueue_ = NULL;
wqueue_size_ = 0;
mutex_.Release(); mutex_.Release();
if (!pending_writes) if (!pending_writes)
break; break;
@ -1785,6 +1791,17 @@ void TunWin32Iocp::StopThread() {
void TunWin32Iocp::WriteTunPacket(Packet *packet) { void TunWin32Iocp::WriteTunPacket(Packet *packet) {
packet->next = NULL; packet->next = NULL;
mutex_.Acquire(); mutex_.Acquire();
if (wqueue_size_ >= HARD_MAXIMUM_TUN_QUEUE_SIZE) {
mutex_.Release();
FreePacket(packet);
if (!did_show_tun_queue_warning_) {
did_show_tun_queue_warning_ = true;
RERROR("TUN Queue Overload! This might happen if you use the NDIS6 driver on Windows 7.");
}
return;
}
wqueue_size_++;
Packet *was_empty = wqueue_; Packet *was_empty = wqueue_;
*wqueue_end_ = packet; *wqueue_end_ = packet;
wqueue_end_ = &packet->next; wqueue_end_ = &packet->next;

View file

@ -157,6 +157,9 @@ private:
Mutex mutex_; Mutex mutex_;
bool exit_thread_; bool exit_thread_;
bool did_show_tun_queue_warning_;
int wqueue_size_;
// All packets queued for writing // All packets queued for writing
Packet *wqueue_, **wqueue_end_; Packet *wqueue_, **wqueue_end_;