Driver: Update group speed limit flags

This commit is contained in:
Nodir Temirkhodjaev 2022-09-18 10:36:08 +03:00
parent e8de7646d4
commit f39a6680b1
8 changed files with 49 additions and 31 deletions

View File

@ -160,6 +160,8 @@ typedef struct fort_app_entry
typedef struct fort_conf_group typedef struct fort_conf_group
{ {
UINT16 group_bits;
UINT16 log_conn; UINT16 log_conn;
UINT16 fragment_bits; UINT16 fragment_bits;

View File

@ -349,9 +349,8 @@ static void fort_callout_defer_packet_flush(UINT32 list_bits, BOOL dispatchLevel
static void fort_callout_defer_stream_flush(UINT64 flow_id, BOOL dispatchLevel) static void fort_callout_defer_stream_flush(UINT64 flow_id, BOOL dispatchLevel)
{ {
UNUSED(dispatchLevel); fort_defer_stream_flush(
&fort_device()->defer, fort_packet_inject_complete, flow_id, dispatchLevel);
fort_defer_stream_flush(&fort_device()->defer, fort_packet_inject_complete, flow_id, FALSE);
} }
FORT_API void fort_callout_defer_flush(void) FORT_API void fort_callout_defer_flush(void)
@ -527,20 +526,20 @@ static BOOL fort_callout_transport_classify_packet(const FWPS_INCOMING_VALUES0 *
const FWPS_FILTER0 *filter, UINT64 flowContext, FWPS_CLASSIFY_OUT0 *classifyOut, const FWPS_FILTER0 *filter, UINT64 flowContext, FWPS_CLASSIFY_OUT0 *classifyOut,
PNET_BUFFER netBuf, BOOL isIPv6, BOOL inbound) PNET_BUFFER netBuf, BOOL isIPv6, BOOL inbound)
{ {
if (isIPv6) /* TODO: Support IPv6 for speed limits */
return FALSE;
PFORT_FLOW flow = (PFORT_FLOW) flowContext; PFORT_FLOW flow = (PFORT_FLOW) flowContext;
const UCHAR flow_flags = fort_flow_flags(flow); const UCHAR flow_flags = fort_flow_flags(flow);
const UCHAR speed_limit = inbound ? FORT_FLOW_SPEED_LIMIT_OUT : FORT_FLOW_SPEED_LIMIT_IN;
const UCHAR defer_flag = inbound ? FORT_FLOW_DEFER_IN : FORT_FLOW_DEFER_OUT; const UCHAR defer_flag = inbound ? FORT_FLOW_DEFER_IN : FORT_FLOW_DEFER_OUT;
const UCHAR ack_speed_limit = inbound ? FORT_FLOW_SPEED_LIMIT_OUT : FORT_FLOW_SPEED_LIMIT_IN;
const UCHAR speed_defer_flags = ack_speed_limit | defer_flag; const UCHAR speed_defer_flags = speed_limit | defer_flag;
const BOOL defer_flow = (flow_flags & speed_defer_flags) == speed_defer_flags const BOOL defer_flow = (flow_flags & speed_defer_flags) == speed_defer_flags
&& !fort_device_flag(&fort_device()->conf, FORT_DEVICE_POWER_OFF); && !fort_device_flag(&fort_device()->conf, FORT_DEVICE_POWER_OFF);
if (isIPv6) /* TODO: Support IPv6 for speed limits */
return FALSE;
#if 0 #if 0
/* Position in the packet data: /* Position in the packet data:
* FWPS_LAYER_INBOUND_TRANSPORT_V4: The beginning of the data. * FWPS_LAYER_INBOUND_TRANSPORT_V4: The beginning of the data.

View File

@ -160,11 +160,15 @@ static NTSTATUS fort_device_control_setconf(const PFORT_CONF_IO conf_io, ULONG l
static NTSTATUS fort_device_control_setflags(const PFORT_CONF_FLAGS conf_flags, ULONG len) static NTSTATUS fort_device_control_setflags(const PFORT_CONF_FLAGS conf_flags, ULONG len)
{ {
if (len == sizeof(FORT_CONF_FLAGS)) { if (len == sizeof(FORT_CONF_FLAGS)) {
PFORT_STAT stat = &g_device->stat;
const FORT_CONF_FLAGS old_conf_flags = fort_conf_ref_flags_set(&g_device->conf, conf_flags); const FORT_CONF_FLAGS old_conf_flags = fort_conf_ref_flags_set(&g_device->conf, conf_flags);
const UINT32 defer_flush_bits = const UINT32 defer_flush_bits =
(old_conf_flags.group_bits != conf_flags->group_bits ? FORT_DEFER_FLUSH_ALL : 0); (old_conf_flags.group_bits != conf_flags->group_bits ? FORT_DEFER_FLUSH_ALL : 0);
fort_stat_conf_flags_update(stat, conf_flags);
return fort_callout_force_reauth(old_conf_flags, defer_flush_bits); return fort_callout_force_reauth(old_conf_flags, defer_flush_bits);
} }
@ -285,7 +289,7 @@ static NTSTATUS fort_device_control_process(
case FORT_IOCTL_SETZONEFLAG: case FORT_IOCTL_SETZONEFLAG:
return fort_device_control_setzoneflag(buffer, in_len); return fort_device_control_setzoneflag(buffer, in_len);
default: default:
return STATUS_UNSUCCESSFUL; return STATUS_INVALID_DEVICE_REQUEST;
} }
} }

View File

@ -393,7 +393,7 @@ FORT_API void fort_defer_packet_free(
if (clonedNetBufList != NULL) { if (clonedNetBufList != NULL) {
const NTSTATUS status = clonedNetBufList->Status; const NTSTATUS status = clonedNetBufList->Status;
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status) && status != STATUS_NOT_FOUND) {
LOG("Defer: Injection error: %x\n", status); LOG("Defer: Injection error: %x\n", status);
TRACE(FORT_PACKET_DEFER_INJECTION_ERROR, status, 0, 0); TRACE(FORT_PACKET_DEFER_INJECTION_ERROR, status, 0, 0);
} }
@ -467,8 +467,8 @@ FORT_API void fort_defer_packet_flush(PFORT_DEFER defer, FORT_INJECT_COMPLETE_FU
for (int i = 0; list_bits != 0; ++i) { for (int i = 0; list_bits != 0; ++i) {
const UINT32 list_bit = (list_bits & 1); const UINT32 list_bit = (list_bits & 1);
list_bits >>= 1; list_bits >>= 1;
if (list_bit == 0) if (list_bit == 0)
continue; continue;

View File

@ -13,10 +13,13 @@
#define fort_flow_hash(flow_id) tommy_inthash_u32((UINT32) (flow_id)) #define fort_flow_hash(flow_id) tommy_inthash_u32((UINT32) (flow_id))
#define fort_stat_group_fragment(stat, group_index) \ #define fort_stat_group_fragment(stat, group_index) \
((((stat)->conf_group.fragment_bits >> (group_index)) & 1) != 0 ? FORT_FLOW_FRAGMENT : 0) (((((stat)->conf_group.group_bits & (stat)->conf_group.fragment_bits) >> (group_index)) & 1) \
!= 0 \
? FORT_FLOW_FRAGMENT \
: 0)
#define fort_stat_group_speed_limit(stat, group_index) \ #define fort_stat_group_speed_limit(stat, group_index) \
(((stat)->conf_group.limit_bits >> (group_index)) & 1) ((((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) static void fort_stat_proc_active_add(PFORT_STAT stat, PFORT_STAT_PROC proc)
{ {
@ -335,6 +338,16 @@ FORT_API void fort_stat_conf_update(PFORT_STAT stat, PFORT_CONF_IO conf_io)
KeReleaseInStackQueuedSpinLock(&lock_queue); KeReleaseInStackQueuedSpinLock(&lock_queue);
} }
FORT_API void fort_stat_conf_flags_update(PFORT_STAT stat, PFORT_CONF_FLAGS conf_flags)
{
KLOCK_QUEUE_HANDLE lock_queue;
KeAcquireInStackQueuedSpinLock(&stat->lock, &lock_queue);
{
stat->conf_group.group_bits = (UINT16) conf_flags->group_bits;
}
KeReleaseInStackQueuedSpinLock(&lock_queue);
}
static NTSTATUS fort_flow_associate_proc(PFORT_STAT stat, UINT32 process_id, BOOL is_reauth, static NTSTATUS fort_flow_associate_proc(PFORT_STAT stat, UINT32 process_id, BOOL is_reauth,
BOOL *is_new_proc, PFORT_STAT_PROC *proc) BOOL *is_new_proc, PFORT_STAT_PROC *proc)
{ {
@ -544,31 +557,24 @@ FORT_API UINT32 fort_stat_dpc_group_flush(PFORT_STAT stat)
/* Handle process group's bytes */ /* Handle process group's bytes */
for (int i = 0; flush_bits != 0; ++i) { for (int i = 0; flush_bits != 0; ++i) {
PFORT_STAT_GROUP group;
PFORT_TRAF group_limit;
FORT_TRAF traf;
UINT32 flush_bit = (flush_bits & 3); UINT32 flush_bit = (flush_bits & 3);
flush_bits >>= 2; flush_bits >>= 2;
if (flush_bit == 0) if (flush_bit == 0)
continue; continue;
group = &stat->groups[i]; PFORT_STAT_GROUP group = &stat->groups[i];
group_limit = &stat->conf_group.limits[i]; PFORT_TRAF traf = &group->traf;
const PFORT_TRAF group_limit = &stat->conf_group.limits[i];
traf = group->traf;
// Inbound // Inbound
fort_stat_group_flush_limit_bytes(&defer_flush_bits, &flush_bit, &traf.in_bytes, fort_stat_group_flush_limit_bytes(&defer_flush_bits, &flush_bit, &traf->in_bytes,
group_limit->in_bytes, /*group_index=*/i, /*flush_index=*/1, /*defer_offset=*/1); group_limit->in_bytes, /*group_index=*/i, /*flush_index=*/1, /*defer_offset=*/1);
// Outbound // Outbound
fort_stat_group_flush_limit_bytes(&defer_flush_bits, &flush_bit, &traf.out_bytes, fort_stat_group_flush_limit_bytes(&defer_flush_bits, &flush_bit, &traf->out_bytes,
group_limit->out_bytes, /*group_index=*/i, /*flush_index=*/2, /*defer_offset=*/0); group_limit->out_bytes, /*group_index=*/i, /*flush_index=*/2, /*defer_offset=*/0);
// Adjust flushed bytes
group->traf = traf;
stat->group_flush_bits &= ~(flush_bit << (i * 2)); stat->group_flush_bits &= ~(flush_bit << (i * 2));
} }

View File

@ -147,6 +147,8 @@ FORT_API void fort_stat_update(PFORT_STAT stat, BOOL log_stat);
FORT_API void fort_stat_conf_update(PFORT_STAT stat, PFORT_CONF_IO conf_io); FORT_API void fort_stat_conf_update(PFORT_STAT stat, PFORT_CONF_IO conf_io);
FORT_API void fort_stat_conf_flags_update(PFORT_STAT stat, PFORT_CONF_FLAGS conf_flags);
FORT_API NTSTATUS fort_flow_associate(PFORT_STAT stat, UINT64 flow_id, UINT32 process_id, FORT_API NTSTATUS fort_flow_associate(PFORT_STAT stat, UINT64 flow_id, UINT32 process_id,
UCHAR group_index, BOOL isIPv6, BOOL is_tcp, BOOL is_reauth, BOOL *is_new_proc); UCHAR group_index, BOOL isIPv6, BOOL is_tcp, BOOL is_reauth, BOOL *is_new_proc);

View File

@ -509,7 +509,8 @@ void ConfUtil::writeConf(char *output, const FirewallConf &conf,
writeApps(&data, exeAppsMap); writeApps(&data, exeAppsMap);
#undef CONF_DATA_OFFSET #undef CONF_DATA_OFFSET
writeAppGroupFlags(&drvConfIo->conf_group.log_conn, &drvConfIo->conf_group.fragment_bits, conf); writeAppGroupFlags(&drvConfIo->conf_group.group_bits, &drvConfIo->conf_group.log_conn,
&drvConfIo->conf_group.fragment_bits, conf);
writeLimits(drvConfIo->conf_group.limits, &drvConfIo->conf_group.limit_bits, writeLimits(drvConfIo->conf_group.limits, &drvConfIo->conf_group.limit_bits,
&drvConfIo->conf_group.limit_2bits, conf.appGroups()); &drvConfIo->conf_group.limit_2bits, conf.appGroups());
@ -534,12 +535,16 @@ void ConfUtil::writeConf(char *output, const FirewallConf &conf,
} }
void ConfUtil::writeAppGroupFlags( void ConfUtil::writeAppGroupFlags(
quint16 *logConnBits, quint16 *fragmentBits, const FirewallConf &conf) quint16 *groupBits, quint16 *logConnBits, quint16 *fragmentBits, const FirewallConf &conf)
{ {
*groupBits = 0;
*logConnBits = 0; *logConnBits = 0;
*fragmentBits = 0; *fragmentBits = 0;
int i = 0; int i = 0;
for (const AppGroup *appGroup : conf.appGroups()) { for (const AppGroup *appGroup : conf.appGroups()) {
if (appGroup->enabled()) {
*groupBits |= (1 << i);
}
if (appGroup->logConn()) { if (appGroup->logConn()) {
*logConnBits |= (1 << i); *logConnBits |= (1 << i);
} }
@ -572,7 +577,7 @@ void ConfUtil::writeLimits(struct fort_traf *limits, quint16 *limitBits, quint32
*limitBits |= (1 << i); *limitBits |= (1 << i);
if (isLimitIn) { if (isLimitIn) {
*limit2Bits |= (1 << (i * 2)); *limit2Bits |= (1 << (i * 2 + 0));
} }
if (isLimitOut) { if (isLimitOut) {
*limit2Bits |= (1 << (i * 2 + 1)); *limit2Bits |= (1 << (i * 2 + 1));

View File

@ -94,8 +94,8 @@ private:
const appentry_map_t &wildAppsMap, const appentry_map_t &prefixAppsMap, const appentry_map_t &wildAppsMap, const appentry_map_t &prefixAppsMap,
const appentry_map_t &exeAppsMap); const appentry_map_t &exeAppsMap);
static void writeAppGroupFlags( static void writeAppGroupFlags(quint16 *groupBits, quint16 *logConnBits, quint16 *fragmentBits,
quint16 *logConnBits, quint16 *fragmentBits, const FirewallConf &conf); const FirewallConf &conf);
static void writeLimits(struct fort_traf *limits, quint16 *limitBits, quint32 *limit2Bits, static void writeLimits(struct fort_traf *limits, quint16 *limitBits, quint32 *limit2Bits,
const QList<AppGroup *> &appGroups); const QList<AppGroup *> &appGroups);