mirror of
https://github.com/tnodir/fort
synced 2024-11-15 07:45:22 +00:00
Driver: Wait for asynchronously deleting flows on unload
This commit is contained in:
parent
a4cf94f762
commit
062bfa0ed6
@ -446,9 +446,6 @@ static void NTAPI fort_callout_flow_delete(UINT16 layerId, UINT32 calloutId, UIN
|
||||
UNUSED(layerId);
|
||||
UNUSED(calloutId);
|
||||
|
||||
if (fort_device() == NULL)
|
||||
return; /* Flow is asynchronously deleting, but the Device was already removed */
|
||||
|
||||
fort_flow_delete(&fort_device()->stat, flowContext);
|
||||
}
|
||||
|
||||
|
@ -161,28 +161,47 @@ static void fort_flow_context_remove(PFORT_STAT stat, PFORT_FLOW flow)
|
||||
const UINT64 flow_id = flow->flow_id;
|
||||
const BOOL is_tcp = (flow->opt.flags & FORT_FLOW_TCP);
|
||||
const BOOL isIPv6 = (flow->opt.flags & FORT_FLOW_IP6);
|
||||
BOOL is_pending;
|
||||
|
||||
if (is_tcp) {
|
||||
if (isIPv6) {
|
||||
FwpsFlowRemoveContext0(flow_id, FWPS_LAYER_STREAM_V6, stat->stream6_id);
|
||||
FwpsFlowRemoveContext0(
|
||||
const NTSTATUS stream6_status =
|
||||
FwpsFlowRemoveContext0(flow_id, FWPS_LAYER_STREAM_V6, stat->stream6_id);
|
||||
const NTSTATUS in_transport6_status = FwpsFlowRemoveContext0(
|
||||
flow_id, FWPS_LAYER_INBOUND_TRANSPORT_V6, stat->in_transport6_id);
|
||||
FwpsFlowRemoveContext0(
|
||||
const NTSTATUS out_transport6_status = FwpsFlowRemoveContext0(
|
||||
flow_id, FWPS_LAYER_OUTBOUND_TRANSPORT_V6, stat->out_transport6_id);
|
||||
|
||||
is_pending = (stream6_status == STATUS_PENDING || in_transport6_status == STATUS_PENDING
|
||||
|| out_transport6_status == STATUS_PENDING);
|
||||
} else {
|
||||
FwpsFlowRemoveContext0(flow_id, FWPS_LAYER_STREAM_V4, stat->stream4_id);
|
||||
FwpsFlowRemoveContext0(
|
||||
const NTSTATUS stream4_status =
|
||||
FwpsFlowRemoveContext0(flow_id, FWPS_LAYER_STREAM_V4, stat->stream4_id);
|
||||
const NTSTATUS in_transport4_status = FwpsFlowRemoveContext0(
|
||||
flow_id, FWPS_LAYER_INBOUND_TRANSPORT_V4, stat->in_transport4_id);
|
||||
FwpsFlowRemoveContext0(
|
||||
const NTSTATUS out_transport4_status = FwpsFlowRemoveContext0(
|
||||
flow_id, FWPS_LAYER_OUTBOUND_TRANSPORT_V4, stat->out_transport4_id);
|
||||
|
||||
is_pending = (stream4_status == STATUS_PENDING || in_transport4_status == STATUS_PENDING
|
||||
|| out_transport4_status == STATUS_PENDING);
|
||||
}
|
||||
} else {
|
||||
if (isIPv6) {
|
||||
FwpsFlowRemoveContext0(flow_id, FWPS_LAYER_DATAGRAM_DATA_V6, stat->datagram6_id);
|
||||
const NTSTATUS datagram6_status = FwpsFlowRemoveContext0(
|
||||
flow_id, FWPS_LAYER_DATAGRAM_DATA_V6, stat->datagram6_id);
|
||||
|
||||
is_pending = (datagram6_status == STATUS_PENDING);
|
||||
} else {
|
||||
FwpsFlowRemoveContext0(flow_id, FWPS_LAYER_DATAGRAM_DATA_V4, stat->datagram4_id);
|
||||
const NTSTATUS datagram4_status = FwpsFlowRemoveContext0(
|
||||
flow_id, FWPS_LAYER_DATAGRAM_DATA_V4, stat->datagram4_id);
|
||||
|
||||
is_pending = (datagram4_status == STATUS_PENDING);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_pending) {
|
||||
fort_stat_flags_set(stat, FORT_STAT_FLOW_PENDING, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void fort_flow_close(PFORT_FLOW flow)
|
||||
@ -289,15 +308,37 @@ FORT_API void fort_stat_open(PFORT_STAT stat)
|
||||
KeInitializeSpinLock(&stat->lock);
|
||||
}
|
||||
|
||||
FORT_API void fort_stat_close(PFORT_STAT stat)
|
||||
static BOOL fort_stat_close_flows(PFORT_STAT stat)
|
||||
{
|
||||
KLOCK_QUEUE_HANDLE lock_queue;
|
||||
KeAcquireInStackQueuedSpinLock(&stat->lock, &lock_queue);
|
||||
|
||||
fort_stat_flags_set(stat, FORT_STAT_CLOSED, TRUE);
|
||||
fort_stat_flags_set(stat, FORT_STAT_FLOW_PENDING, FALSE);
|
||||
|
||||
tommy_hashdyn_foreach_node_arg(&stat->flows_map, fort_flow_context_remove, stat);
|
||||
|
||||
const BOOL not_pending = (fort_stat_flags(stat) & FORT_STAT_FLOW_PENDING) == 0;
|
||||
|
||||
KeReleaseInStackQueuedSpinLock(&lock_queue);
|
||||
|
||||
return not_pending;
|
||||
}
|
||||
|
||||
FORT_API void fort_stat_close(PFORT_STAT stat)
|
||||
{
|
||||
fort_stat_flags_set(stat, FORT_STAT_CLOSED, TRUE);
|
||||
|
||||
while (!fort_stat_close_flows(stat)) {
|
||||
/* Wait for asynchronously deleting flows */
|
||||
LARGE_INTEGER delay;
|
||||
delay.QuadPart = -5000000; /* sleep 500000us (500ms) */
|
||||
|
||||
KeDelayExecutionThread(KernelMode, FALSE, &delay);
|
||||
}
|
||||
|
||||
KLOCK_QUEUE_HANDLE lock_queue;
|
||||
KeAcquireInStackQueuedSpinLock(&stat->lock, &lock_queue);
|
||||
|
||||
tommy_arrayof_done(&stat->procs);
|
||||
tommy_hashdyn_done(&stat->procs_map);
|
||||
|
||||
|
@ -86,6 +86,7 @@ typedef struct fort_flow
|
||||
#define FORT_STAT_CLOSED 0x01
|
||||
#define FORT_STAT_LOG 0x02
|
||||
#define FORT_STAT_TIME_CHANGED 0x04
|
||||
#define FORT_STAT_FLOW_PENDING 0x08
|
||||
|
||||
typedef struct fort_stat
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user