Driver: Prepare stream transport layers to classify.

This commit is contained in:
Nodir Temirkhodjaev 2018-01-02 15:34:21 +05:00
parent 678c229fcb
commit dd40a4ea79
8 changed files with 252 additions and 41 deletions

View File

@ -28,6 +28,14 @@ DEFINE_GUID(FORT_GUID_CALLOUT_STREAM_V4,
DEFINE_GUID(FORT_GUID_CALLOUT_DATAGRAM_V4,
0x5f1a7b3c, 0x3e88, 0x41c9, 0xa4, 0x42, 0x61, 0xcf, 0xe6, 0xa4, 0x88, 0x6);
/* {DED18B1B-0022-415F-AFDC-C9D59CE6D475} */
DEFINE_GUID(FORT_GUID_CALLOUT_IN_TRANSPORT_V4,
0xded18b1b, 0x22, 0x415f, 0xaf, 0xdc, 0xc9, 0xd5, 0x9c, 0xe6, 0xd4, 0x75);
/* {0004F6D3-8430-4B35-9BF7-23C25C25003E} */
DEFINE_GUID(FORT_GUID_CALLOUT_OUT_TRANSPORT_V4,
0x4f6d3, 0x8430, 0x4b35, 0x9b, 0xf7, 0x23, 0xc2, 0x5c, 0x25, 0x0, 0x3e);
/* {AFA06CD5-4942-4FDF-8A4A-2EDEB25BBECE} */
DEFINE_GUID(FORT_GUID_SUBLAYER,
0xafa06cd5, 0x4942, 0x4fdf, 0x8a, 0x4a, 0x2e, 0xde, 0xb2, 0x5b, 0xbe, 0xce);
@ -48,6 +56,14 @@ DEFINE_GUID(FORT_GUID_FILTER_STREAM_V4,
DEFINE_GUID(FORT_GUID_FILTER_DATAGRAM_V4,
0xa3700639, 0x1b50, 0x461c, 0xbe, 0x4c, 0xbc, 0x35, 0xa, 0x7f, 0xb3, 0xa9);
/* {F515D62B-26A3-413E-874C-D65CE70C9AEF} */
DEFINE_GUID(FORT_GUID_FILTER_IN_TRANSPORT_V4,
0xf515d62b, 0x26a3, 0x413e, 0x87, 0x4c, 0xd6, 0x5c, 0xe7, 0xc, 0x9a, 0xef);
/* {D284AFE8-4CAF-4432-A753-B6F311BDA2BA} */
DEFINE_GUID(FORT_GUID_FILTER_OUT_TRANSPORT_V4,
0xd284afe8, 0x4caf, 0x4432, 0xa7, 0x53, 0xb6, 0xf3, 0x11, 0xbd, 0xa2, 0xba);
/* {749709CE-9686-4056-B89A-7A5852DFC898} */
DEFINE_GUID(FORT_GUID_FILTER_REAUTH_OUT,
0x749709ce, 0x9686, 0x4056, 0xb8, 0x9a, 0x7a, 0x58, 0x52, 0xdf, 0xc8, 0x98);

View File

@ -20,7 +20,8 @@ typedef struct fort_conf_flags {
UINT32 app_allow_all : 1;
UINT32 log_blocked : 1;
UINT32 log_stat : 1;
UINT32 _reserved_ : 7;
UINT32 speed_limit : 1;
UINT32 _reserved_ : 6;
UINT32 group_bits : 16;
} FORT_CONF_FLAGS, *PFORT_CONF_FLAGS;
@ -40,7 +41,6 @@ typedef struct fort_conf {
UINT16 ip_include_n;
UINT16 ip_exclude_n;
UINT16 limit_bits;
UINT16 apps_n;
UINT32 app_perms_block_mask;

View File

@ -28,6 +28,8 @@ fort_prov_unregister (void)
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_ACCEPT_V4);
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_STREAM_V4);
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_DATAGRAM_V4);
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_IN_TRANSPORT_V4);
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_OUT_TRANSPORT_V4);
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_REAUTH_OUT);
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_REAUTH_IN);
FwpmSubLayerDeleteByKey0(engine, (GUID *) &FORT_GUID_SUBLAYER);
@ -35,6 +37,8 @@ fort_prov_unregister (void)
FwpmCalloutDeleteByKey0(engine, (GUID *) &FORT_GUID_CALLOUT_ACCEPT_V4);
FwpmCalloutDeleteByKey0(engine, (GUID *) &FORT_GUID_CALLOUT_STREAM_V4);
FwpmCalloutDeleteByKey0(engine, (GUID *) &FORT_GUID_CALLOUT_DATAGRAM_V4);
FwpmCalloutDeleteByKey0(engine, (GUID *) &FORT_GUID_CALLOUT_IN_TRANSPORT_V4);
FwpmCalloutDeleteByKey0(engine, (GUID *) &FORT_GUID_CALLOUT_OUT_TRANSPORT_V4);
FwpmProviderDeleteByKey0(engine, (GUID *) &FORT_GUID_PROVIDER);
fort_prov_close(engine);
@ -50,6 +54,8 @@ fort_prov_flow_unregister (void)
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_STREAM_V4);
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_DATAGRAM_V4);
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_IN_TRANSPORT_V4);
FwpmFilterDeleteByKey0(engine, (GUID *) &FORT_GUID_FILTER_OUT_TRANSPORT_V4);
fort_prov_close(engine);
}
@ -58,7 +64,9 @@ static DWORD
fort_prov_register (BOOL is_boot)
{
FWPM_PROVIDER0 provider;
FWPM_CALLOUT0 ocallout4, icallout4, scallout4, dcallout4;
FWPM_CALLOUT0 ocallout4, icallout4;
FWPM_CALLOUT0 scallout4, dcallout4;
FWPM_CALLOUT0 itcallout4, otcallout4;
FWPM_SUBLAYER0 sublayer;
FWPM_FILTER0 ofilter4, ifilter4;
HANDLE engine;
@ -105,6 +113,20 @@ fort_prov_register (BOOL is_boot)
dcallout4.providerKey = (GUID *) &FORT_GUID_PROVIDER;
dcallout4.applicableLayer = FWPM_LAYER_DATAGRAM_DATA_V4;
RtlZeroMemory(&itcallout4, sizeof(FWPM_CALLOUT0));
itcallout4.calloutKey = FORT_GUID_CALLOUT_IN_TRANSPORT_V4;
itcallout4.displayData.name = (PWCHAR) L"FortCalloutInTransport4";
itcallout4.displayData.description = (PWCHAR) L"Fort Firewall Callout Inbound Transport V4";
itcallout4.providerKey = (GUID *) &FORT_GUID_PROVIDER;
itcallout4.applicableLayer = FWPM_LAYER_INBOUND_TRANSPORT_V4;
RtlZeroMemory(&otcallout4, sizeof(FWPM_CALLOUT0));
otcallout4.calloutKey = FORT_GUID_CALLOUT_OUT_TRANSPORT_V4;
otcallout4.displayData.name = (PWCHAR) L"FortCalloutOutTransport4";
otcallout4.displayData.description = (PWCHAR) L"Fort Firewall Callout Outbound Transport V4";
otcallout4.providerKey = (GUID *) &FORT_GUID_PROVIDER;
otcallout4.applicableLayer = FWPM_LAYER_OUTBOUND_TRANSPORT_V4;
RtlZeroMemory(&sublayer, sizeof(FWPM_SUBLAYER0));
sublayer.subLayerKey = FORT_GUID_SUBLAYER;
sublayer.displayData.name = (PWCHAR) L"FortSublayer";
@ -137,6 +159,8 @@ fort_prov_register (BOOL is_boot)
|| (status = FwpmCalloutAdd0(engine, &icallout4, NULL, NULL))
|| (status = FwpmCalloutAdd0(engine, &scallout4, NULL, NULL))
|| (status = FwpmCalloutAdd0(engine, &dcallout4, NULL, NULL))
|| (status = FwpmCalloutAdd0(engine, &itcallout4, NULL, NULL))
|| (status = FwpmCalloutAdd0(engine, &otcallout4, NULL, NULL))
|| (status = FwpmSubLayerAdd0(engine, &sublayer, NULL))
|| (status = FwpmFilterAdd0(engine, &ofilter4, NULL, NULL))
|| (status = FwpmFilterAdd0(engine, &ifilter4, NULL, NULL))
@ -154,13 +178,17 @@ static DWORD
fort_prov_flow_register (void)
{
FWPM_FILTER0 sfilter4, dfilter4;
FWPM_FILTER0 itfilter4, otfilter4;
HANDLE engine;
const UINT32 filter_flags = FWP_CALLOUT_FLAG_ALLOW_MID_STREAM_INSPECTION;
UINT32 filter_flags;
DWORD status;
if ((status = fort_prov_open(&engine)))
goto end;
filter_flags = FWPM_FILTER_FLAG_PERMIT_IF_CALLOUT_UNREGISTERED
| FWP_CALLOUT_FLAG_ALLOW_MID_STREAM_INSPECTION;
RtlZeroMemory(&sfilter4, sizeof(FWPM_FILTER0));
sfilter4.flags = filter_flags;
sfilter4.filterKey = FORT_GUID_FILTER_STREAM_V4;
@ -168,7 +196,7 @@ fort_prov_flow_register (void)
sfilter4.subLayerKey = FORT_GUID_SUBLAYER;
sfilter4.displayData.name = (PWCHAR) L"FortFilterStream4";
sfilter4.displayData.description = (PWCHAR) L"Fort Firewall Filter Stream V4";
sfilter4.action.type = FWP_ACTION_CALLOUT_INSPECTION;
sfilter4.action.type = FWP_ACTION_CALLOUT_UNKNOWN;
sfilter4.action.calloutKey = FORT_GUID_CALLOUT_STREAM_V4;
RtlZeroMemory(&dfilter4, sizeof(FWPM_FILTER0));
@ -178,12 +206,34 @@ fort_prov_flow_register (void)
dfilter4.subLayerKey = FORT_GUID_SUBLAYER;
dfilter4.displayData.name = (PWCHAR) L"FortFilterDatagram4";
dfilter4.displayData.description = (PWCHAR) L"Fort Firewall Filter Datagram V4";
dfilter4.action.type = FWP_ACTION_CALLOUT_INSPECTION;
dfilter4.action.type = FWP_ACTION_CALLOUT_UNKNOWN;
dfilter4.action.calloutKey = FORT_GUID_CALLOUT_DATAGRAM_V4;
RtlZeroMemory(&itfilter4, sizeof(FWPM_FILTER0));
itfilter4.flags = filter_flags;
itfilter4.filterKey = FORT_GUID_FILTER_IN_TRANSPORT_V4;
itfilter4.layerKey = FWPM_LAYER_INBOUND_TRANSPORT_V4;
itfilter4.subLayerKey = FORT_GUID_SUBLAYER;
itfilter4.displayData.name = (PWCHAR) L"FortFilterInTransport4";
itfilter4.displayData.description = (PWCHAR) L"Fort Firewall Filter Inbound Transport V4";
itfilter4.action.type = FWP_ACTION_CALLOUT_UNKNOWN;
itfilter4.action.calloutKey = FORT_GUID_CALLOUT_IN_TRANSPORT_V4;
RtlZeroMemory(&otfilter4, sizeof(FWPM_FILTER0));
otfilter4.flags = filter_flags;
otfilter4.filterKey = FORT_GUID_FILTER_OUT_TRANSPORT_V4;
otfilter4.layerKey = FWPM_LAYER_OUTBOUND_TRANSPORT_V4;
otfilter4.subLayerKey = FORT_GUID_SUBLAYER;
otfilter4.displayData.name = (PWCHAR) L"FortFilterOutTransport4";
otfilter4.displayData.description = (PWCHAR) L"Fort Firewall Filter Outbound Transport V4";
otfilter4.action.type = FWP_ACTION_CALLOUT_UNKNOWN;
otfilter4.action.calloutKey = FORT_GUID_CALLOUT_OUT_TRANSPORT_V4;
if ((status = FwpmTransactionBegin0(engine, 0))
|| (status = FwpmFilterAdd0(engine, &sfilter4, NULL, NULL))
|| (status = FwpmFilterAdd0(engine, &dfilter4, NULL, NULL))
|| (status = FwpmFilterAdd0(engine, &itfilter4, NULL, NULL))
|| (status = FwpmFilterAdd0(engine, &otfilter4, NULL, NULL))
|| (status = FwpmTransactionCommit0(engine))) {
FwpmTransactionAbort0(engine);
}

View File

@ -221,12 +221,13 @@ fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
const UCHAR group_index = fort_conf_app_group_index(
&conf_ref->conf, app_index);
const BOOL is_udp = (ip_proto == IPPROTO_UDP);
const BOOL speed_limit = conf_flags.speed_limit;
BOOL is_new = FALSE;
NTSTATUS status;
status = fort_stat_flow_associate(&g_device->stat,
inMetaValues->flowHandle, process_id, group_index,
is_udp, &is_new);
is_udp, speed_limit, &is_new);
if (!NT_SUCCESS(status)) {
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
@ -355,6 +356,54 @@ fort_callout_datagram_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
classifyOut->actionType = FWP_ACTION_CONTINUE;
}
static void
fort_callout_transport_classify_v4 (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,
BOOL inbound)
{
//fort_stat_flow_shape(&g_device->stat, flowContext, inbound);
classifyOut->actionType = FWP_ACTION_CONTINUE;
}
static void
fort_callout_in_transport_classify_v4 (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_v4(inFixedValues, inMetaValues, netBufList,
filter, flowContext, classifyOut, TRUE);
}
static void
fort_callout_out_transport_classify_v4 (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_v4(inFixedValues, inMetaValues, netBufList,
filter, flowContext, classifyOut, FALSE);
}
static void
fort_callout_transport_delete_v4 (UINT16 layerId,
UINT32 calloutId,
UINT64 flowContext)
{
UNUSED(layerId);
UNUSED(calloutId);
UNUSED(flowContext);
}
static NTSTATUS
fort_callout_install (PDEVICE_OBJECT device)
{
@ -415,6 +464,34 @@ fort_callout_install (PDEVICE_OBJECT device)
return status;
}
/* IPv4 inbound transport callout */
c.calloutKey = FORT_GUID_CALLOUT_IN_TRANSPORT_V4;
c.classifyFn = fort_callout_in_transport_classify_v4;
c.flowDeleteFn = fort_callout_transport_delete_v4;
c.flags = FWP_CALLOUT_FLAG_CONDITIONAL_ON_FLOW;
status = FwpsCalloutRegister0(device, &c, &g_device->stat.in_transport4_id);
if (!NT_SUCCESS(status)) {
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
"FORT: Register Inbound Transport V4: Error: %d\n", status);
return status;
}
/* IPv4 outbound transport callout */
c.calloutKey = FORT_GUID_CALLOUT_OUT_TRANSPORT_V4;
c.classifyFn = fort_callout_out_transport_classify_v4;
c.flowDeleteFn = fort_callout_transport_delete_v4;
c.flags = FWP_CALLOUT_FLAG_CONDITIONAL_ON_FLOW;
status = FwpsCalloutRegister0(device, &c, &g_device->stat.out_transport4_id);
if (!NT_SUCCESS(status)) {
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
"FORT: Register Outbound Transport V4: Error: %d\n", status);
return status;
}
return STATUS_SUCCESS;
}
@ -440,6 +517,16 @@ fort_callout_remove (void)
FwpsCalloutUnregisterById0(g_device->stat.datagram4_id);
g_device->stat.datagram4_id = 0;
}
if (g_device->stat.in_transport4_id) {
FwpsCalloutUnregisterById0(g_device->stat.in_transport4_id);
g_device->stat.in_transport4_id = 0;
}
if (g_device->stat.out_transport4_id) {
FwpsCalloutUnregisterById0(g_device->stat.out_transport4_id);
g_device->stat.out_transport4_id = 0;
}
}
static NTSTATUS

View File

@ -4,12 +4,22 @@
#define FORT_PROC_BAD_INDEX ((UINT16) -1)
#define FORT_FLOW_BAD_INDEX ((UINT32) -1)
#define FORT_FLOW_BAD_ID ((UINT64) -1LL)
typedef struct fort_stat_traf {
UINT32 in_bytes;
UINT32 out_bytes;
} FORT_STAT_TRAF, *PFORT_STAT_TRAF;
typedef struct fort_stat_group {
FORT_CONF_LIMIT limit;
union {
LARGE_INTEGER traf_all;
FORT_STAT_TRAF traf;
};
} FORT_STAT_GROUP, *PFORT_STAT_GROUP;
typedef struct fort_stat_proc {
UINT16 next_index;
UINT16 refcount;
@ -23,14 +33,12 @@ typedef struct fort_stat_proc {
} FORT_STAT_PROC, *PFORT_STAT_PROC;
typedef struct fort_stat_flow {
union {
struct {
UINT32 next_index;
UINT32 is_free;
};
UINT32 is_udp : 1;
UINT32 speed_limit : 1;
UINT64 flow_id;
};
UINT32 next_free_index;
UINT64 flow_id;
} FORT_STAT_FLOW, *PFORT_STAT_FLOW;
typedef struct fort_stat {
@ -54,6 +62,10 @@ typedef struct fort_stat {
UINT32 stream4_id;
UINT32 datagram4_id;
UINT32 in_transport4_id;
UINT32 out_transport4_id;
FORT_STAT_GROUP groups[FORT_CONF_GROUP_MAX];
PFORT_STAT_PROC procs;
PFORT_STAT_FLOW flows;
@ -222,9 +234,9 @@ fort_stat_flow_free (PFORT_STAT stat, UINT32 flow_index)
PFORT_STAT_FLOW flow = &stat->flows[flow_index];
/* Add to free chain */
flow->is_free = FORT_FLOW_BAD_INDEX;
flow->flow_id = FORT_FLOW_BAD_ID;
flow->next_index = stat->flow_free_index;
flow->next_free_index = stat->flow_free_index;
stat->flow_free_index = flow_index;
}
@ -256,7 +268,8 @@ fort_stat_flow_realloc (PFORT_STAT stat)
}
static UINT32
fort_stat_flow_add (PFORT_STAT stat, UINT64 flow_id)
fort_stat_flow_add (PFORT_STAT stat, UINT64 flow_id,
BOOL is_udp, BOOL speed_limit)
{
PFORT_STAT_FLOW flow;
UINT32 flow_index = stat->flow_free_index;
@ -264,7 +277,7 @@ fort_stat_flow_add (PFORT_STAT stat, UINT64 flow_id)
if (flow_index != FORT_FLOW_BAD_INDEX) {
flow = &stat->flows[flow_index];
stat->flow_free_index = flow->next_index;
stat->flow_free_index = flow->next_free_index;
} else {
if (stat->flow_top >= stat->flow_end
&& !fort_stat_flow_realloc(stat)) {
@ -275,6 +288,9 @@ fort_stat_flow_add (PFORT_STAT stat, UINT64 flow_id)
flow = &stat->flows[flow_index];
}
flow->is_udp = is_udp;
flow->speed_limit = speed_limit;
flow->flow_id = flow_id;
stat->flow_count++;
@ -283,13 +299,9 @@ fort_stat_flow_add (PFORT_STAT stat, UINT64 flow_id)
}
static NTSTATUS
fort_stat_flow_set_context (PFORT_STAT stat, UINT64 flow_id,
UINT64 flow_context, BOOL is_udp)
fort_stat_flow_set_context (UINT64 flow_id, UINT16 layer_id,
UINT32 callout_id, UINT64 flow_context)
{
const UINT16 layer_id = is_udp ? FWPS_LAYER_DATAGRAM_DATA_V4
: FWPS_LAYER_STREAM_V4;
const UINT32 callout_id = is_udp ? stat->datagram4_id : stat->stream4_id;
return FwpsFlowAssociateContext0(flow_id, layer_id,
callout_id, flow_context);
}
@ -301,6 +313,25 @@ fort_stat_flow_remove_context (UINT64 flow_id, UINT16 layer_id,
return FwpsFlowRemoveContext0(flow_id, layer_id, callout_id);
}
static void
fort_stat_flow_transport_remove_contexts (PFORT_STAT stat, PFORT_STAT_FLOW flow)
{
fort_stat_flow_remove_context(flow->flow_id,
FWPS_LAYER_INBOUND_TRANSPORT_V4, stat->in_transport4_id);
fort_stat_flow_remove_context(flow->flow_id,
FWPS_LAYER_OUTBOUND_TRANSPORT_V4, stat->out_transport4_id);
}
static void
fort_stat_flow_transport_check_remove_contexts (PFORT_STAT stat, UINT32 flow_index)
{
PFORT_STAT_FLOW flow = &stat->flows[flow_index];
if (!flow->is_udp && flow->speed_limit) {
fort_stat_flow_transport_remove_contexts(stat, flow);
}
}
static void
fort_stat_flow_remove_contexts (PFORT_STAT stat)
{
@ -308,14 +339,19 @@ fort_stat_flow_remove_contexts (PFORT_STAT stat)
UINT32 count = stat->flow_count;
for (; count != 0; ++flow) {
if (flow->is_free == FORT_FLOW_BAD_INDEX)
if (flow->flow_id == FORT_FLOW_BAD_ID)
continue;
if (!NT_SUCCESS(fort_stat_flow_remove_context(
flow->flow_id, FWPS_LAYER_STREAM_V4, stat->stream4_id))) {
// Remove stream/dgram layer context
if (flow->is_udp) {
fort_stat_flow_remove_context(flow->flow_id,
FWPS_LAYER_DATAGRAM_DATA_V4, stat->datagram4_id);
} else {
fort_stat_flow_remove_context(flow->flow_id,
FWPS_LAYER_STREAM_V4, stat->stream4_id);
// Remove stream transport layer contexts
fort_stat_flow_transport_remove_contexts(stat, flow);
}
--count;
@ -382,7 +418,7 @@ fort_stat_close (PFORT_STAT stat)
static NTSTATUS
fort_stat_flow_associate (PFORT_STAT stat, UINT64 flow_id,
UINT32 process_id, UCHAR group_index,
BOOL is_udp, BOOL *is_new)
BOOL is_udp, BOOL speed_limit, BOOL *is_new)
{
KLOCK_QUEUE_HANDLE lock_queue;
UINT64 flow_context;
@ -408,7 +444,7 @@ fort_stat_flow_associate (PFORT_STAT stat, UINT64 flow_id,
*is_new = TRUE;
}
flow_index = fort_stat_flow_add(stat, flow_id);
flow_index = fort_stat_flow_add(stat, flow_id, is_udp, speed_limit);
if (flow_index == FORT_FLOW_BAD_INDEX) {
status = STATUS_INSUFFICIENT_RESOURCES;
@ -420,9 +456,26 @@ fort_stat_flow_associate (PFORT_STAT stat, UINT64 flow_id,
| ((UINT64) group_index << 40)
| ((UINT64) proc_index << 48);
status = fort_stat_flow_set_context(stat, flow_id, flow_context, is_udp);
// Set stream/dgram layer context
{
const UINT16 layer_id = is_udp ? FWPS_LAYER_DATAGRAM_DATA_V4
: FWPS_LAYER_STREAM_V4;
const UINT32 callout_id = is_udp ? stat->datagram4_id
: stat->stream4_id;
status = fort_stat_flow_set_context(
flow_id, layer_id, callout_id, flow_context);
}
if (NT_SUCCESS(status)) {
// Set transport layer contexts
if (!is_udp && speed_limit) {
fort_stat_flow_set_context(flow_id, FWPS_LAYER_INBOUND_TRANSPORT_V4,
stat->in_transport4_id, flow_context);
fort_stat_flow_set_context(flow_id, FWPS_LAYER_OUTBOUND_TRANSPORT_V4,
stat->out_transport4_id, flow_context);
}
fort_stat_proc_inc(stat, proc_index);
} else {
fort_stat_flow_free(stat, flow_index);
@ -456,6 +509,7 @@ fort_stat_flow_delete (PFORT_STAT stat, UINT64 flow_context)
KeAcquireInStackQueuedSpinLock(&stat->lock, &lock_queue);
if (stat_version == stat->version) {
fort_stat_flow_transport_check_remove_contexts(stat, flow_index);
fort_stat_flow_free(stat, flow_index);
fort_stat_proc_dec(stat, proc_index);
}

View File

@ -33,7 +33,9 @@ ColumnLayout {
Layout.preferredWidth: 10
}
SpeedLimitButton {}
SpeedLimitButton {
visible: firewallConf.logStat
}
Item {
Layout.fillWidth: true

View File

@ -262,6 +262,9 @@ void ConfUtil::writeData(char *output, const FirewallConf &conf,
drvConf->flags.log_blocked = conf.logBlocked();
drvConf->flags.log_stat = conf.logStat();
drvConf->flags.speed_limit = writeLimits(
drvConf->limits, conf.appGroupsList());
drvConf->flags.group_bits = conf.appGroupBits();
FortCommon::confAppPermsMaskInit(drvConf);
@ -273,8 +276,6 @@ void ConfUtil::writeData(char *output, const FirewallConf &conf,
drvConf->ip_include_n = incRangeSize;
drvConf->ip_exclude_n = excRangeSize;
drvConf->limit_bits = writeLimits(drvConf->limits, conf.appGroupsList());
drvConf->apps_n = appPathsSize;
drvConf->ip_from_include_off = incRangeFromOff;
@ -288,11 +289,11 @@ void ConfUtil::writeData(char *output, const FirewallConf &conf,
drvConf->apps_off = appPathsOff;
}
quint16 ConfUtil::writeLimits(struct fort_conf_limit *limits,
const QList<AppGroup *> &appGroups)
bool ConfUtil::writeLimits(struct fort_conf_limit *limits,
const QList<AppGroup *> &appGroups)
{
PFORT_CONF_LIMIT limit = &limits[0];
quint16 limit_bits = 0;
bool speedLimit = false;
const int groupsCount = appGroups.size();
for (int i = 0; i < groupsCount; ++i, ++limit) {
@ -303,12 +304,13 @@ quint16 ConfUtil::writeLimits(struct fort_conf_limit *limits,
limit->out_bytes = appGroup->enabled() && appGroup->limitOutEnabled()
? appGroup->speedLimitOut() * 1024 / 2 : 0;
const quint16 bit = quint16(1 << i);
if (limit->in_bytes || limit->out_bytes) {
limit_bits |= (1 << i);
speedLimit = true;
}
}
return limit_bits;
return speedLimit;
}
void ConfUtil::writeNumbers(char **data, const QVector<quint32> &array)

View File

@ -57,8 +57,8 @@ private:
const appperms_arr_t &appPerms,
const appgroups_arr_t &appGroupIndexes);
static quint16 writeLimits(struct fort_conf_limit *limits,
const QList<AppGroup *> &appGroups);
static bool writeLimits(struct fort_conf_limit *limits,
const QList<AppGroup *> &appGroups);
static void writeNumbers(char **data, const QVector<quint32> &array);
static void writeChars(char **data, const QVector<qint8> &array);