From dd40a4ea798c10cc098fa4197e26008cd4a42981 Mon Sep 17 00:00:00 2001 From: Nodir Temirkhodjaev Date: Tue, 2 Jan 2018 15:34:21 +0500 Subject: [PATCH] Driver: Prepare stream transport layers to classify. --- src/common/common.h | 16 +++++ src/common/fortconf.h | 4 +- src/common/fortprov.c | 58 +++++++++++++-- src/driver/fortdrv.c | 89 ++++++++++++++++++++++- src/driver/fortstat.c | 102 ++++++++++++++++++++------- src/ui/qml/pages/apps/AppsColumn.qml | 4 +- src/ui/util/confutil.cpp | 16 +++-- src/ui/util/confutil.h | 4 +- 8 files changed, 252 insertions(+), 41 deletions(-) diff --git a/src/common/common.h b/src/common/common.h index c977107a..c95e0290 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -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); diff --git a/src/common/fortconf.h b/src/common/fortconf.h index 523ed632..25aa4625 100644 --- a/src/common/fortconf.h +++ b/src/common/fortconf.h @@ -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; diff --git a/src/common/fortprov.c b/src/common/fortprov.c index fb655310..c3b43fd9 100644 --- a/src/common/fortprov.c +++ b/src/common/fortprov.c @@ -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); } diff --git a/src/driver/fortdrv.c b/src/driver/fortdrv.c index 90fb6599..20e67feb 100644 --- a/src/driver/fortdrv.c +++ b/src/driver/fortdrv.c @@ -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 diff --git a/src/driver/fortstat.c b/src/driver/fortstat.c index bf60131f..69e0b1e5 100644 --- a/src/driver/fortstat.c +++ b/src/driver/fortstat.c @@ -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); } diff --git a/src/ui/qml/pages/apps/AppsColumn.qml b/src/ui/qml/pages/apps/AppsColumn.qml index 2cc9d01a..5cfc37ec 100644 --- a/src/ui/qml/pages/apps/AppsColumn.qml +++ b/src/ui/qml/pages/apps/AppsColumn.qml @@ -33,7 +33,9 @@ ColumnLayout { Layout.preferredWidth: 10 } - SpeedLimitButton {} + SpeedLimitButton { + visible: firewallConf.logStat + } Item { Layout.fillWidth: true diff --git a/src/ui/util/confutil.cpp b/src/ui/util/confutil.cpp index 18d6daf4..7af1a6ed 100644 --- a/src/ui/util/confutil.cpp +++ b/src/ui/util/confutil.cpp @@ -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 &appGroups) +bool ConfUtil::writeLimits(struct fort_conf_limit *limits, + const QList &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 &array) diff --git a/src/ui/util/confutil.h b/src/ui/util/confutil.h index 0de7717d..ce7dfb3a 100644 --- a/src/ui/util/confutil.h +++ b/src/ui/util/confutil.h @@ -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 &appGroups); + static bool writeLimits(struct fort_conf_limit *limits, + const QList &appGroups); static void writeNumbers(char **data, const QVector &array); static void writeChars(char **data, const QVector &array);