mirror of
https://github.com/tnodir/fort
synced 2024-11-15 07:25:18 +00:00
Driver: Shaper: Fix packets handling
This commit is contained in:
parent
2db2e37394
commit
1e2a9437dc
Binary file not shown.
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user