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
{
UINT16 group_bits;
UINT16 log_conn;
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)
{
UNUSED(dispatchLevel);
fort_defer_stream_flush(&fort_device()->defer, fort_packet_inject_complete, flow_id, FALSE);
fort_defer_stream_flush(
&fort_device()->defer, fort_packet_inject_complete, flow_id, dispatchLevel);
}
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,
PNET_BUFFER netBuf, BOOL isIPv6, BOOL inbound)
{
if (isIPv6) /* TODO: Support IPv6 for speed limits */
return FALSE;
PFORT_FLOW flow = (PFORT_FLOW) flowContext;
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 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
&& !fort_device_flag(&fort_device()->conf, FORT_DEVICE_POWER_OFF);
if (isIPv6) /* TODO: Support IPv6 for speed limits */
return FALSE;
#if 0
/* Position in the packet 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)
{
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 UINT32 defer_flush_bits =
(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);
}
@ -285,7 +289,7 @@ static NTSTATUS fort_device_control_process(
case FORT_IOCTL_SETZONEFLAG:
return fort_device_control_setzoneflag(buffer, in_len);
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) {
const NTSTATUS status = clonedNetBufList->Status;
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status) && status != STATUS_NOT_FOUND) {
LOG("Defer: Injection error: %x\n", status);
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) {
const UINT32 list_bit = (list_bits & 1);
list_bits >>= 1;
if (list_bit == 0)
continue;

View File

@ -13,10 +13,13 @@
#define fort_flow_hash(flow_id) tommy_inthash_u32((UINT32) (flow_id))
#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) \
(((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)
{
@ -335,6 +338,16 @@ FORT_API void fort_stat_conf_update(PFORT_STAT stat, PFORT_CONF_IO conf_io)
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,
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 */
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);
flush_bits >>= 2;
if (flush_bit == 0)
continue;
group = &stat->groups[i];
group_limit = &stat->conf_group.limits[i];
traf = group->traf;
PFORT_STAT_GROUP group = &stat->groups[i];
PFORT_TRAF traf = &group->traf;
const PFORT_TRAF group_limit = &stat->conf_group.limits[i];
// 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);
// 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);
// Adjust flushed bytes
group->traf = traf;
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_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,
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);
#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,
&drvConfIo->conf_group.limit_2bits, conf.appGroups());
@ -534,12 +535,16 @@ void ConfUtil::writeConf(char *output, const FirewallConf &conf,
}
void ConfUtil::writeAppGroupFlags(
quint16 *logConnBits, quint16 *fragmentBits, const FirewallConf &conf)
quint16 *groupBits, quint16 *logConnBits, quint16 *fragmentBits, const FirewallConf &conf)
{
*groupBits = 0;
*logConnBits = 0;
*fragmentBits = 0;
int i = 0;
for (const AppGroup *appGroup : conf.appGroups()) {
if (appGroup->enabled()) {
*groupBits |= (1 << i);
}
if (appGroup->logConn()) {
*logConnBits |= (1 << i);
}
@ -572,7 +577,7 @@ void ConfUtil::writeLimits(struct fort_traf *limits, quint16 *limitBits, quint32
*limitBits |= (1 << i);
if (isLimitIn) {
*limit2Bits |= (1 << (i * 2));
*limit2Bits |= (1 << (i * 2 + 0));
}
if (isLimitOut) {
*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 &exeAppsMap);
static void writeAppGroupFlags(
quint16 *logConnBits, quint16 *fragmentBits, const FirewallConf &conf);
static void writeAppGroupFlags(quint16 *groupBits, quint16 *logConnBits, quint16 *fragmentBits,
const FirewallConf &conf);
static void writeLimits(struct fort_traf *limits, quint16 *limitBits, quint32 *limit2Bits,
const QList<AppGroup *> &appGroups);