By attaching to NDIS device instead of creating our own device for I/O,
the adapter is always running before client is able to connect and
register rings. NDIS also won't allow adapter to pause with connected
clients.
Signed-off-by: Simon Rozman <simon@rozman.si>
With no PnP notifications and custom surprise removal code we do not
need the TUN_FLAGS_PRESENT any more. The traffic is stopped when handle
is closed or adapter is somehow paused. Though by reusing the NDIS device
for our I/O, the adapter will not be able to pause with a client
connected.
Signed-off-by: Simon Rozman <simon@rozman.si>
Before the TunProcessReceiveData() thread terminates or adapter is
paused, we wait for all receive NBLs to be returned. Unfortunately,
IoReleaseRemoveLockAndWait() leaves the remove lock in non reusable
state.
To be able to start receiving packets on existing adapter again, we
(re)initialize the remove lock on ring registration or adapter resume.
The former addresses TunProcessReceiveData()'s
IoReleaseRemoveLockAndWait() call, the later addresses the TunPause()'s.
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit moves NBL post-processing (moving ring head, releasing NBL)
to MINIPORT_RETURN_NET_BUFFER_LISTS handler.
Signed-off-by: Simon Rozman <simon@rozman.si>
We do not need to share-lock the TransitionLock for complete NBL chain.
This commit should improve better state transition response, thou until
NDIS is sending a single NBL per MINIPORT_SEND_NET_BUFFER_LISTS call,
this should not have a considerable effect.
Since the skibNbl: call of NdisMSendNetBufferListsComplete() is made
inside the TransactionLock at dispatch IRQL, a dispatch IRQL hint was
added to the NdisMSendNetBufferListsComplete() call.
Signed-off-by: Simon Rozman <simon@rozman.si>
On client closing the handle there is a potential race if somebody
resets the TailMoved event of receive ring at the right time. Rather
than rely on TailMoved event, we introduce our own Disconnected
notification event and have the receive thread wait on both. The
Disconnected event is also usable as TUN_FLAGS_CONNECTED substitute.
Signed-off-by: Simon Rozman <simon@rozman.si>
NDIS may call MINIPORT_SEND_NET_BUFFER_LISTS from parallel threads to
queue as many packets as fast as possible. Initial implementation of
ring buffers used a spin lock to completely serialize sending packets
making it sub-optimal and burning large amount of CPU.
This commit uses locked section to allocate space for packet(s) in the
ring. It copies the packets unlocked, then it locks again to adjust the
ring tail.
Signed-off-by: Simon Rozman <simon@rozman.si>
This demonstrates the use of ring buffers in its simplest, purest form.
No performance optimizations were made.
Signed-off-by: Simon Rozman <simon@rozman.si>
The transition lock ensures that TunPause won't drop its last reference
until the shared transition lock is dropped.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
It turns out that waiting for them to come back in the return function
introduces extremely high latency.
We need to eventually stop doing this and move to a proper ring buffer.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>