From 1e2a9437dcdb0810d36257a5baeb6e3fa7cc0736 Mon Sep 17 00:00:00 2001 From: Nodir Temirkhodjaev Date: Sun, 8 Jan 2023 15:24:56 +0300 Subject: [PATCH] Driver: Shaper: Fix packets handling --- src/driver/evt/FORTEVT_MSG00001.bin | Bin 1556 -> 1620 bytes src/driver/evt/fortevt.h | 9 +++ src/driver/evt/fortevt.mc | 5 ++ src/driver/fortcout.c | 33 ++++++--- src/driver/fortpkt.c | 94 +++++++++++++++++-------- src/driver/fortpkt.h | 8 ++- src/driver/fortstat.c | 105 +++++++++++++--------------- src/ui/util/conf/confutil.cpp | 2 +- 8 files changed, 161 insertions(+), 95 deletions(-) diff --git a/src/driver/evt/FORTEVT_MSG00001.bin b/src/driver/evt/FORTEVT_MSG00001.bin index 3d788b8bc94c681ae83c1eb774903e863700fcd4..ca234126606b00d5257dfa2bbf96b0953bbac05e 100644 GIT binary patch delta 55 zcmbQjbA@Mug&;En>j42)1_nk3wgXH+{AQzPGApCQWIj42)1_nk3wgXH+yk?_kGVA0wtQi1-N(jFI diff --git a/src/driver/evt/fortevt.h b/src/driver/evt/fortevt.h index e8a7f50b..99e74d18 100644 --- a/src/driver/evt/fortevt.h +++ b/src/driver/evt/fortevt.h @@ -243,6 +243,15 @@ // #define FORT_SHAPER_PACKET_INJECTION_CALL_ERROR ((NTSTATUS)0xC0050002L) +// +// MessageId: FORT_SHAPER_PACKET_CLONE_ERROR +// +// MessageText: +// +// Shaper: Packet clone error. +// +#define FORT_SHAPER_PACKET_CLONE_ERROR ((NTSTATUS)0xC0050003L) + /* ProcessTree */ // // MessageId: FORT_PSTREE_UPDATE_ERROR diff --git a/src/driver/evt/fortevt.mc b/src/driver/evt/fortevt.mc index e26f277b..1b9b8bac 100644 --- a/src/driver/evt/fortevt.mc +++ b/src/driver/evt/fortevt.mc @@ -138,6 +138,11 @@ Language=English Shaper: Packet injection call error. . +MessageId=3 Facility=Shaper Severity=Error SymbolicName=FORT_SHAPER_PACKET_CLONE_ERROR +Language=English +Shaper: Packet clone error. +. + ;/* ProcessTree */ MessageId=1 Facility=ProcessTree Severity=Error SymbolicName=FORT_PSTREE_UPDATE_ERROR diff --git a/src/driver/fortcout.c b/src/driver/fortcout.c index 6b6e95b0..b134bd34 100644 --- a/src/driver/fortcout.c +++ b/src/driver/fortcout.c @@ -408,9 +408,10 @@ static void NTAPI fort_callout_flow_delete(UINT16 layerId, UINT32 calloutId, UIN fort_flow_delete(&fort_device()->stat, flowContext); } -static void NTAPI fort_callout_transport_classify(const FWPS_INCOMING_VALUES0 *inFixedValues, +static void fort_callout_transport_classify(const FWPS_INCOMING_VALUES0 *inFixedValues, const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues, const PNET_BUFFER_LIST netBufList, - const FWPS_FILTER0 *filter, UINT64 flowContext, FWPS_CLASSIFY_OUT0 *classifyOut) + const FWPS_FILTER0 *filter, UINT64 flowContext, FWPS_CLASSIFY_OUT0 *classifyOut, + BOOL inbound) { if ((classifyOut->rights & FWPS_RIGHT_ACTION_WRITE) == 0 || classifyOut->actionType == FWP_ACTION_BLOCK) @@ -419,8 +420,8 @@ static void NTAPI fort_callout_transport_classify(const FWPS_INCOMING_VALUES0 *i if (!FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_ALE_CLASSIFY_REQUIRED) && netBufList != NULL /* Process the Packet by Shaper */ - && fort_shaper_packet_process( - &fort_device()->shaper, inFixedValues, inMetaValues, netBufList, flowContext)) { + && fort_shaper_packet_process(&fort_device()->shaper, inFixedValues, inMetaValues, + netBufList, flowContext, inbound)) { fort_callout_classify_drop(classifyOut); /* drop */ return; @@ -429,6 +430,22 @@ static void NTAPI fort_callout_transport_classify(const FWPS_INCOMING_VALUES0 *i fort_callout_classify_permit(filter, classifyOut); /* permit */ } +static void NTAPI fort_callout_transport_classify_in(const FWPS_INCOMING_VALUES0 *inFixedValues, + const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues, const PNET_BUFFER_LIST netBufList, + const FWPS_FILTER0 *filter, UINT64 flowContext, FWPS_CLASSIFY_OUT0 *classifyOut) +{ + fort_callout_transport_classify(inFixedValues, inMetaValues, netBufList, filter, flowContext, + classifyOut, /*inbound=*/TRUE); +} + +static void NTAPI fort_callout_transport_classify_out(const FWPS_INCOMING_VALUES0 *inFixedValues, + const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues, const PNET_BUFFER_LIST netBufList, + const FWPS_FILTER0 *filter, UINT64 flowContext, FWPS_CLASSIFY_OUT0 *classifyOut) +{ + fort_callout_transport_classify(inFixedValues, inMetaValues, netBufList, filter, flowContext, + classifyOut, /*inbound=*/FALSE); +} + static void NTAPI fort_callout_transport_delete( UINT16 layerId, UINT32 calloutId, UINT64 flowContext) { @@ -547,7 +564,7 @@ FORT_API NTSTATUS fort_callout_install(PDEVICE_OBJECT device) /* IPv4 inbound transport callout */ c.calloutKey = FORT_GUID_CALLOUT_IN_TRANSPORT_V4; - c.classifyFn = (FWPS_CALLOUT_CLASSIFY_FN0) fort_callout_transport_classify; + c.classifyFn = (FWPS_CALLOUT_CLASSIFY_FN0) fort_callout_transport_classify_in; c.flowDeleteFn = fort_callout_transport_delete; /* reuse c.flags */ @@ -561,7 +578,7 @@ FORT_API NTSTATUS fort_callout_install(PDEVICE_OBJECT device) /* IPv6 inbound transport callout */ c.calloutKey = FORT_GUID_CALLOUT_IN_TRANSPORT_V6; - c.classifyFn = (FWPS_CALLOUT_CLASSIFY_FN0) fort_callout_transport_classify; + c.classifyFn = (FWPS_CALLOUT_CLASSIFY_FN0) fort_callout_transport_classify_in; /* reuse c.flowDeleteFn & c.flags */ @@ -574,7 +591,7 @@ FORT_API NTSTATUS fort_callout_install(PDEVICE_OBJECT device) /* IPv4 outbound transport callout */ c.calloutKey = FORT_GUID_CALLOUT_OUT_TRANSPORT_V4; - c.classifyFn = (FWPS_CALLOUT_CLASSIFY_FN0) fort_callout_transport_classify; + c.classifyFn = (FWPS_CALLOUT_CLASSIFY_FN0) fort_callout_transport_classify_out; /* reuse c.flowDeleteFn & c.flags */ @@ -587,7 +604,7 @@ FORT_API NTSTATUS fort_callout_install(PDEVICE_OBJECT device) /* IPv6 outbound transport callout */ c.calloutKey = FORT_GUID_CALLOUT_OUT_TRANSPORT_V6; - c.classifyFn = (FWPS_CALLOUT_CLASSIFY_FN0) fort_callout_transport_classify; + c.classifyFn = (FWPS_CALLOUT_CLASSIFY_FN0) fort_callout_transport_classify_out; /* reuse c.flowDeleteFn & c.flags */ diff --git a/src/driver/fortpkt.c b/src/driver/fortpkt.c index adca251e..c95511e5 100644 --- a/src/driver/fortpkt.c +++ b/src/driver/fortpkt.c @@ -14,9 +14,6 @@ #define HTONL(l) _byteswap_ulong(l) -#define fort_shaper_injection_id(shaper, isIPv6) \ - ((isIPv6) ? (shaper)->injection_transport6_id : (shaper)->injection_transport4_id) - typedef void(NTAPI *FORT_PACKET_FOREACH_FUNC)(PFORT_SHAPER, PFORT_PACKET); static LARGE_INTEGER g_QpcFrequency; @@ -52,7 +49,7 @@ static ULONG fort_packet_data_length(const PNET_BUFFER_LIST netBufList) ULONG data_length = 0; PNET_BUFFER netBuf = NET_BUFFER_LIST_FIRST_NB(netBufList); - while (netBuf) { + while (netBuf != NULL) { data_length += NET_BUFFER_DATA_LENGTH(netBuf); netBuf = NET_BUFFER_NEXT_NB(netBuf); } @@ -173,11 +170,18 @@ static NTSTATUS fort_shaper_packet_inject_out(PFORT_SHAPER shaper, const PFORT_P (FWPS_INJECT_COMPLETE0) &fort_packet_inject_complete, pkt); } +inline static HANDLE fort_shaper_injection_id(PFORT_SHAPER shaper, BOOL isIPv6, BOOL inbound) +{ + return inbound + ? (isIPv6 ? shaper->injection_in_transport6_id : shaper->injection_in_transport4_id) + : (isIPv6 ? shaper->injection_out_transport6_id : shaper->injection_out_transport4_id); +} + static void fort_shaper_packet_inject(PFORT_SHAPER shaper, PFORT_PACKET pkt) { const BOOL inbound = (pkt->flags & FORT_PACKET_INBOUND) != 0; const BOOL isIPv6 = (pkt->flags & FORT_PACKET_IP6) != 0; - const HANDLE injection_id = fort_shaper_injection_id(shaper, isIPv6); + const HANDLE injection_id = fort_shaper_injection_id(shaper, isIPv6, inbound); const ADDRESS_FAMILY addressFamily = (isIPv6 ? AF_INET6 : AF_INET); const NTSTATUS status = inbound @@ -344,7 +348,7 @@ static PFORT_PACKET fort_shaper_queue_get_packets(PFORT_PACKET_QUEUE queue, PFOR inline static BOOL fort_shaper_queue_is_empty(PFORT_PACKET_QUEUE queue) { return fort_shaper_packet_list_is_empty(&queue->bandwidth_list) - || fort_shaper_packet_list_is_empty(&queue->latency_list); + && fort_shaper_packet_list_is_empty(&queue->latency_list); } static BOOL fort_shaper_queue_process(PFORT_SHAPER shaper, PFORT_PACKET_QUEUE queue) @@ -392,6 +396,8 @@ static void fort_shaper_create_queues( RtlZeroMemory(queue, sizeof(FORT_PACKET_QUEUE)); + KeInitializeSpinLock(&queue->lock); + shaper->queues[i] = queue; } @@ -513,9 +519,13 @@ FORT_API void fort_shaper_open(PFORT_SHAPER shaper) g_RandomSeed = now.LowPart; FwpsInjectionHandleCreate0( - AF_INET, FWPS_INJECTION_TYPE_TRANSPORT, &shaper->injection_transport4_id); + AF_INET, FWPS_INJECTION_TYPE_TRANSPORT, &shaper->injection_in_transport4_id); FwpsInjectionHandleCreate0( - AF_INET6, FWPS_INJECTION_TYPE_TRANSPORT, &shaper->injection_transport6_id); + AF_INET6, FWPS_INJECTION_TYPE_TRANSPORT, &shaper->injection_in_transport6_id); + FwpsInjectionHandleCreate0( + AF_INET, FWPS_INJECTION_TYPE_TRANSPORT, &shaper->injection_out_transport4_id); + FwpsInjectionHandleCreate0( + AF_INET6, FWPS_INJECTION_TYPE_TRANSPORT, &shaper->injection_out_transport6_id); fort_timer_open( &shaper->timer, /*period(ms)=*/1, FORT_TIMER_ONESHOT, &fort_shaper_timer_process); @@ -530,8 +540,10 @@ FORT_API void fort_shaper_close(PFORT_SHAPER shaper) fort_shaper_drop_packets(shaper); fort_shaper_free_queues(shaper); - FwpsInjectionHandleDestroy0(shaper->injection_transport4_id); - FwpsInjectionHandleDestroy0(shaper->injection_transport6_id); + FwpsInjectionHandleDestroy0(shaper->injection_in_transport4_id); + FwpsInjectionHandleDestroy0(shaper->injection_in_transport6_id); + FwpsInjectionHandleDestroy0(shaper->injection_out_transport4_id); + FwpsInjectionHandleDestroy0(shaper->injection_out_transport6_id); } FORT_API void fort_shaper_conf_update(PFORT_SHAPER shaper, const PFORT_CONF_IO conf_io) @@ -582,8 +594,7 @@ void fort_shaper_conf_flags_update(PFORT_SHAPER shaper, const PFORT_CONF_FLAGS c fort_shaper_flush(shaper, flush_io_bits, /*drop=*/FALSE); } -static void fort_shaper_packet_queue_add( - PFORT_SHAPER shaper, PFORT_PACKET_QUEUE queue, PFORT_PACKET pkt) +static void fort_shaper_packet_queue_add_packet(PFORT_PACKET_QUEUE queue, PFORT_PACKET pkt) { KLOCK_QUEUE_HANDLE lock_queue; KeAcquireInStackQueuedSpinLock(&queue->lock, &lock_queue); @@ -595,6 +606,40 @@ static void fort_shaper_packet_queue_add( KeReleaseInStackQueuedSpinLock(&lock_queue); } +inline static BOOL fort_shaper_packet_queue_check_plr(PFORT_PACKET_QUEUE queue) +{ + const UINT16 plr = queue->limit.plr; + if (plr > 0) { + const ULONG random = RtlRandomEx(&g_RandomSeed) % 10000; /* PLR range is 0-10000 */ + if (random < plr) + return FALSE; + } + return TRUE; +} + +inline static BOOL fort_shaper_packet_queue_check_buffer( + PFORT_PACKET_QUEUE queue, ULONG data_length) +{ + const UINT64 buffer_bytes = queue->limit.buffer_bytes; + + return buffer_bytes == 0 || buffer_bytes >= (queue->queued_bytes + data_length); +} + +static BOOL fort_shaper_packet_queue_check_packet(PFORT_PACKET_QUEUE queue, ULONG data_length) +{ + BOOL res; + + KLOCK_QUEUE_HANDLE lock_queue; + KeAcquireInStackQueuedSpinLock(&queue->lock, &lock_queue); + { + res = fort_shaper_packet_queue_check_plr(queue) + && fort_shaper_packet_queue_check_buffer(queue, data_length); + } + KeReleaseInStackQueuedSpinLock(&lock_queue); + + return res; +} + static NTSTATUS fort_shaper_packet_queue(PFORT_SHAPER shaper, const FWPS_INCOMING_VALUES0 *inFixedValues, const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues, PNET_BUFFER_LIST netBufList, @@ -614,20 +659,11 @@ static NTSTATUS fort_shaper_packet_queue(PFORT_SHAPER shaper, if (queue == NULL) return STATUS_NO_SUCH_GROUP; - /* Check the Queue's PLR */ - const UINT16 plr = queue->limit.plr; - if (plr > 0) { - const ULONG random = RtlRandomEx(&g_RandomSeed) % 10000; /* PLR range is 0-10000 */ - if (random < plr) - return STATUS_SUCCESS; /* drop the packet */ - } - /* Calculate the Packets' Data Length */ const ULONG data_length = fort_packet_data_length(netBufList); - /* Check the Queue's Buffer Capacity */ - const UINT64 buffer_bytes = queue->limit.buffer_bytes; - if (buffer_bytes > 0 && queue->queued_bytes + data_length > buffer_bytes) + /* Check the Queue for new Packet */ + if (!fort_shaper_packet_queue_check_packet(queue, data_length)) return STATUS_SUCCESS; /* drop the packet */ /* Clone the Packet */ @@ -639,7 +675,11 @@ static NTSTATUS fort_shaper_packet_queue(PFORT_SHAPER shaper, status = fort_shaper_packet_clone( shaper, inFixedValues, inMetaValues, netBufList, pkt, isIPv6, inbound); + if (!NT_SUCCESS(status)) { + LOG("Shaper: Packet clone error: %x\n", status); + TRACE(FORT_SHAPER_PACKET_CLONE_ERROR, status, 0, 0); + fort_shaper_packet_free(/*shaper=*/NULL, pkt); return status; } @@ -648,7 +688,7 @@ static NTSTATUS fort_shaper_packet_queue(PFORT_SHAPER shaper, pkt->flags = (inbound ? FORT_PACKET_INBOUND : 0) | (isIPv6 ? FORT_PACKET_IP6 : 0); /* Add the Cloned Packet to Queue */ - fort_shaper_packet_queue_add(shaper, queue, pkt); + fort_shaper_packet_queue_add_packet(queue, pkt); /* Process the Packet Queue */ if (fort_shaper_queue_process(shaper, queue)) { @@ -663,13 +703,11 @@ static NTSTATUS fort_shaper_packet_queue(PFORT_SHAPER shaper, FORT_API BOOL fort_shaper_packet_process(PFORT_SHAPER shaper, const FWPS_INCOMING_VALUES0 *inFixedValues, const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues, PNET_BUFFER_LIST netBufList, - UINT64 flowContext) + UINT64 flowContext, BOOL inbound) { PFORT_FLOW flow = (PFORT_FLOW) flowContext; const UCHAR flow_flags = fort_flow_flags(flow); - - const BOOL inbound = (flow_flags & FORT_FLOW_INBOUND) != 0; const UCHAR speed_limit = inbound ? FORT_FLOW_SPEED_LIMIT_IN : FORT_FLOW_SPEED_LIMIT_OUT; if ((flow_flags & speed_limit) == 0 @@ -677,7 +715,7 @@ FORT_API BOOL fort_shaper_packet_process(PFORT_SHAPER shaper, return FALSE; const BOOL isIPv6 = (flow_flags & FORT_FLOW_IP6) != 0; - const HANDLE injection_id = fort_shaper_injection_id(shaper, isIPv6); + const HANDLE injection_id = fort_shaper_injection_id(shaper, isIPv6, inbound); /* Skip self injected packet */ if (fort_packet_injected_by_self(injection_id, netBufList)) diff --git a/src/driver/fortpkt.h b/src/driver/fortpkt.h index 665c7bb0..dfd35926 100644 --- a/src/driver/fortpkt.h +++ b/src/driver/fortpkt.h @@ -77,8 +77,10 @@ typedef struct fort_shaper LONG volatile group_io_bits; LONG volatile active_io_bits; - HANDLE injection_transport4_id; - HANDLE injection_transport6_id; + HANDLE injection_in_transport4_id; + HANDLE injection_in_transport6_id; + HANDLE injection_out_transport4_id; + HANDLE injection_out_transport6_id; FORT_TIMER timer; @@ -102,7 +104,7 @@ FORT_API void fort_shaper_conf_flags_update(PFORT_SHAPER shaper, const PFORT_CON FORT_API BOOL fort_shaper_packet_process(PFORT_SHAPER shaper, const FWPS_INCOMING_VALUES0 *inFixedValues, const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues, PNET_BUFFER_LIST netBufList, - UINT64 flowContext); + UINT64 flowContext, BOOL inbound); FORT_API void fort_shaper_drop_packets(PFORT_SHAPER shaper); diff --git a/src/driver/fortstat.c b/src/driver/fortstat.c index 57a25db3..09312cb9 100644 --- a/src/driver/fortstat.c +++ b/src/driver/fortstat.c @@ -10,9 +10,6 @@ #define fort_stat_proc_hash(process_id) tommy_inthash_u32((UINT32) (process_id)) #define fort_flow_hash(flow_id) tommy_inthash_u32((UINT32) (flow_id)) -#define fort_stat_group_speed_limit(stat, group_index) \ - ((((stat)->conf_group.group_bits & (stat)->conf_group.limit_bits) >> (group_index)) & 1) - static void fort_stat_proc_active_add(PFORT_STAT stat, PFORT_STAT_PROC proc) { if (proc->active) @@ -146,29 +143,7 @@ static void fort_flow_context_stream_init( } } -static void fort_flow_context_transport_init( - PFORT_STAT stat, BOOL isIPv6, BOOL inbound, UINT16 *layerId, UINT32 *calloutId) -{ - if (inbound) { - if (isIPv6) { - *layerId = FWPS_LAYER_INBOUND_TRANSPORT_V6; - *calloutId = stat->in_transport6_id; - } else { - *layerId = FWPS_LAYER_INBOUND_TRANSPORT_V4; - *calloutId = stat->in_transport4_id; - } - } else { - if (isIPv6) { - *layerId = FWPS_LAYER_OUTBOUND_TRANSPORT_V6; - *calloutId = stat->out_transport6_id; - } else { - *layerId = FWPS_LAYER_OUTBOUND_TRANSPORT_V4; - *calloutId = stat->out_transport4_id; - } - } -} - -inline static NTSTATUS fort_flow_context_stream_set( +inline static void fort_flow_context_stream_set( PFORT_STAT stat, UINT64 flow_id, UINT64 flowContext, BOOL isIPv6, BOOL is_tcp) { UINT16 layerId; @@ -176,18 +151,23 @@ inline static NTSTATUS fort_flow_context_stream_set( fort_flow_context_stream_init(stat, isIPv6, is_tcp, &layerId, &calloutId); - return FwpsFlowAssociateContext0(flow_id, layerId, calloutId, flowContext); + FwpsFlowAssociateContext0(flow_id, layerId, calloutId, flowContext); } -inline static NTSTATUS fort_flow_context_transport_set( +inline static void fort_flow_context_transport_set( PFORT_STAT stat, UINT64 flow_id, UINT64 flowContext, BOOL isIPv6, BOOL inbound) { - UINT16 layerId; - UINT32 calloutId; - - fort_flow_context_transport_init(stat, isIPv6, inbound, &layerId, &calloutId); - - return FwpsFlowAssociateContext0(flow_id, layerId, calloutId, flowContext); + if (isIPv6) { + FwpsFlowAssociateContext0( + flow_id, FWPS_LAYER_INBOUND_TRANSPORT_V6, stat->in_transport6_id, flowContext); + FwpsFlowAssociateContext0( + flow_id, FWPS_LAYER_OUTBOUND_TRANSPORT_V6, stat->out_transport6_id, flowContext); + } else { + FwpsFlowAssociateContext0( + flow_id, FWPS_LAYER_INBOUND_TRANSPORT_V4, stat->in_transport4_id, flowContext); + FwpsFlowAssociateContext0( + flow_id, FWPS_LAYER_OUTBOUND_TRANSPORT_V4, stat->out_transport4_id, flowContext); + } } static void fort_flow_context_set( @@ -200,7 +180,7 @@ static void fort_flow_context_set( fort_flow_context_transport_set(stat, flow_id, flowContext, isIPv6, inbound); } -inline static NTSTATUS fort_flow_context_stream_remove( +inline static BOOL fort_flow_context_stream_remove( PFORT_STAT stat, UINT64 flow_id, BOOL isIPv6, BOOL is_tcp) { UINT16 layerId; @@ -208,29 +188,37 @@ inline static NTSTATUS fort_flow_context_stream_remove( fort_flow_context_stream_init(stat, isIPv6, is_tcp, &layerId, &calloutId); - return FwpsFlowRemoveContext0(flow_id, layerId, calloutId); + return FwpsFlowRemoveContext0(flow_id, layerId, calloutId) != STATUS_PENDING; } inline static NTSTATUS fort_flow_context_transport_remove( - PFORT_STAT stat, UINT64 flow_id, BOOL isIPv6, BOOL inbound) + PFORT_STAT stat, UINT64 flow_id, BOOL isIPv6) { - UINT16 layerId; - UINT32 calloutId; + NTSTATUS in_status; + NTSTATUS out_status; - fort_flow_context_transport_init(stat, isIPv6, inbound, &layerId, &calloutId); + if (isIPv6) { + in_status = FwpsFlowRemoveContext0( + flow_id, FWPS_LAYER_INBOUND_TRANSPORT_V6, stat->in_transport6_id); + out_status = FwpsFlowRemoveContext0( + flow_id, FWPS_LAYER_OUTBOUND_TRANSPORT_V6, stat->out_transport6_id); + } else { + in_status = FwpsFlowRemoveContext0( + flow_id, FWPS_LAYER_INBOUND_TRANSPORT_V4, stat->in_transport4_id); + out_status = FwpsFlowRemoveContext0( + flow_id, FWPS_LAYER_OUTBOUND_TRANSPORT_V4, stat->out_transport4_id); + } - return FwpsFlowRemoveContext0(flow_id, layerId, calloutId); + return in_status != STATUS_PENDING && out_status != STATUS_PENDING; } -static BOOL fort_flow_context_remove_id( - PFORT_STAT stat, UINT64 flow_id, BOOL isIPv6, BOOL is_tcp, BOOL inbound) +static BOOL fort_flow_context_remove_id(PFORT_STAT stat, UINT64 flow_id, BOOL isIPv6, BOOL is_tcp) { - const NTSTATUS stream_status = fort_flow_context_stream_remove(stat, flow_id, isIPv6, is_tcp); + const BOOL stream_res = fort_flow_context_stream_remove(stat, flow_id, isIPv6, is_tcp); - const NTSTATUS transport_status = - fort_flow_context_transport_remove(stat, flow_id, isIPv6, inbound); + const BOOL transport_res = fort_flow_context_transport_remove(stat, flow_id, isIPv6); - return stream_status != STATUS_PENDING && transport_status != STATUS_PENDING; + return stream_res && transport_res; } static void fort_flow_context_remove(PFORT_STAT stat, PFORT_FLOW flow) @@ -238,11 +226,10 @@ static void fort_flow_context_remove(PFORT_STAT stat, PFORT_FLOW flow) const UINT64 flow_id = flow->flow_id; const UCHAR flow_flags = fort_flow_flags(flow); - const BOOL inbound = (flow_flags & FORT_FLOW_INBOUND); const BOOL is_tcp = (flow_flags & FORT_FLOW_TCP); const BOOL isIPv6 = (flow_flags & FORT_FLOW_IP6); - if (!fort_flow_context_remove_id(stat, flow_id, isIPv6, is_tcp, inbound)) { + if (!fort_flow_context_remove_id(stat, flow_id, isIPv6, is_tcp)) { fort_stat_flags_set(stat, FORT_STAT_FLOW_PENDING, TRUE); } } @@ -310,8 +297,16 @@ static PFORT_FLOW fort_flow_new(PFORT_STAT stat, UINT64 flow_id, const tommy_key return flow; } +inline static UCHAR fort_stat_group_speed_limit(PFORT_CONF_GROUP conf_group, UCHAR group_index) +{ + if (((conf_group->group_bits & conf_group->limit_bits) & (1 << group_index)) == 0) + return 0; + + return (((conf_group->limit_io_bits) >> (group_index * 2)) & 3); +} + static NTSTATUS fort_flow_add(PFORT_STAT stat, UINT64 flow_id, UCHAR group_index, UINT16 proc_index, - UCHAR speed_limit, BOOL isIPv6, BOOL is_tcp, BOOL inbound, BOOL is_reauth) + BOOL isIPv6, BOOL is_tcp, BOOL inbound, BOOL is_reauth) { const tommy_key_t flow_hash = fort_flow_hash(flow_id); PFORT_FLOW flow = fort_flow_get(stat, flow_id, flow_hash); @@ -320,7 +315,7 @@ static NTSTATUS fort_flow_add(PFORT_STAT stat, UINT64 flow_id, UCHAR group_index if (flow == NULL) { if (is_reauth) { /* Remove existing flow context after reauth. to be able to associate a flow-context */ - if (!fort_flow_context_remove_id(stat, flow_id, isIPv6, is_tcp, inbound)) + if (!fort_flow_context_remove_id(stat, flow_id, isIPv6, is_tcp)) return FORT_STATUS_FLOW_BLOCK; } @@ -337,6 +332,8 @@ static NTSTATUS fort_flow_add(PFORT_STAT stat, UINT64 flow_id, UCHAR group_index fort_stat_proc_inc(stat, proc_index); } + const UCHAR speed_limit = fort_stat_group_speed_limit(&stat->conf_group, group_index); + flow->opt.flags = speed_limit | (is_tcp ? FORT_FLOW_TCP : 0) | (isIPv6 ? FORT_FLOW_IP6 : 0) | (inbound ? FORT_FLOW_INBOUND : 0); flow->opt.group_index = group_index; @@ -476,10 +473,8 @@ FORT_API NTSTATUS fort_flow_associate(PFORT_STAT stat, UINT64 flow_id, UINT32 pr /* Add flow */ if (NT_SUCCESS(status)) { - const UCHAR speed_limit = fort_stat_group_speed_limit(stat, group_index); - - status = fort_flow_add(stat, flow_id, group_index, proc->proc_index, speed_limit, isIPv6, - is_tcp, inbound, is_reauth); + status = fort_flow_add( + stat, flow_id, group_index, proc->proc_index, isIPv6, is_tcp, inbound, is_reauth); if (!NT_SUCCESS(status) && *is_new_proc) { fort_stat_proc_free(stat, proc); diff --git a/src/ui/util/conf/confutil.cpp b/src/ui/util/conf/confutil.cpp index 9523c2fb..94f83f67 100644 --- a/src/ui/util/conf/confutil.cpp +++ b/src/ui/util/conf/confutil.cpp @@ -557,7 +557,7 @@ void ConfUtil::writeLimits(struct fort_speed_limit *limits, quint16 *limitBits, *limitIoBits = 0; const int groupsCount = appGroups.size(); - for (int i = 0; i < groupsCount; ++i, ++limits) { + for (int i = 0; i < groupsCount; ++i, limits += 2) { const AppGroup *appGroup = appGroups.at(i); const quint32 limitIn = appGroup->enabledSpeedLimitIn();