Driver: Shaper: Fix packets handling

This commit is contained in:
Nodir Temirkhodjaev 2023-01-08 15:24:56 +03:00
parent 2db2e37394
commit 1e2a9437dc
8 changed files with 161 additions and 95 deletions

Binary file not shown.

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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))

View File

@ -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);

View File

@ -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);

View File

@ -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();