mirror of
https://github.com/tnodir/fort
synced 2024-11-15 06:35:23 +00:00
Driver: Drop limited traffic.
This commit is contained in:
parent
bb954c116b
commit
01311d12aa
@ -158,6 +158,29 @@ fort_conf_ref_flags_set (const PFORT_CONF_FLAGS conf_flags)
|
||||
return old_conf_flags;
|
||||
}
|
||||
|
||||
static void
|
||||
fort_callout_classify_block (FWPS_CLASSIFY_OUT0 *classifyOut)
|
||||
{
|
||||
classifyOut->actionType = FWP_ACTION_BLOCK;
|
||||
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
|
||||
}
|
||||
|
||||
static void
|
||||
fort_callout_classify_permit (const FWPS_FILTER0 *filter,
|
||||
FWPS_CLASSIFY_OUT0 *classifyOut)
|
||||
{
|
||||
classifyOut->actionType = FWP_ACTION_PERMIT;
|
||||
if ((filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT)) {
|
||||
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fort_callout_classify_continue (FWPS_CLASSIFY_OUT0 *classifyOut)
|
||||
{
|
||||
classifyOut->actionType = FWP_ACTION_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues,
|
||||
@ -181,25 +204,26 @@ fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
conf_ref = fort_conf_ref_take();
|
||||
|
||||
if (conf_ref == NULL) {
|
||||
if (g_device->prov_boot)
|
||||
goto block;
|
||||
|
||||
classifyOut->actionType = FWP_ACTION_CONTINUE;
|
||||
if (g_device->prov_boot) {
|
||||
fort_callout_classify_block(classifyOut);
|
||||
} else {
|
||||
fort_callout_classify_continue(classifyOut);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
conf_flags = conf_ref->conf.flags;
|
||||
|
||||
if (conf_flags.stop_traffic) {
|
||||
goto block;
|
||||
}
|
||||
|
||||
flags = inFixedValues->incomingValue[flagsField].value.uint32;
|
||||
remote_ip = inFixedValues->incomingValue[remoteIpField].value.uint32;
|
||||
|
||||
if (!conf_flags.filter_enabled || conf_flags.stop_traffic
|
||||
if (!conf_flags.filter_enabled
|
||||
|| (flags & FWP_CONDITION_FLAG_IS_LOOPBACK)
|
||||
|| remote_ip == 0xFFFFFFFF) { // Local broadcast
|
||||
fort_conf_ref_put(conf_ref);
|
||||
if (conf_flags.stop_traffic) {
|
||||
goto block;
|
||||
}
|
||||
goto permit;
|
||||
}
|
||||
|
||||
@ -212,8 +236,6 @@ fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
&& ((app_index = fort_conf_app_index(&conf_ref->conf, path_len, path)),
|
||||
fort_conf_app_blocked(&conf_ref->conf, app_index));
|
||||
|
||||
fort_conf_ref_put(conf_ref);
|
||||
|
||||
if (!blocked) {
|
||||
if (ip_included && conf_flags.log_stat) {
|
||||
const IPPROTO ip_proto = (IPPROTO) inFixedValues->incomingValue[
|
||||
@ -246,17 +268,15 @@ fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
}
|
||||
|
||||
block:
|
||||
classifyOut->actionType = FWP_ACTION_BLOCK;
|
||||
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
|
||||
fort_callout_classify_block(classifyOut);
|
||||
goto end;
|
||||
|
||||
permit:
|
||||
classifyOut->actionType = FWP_ACTION_PERMIT;
|
||||
if ((filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT)) {
|
||||
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
|
||||
}
|
||||
fort_callout_classify_permit(filter, classifyOut);
|
||||
|
||||
end:
|
||||
fort_conf_ref_put(conf_ref);
|
||||
|
||||
if (irp != NULL) {
|
||||
fort_request_complete_info(irp, STATUS_SUCCESS, info);
|
||||
}
|
||||
@ -312,6 +332,22 @@ fort_callout_flow_delete_v4 (UINT16 layerId,
|
||||
fort_stat_flow_delete(&g_device->stat, flowContext);
|
||||
}
|
||||
|
||||
static void
|
||||
fort_callout_flow_classify_v4 (const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues,
|
||||
UINT64 flowContext,
|
||||
FWPS_CLASSIFY_OUT0 *classifyOut,
|
||||
UINT32 dataSize, BOOL inbound)
|
||||
{
|
||||
const UINT32 headerSize = inbound ? inMetaValues->transportHeaderSize : 0;
|
||||
|
||||
if (fort_stat_flow_classify(&g_device->stat, flowContext,
|
||||
headerSize + dataSize, inbound)) {
|
||||
fort_callout_classify_block(classifyOut);
|
||||
} else {
|
||||
fort_callout_classify_continue(classifyOut);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fort_callout_stream_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues,
|
||||
@ -325,12 +361,11 @@ fort_callout_stream_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
|
||||
const BOOL inbound = (streamData->flags & FWPS_STREAM_FLAG_RECEIVE) != 0;
|
||||
|
||||
const UINT32 headerSize = inbound ? inMetaValues->transportHeaderSize : 0;
|
||||
UNUSED(inFixedValues);
|
||||
UNUSED(filter);
|
||||
|
||||
fort_stat_flow_classify(&g_device->stat, flowContext,
|
||||
headerSize + dataSize, inbound);
|
||||
|
||||
classifyOut->actionType = FWP_ACTION_CONTINUE;
|
||||
fort_callout_flow_classify_v4(inMetaValues, flowContext, classifyOut,
|
||||
dataSize, inbound);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -348,12 +383,11 @@ fort_callout_datagram_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
FWPS_FIELD_DATAGRAM_DATA_V4_DIRECTION].value.uint8;
|
||||
const BOOL inbound = (direction == FWP_DIRECTION_INBOUND);
|
||||
|
||||
const UINT32 headerSize = inbound ? inMetaValues->transportHeaderSize : 0;
|
||||
UNUSED(inFixedValues);
|
||||
UNUSED(filter);
|
||||
|
||||
fort_stat_flow_classify(&g_device->stat, flowContext,
|
||||
headerSize + dataSize, inbound);
|
||||
|
||||
classifyOut->actionType = FWP_ACTION_CONTINUE;
|
||||
fort_callout_flow_classify_v4(inMetaValues, flowContext, classifyOut,
|
||||
dataSize, inbound);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -319,10 +319,19 @@ fort_stat_flow_remove_context (UINT64 flow_id, UINT16 layer_id,
|
||||
|
||||
static void
|
||||
fort_stat_flow_transport_set_contexts (PFORT_STAT stat, UINT64 flow_id,
|
||||
UINT64 flow_context,
|
||||
BOOL is_udp, BOOL speed_limit)
|
||||
UINT64 flow_context, BOOL is_udp,
|
||||
BOOL speed_limit, BOOL is_reauth)
|
||||
{
|
||||
if (!is_udp && speed_limit) {
|
||||
if (is_udp) return;
|
||||
|
||||
if (is_reauth) {
|
||||
fort_stat_flow_remove_context(flow_id,
|
||||
FWPS_LAYER_INBOUND_TRANSPORT_V4, stat->in_transport4_id);
|
||||
fort_stat_flow_remove_context(flow_id,
|
||||
FWPS_LAYER_OUTBOUND_TRANSPORT_V4, stat->out_transport4_id);
|
||||
}
|
||||
|
||||
if (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,
|
||||
@ -438,8 +447,15 @@ fort_stat_update_limits (PFORT_STAT stat, PFORT_CONF_IO conf_io)
|
||||
KLOCK_QUEUE_HANDLE lock_queue;
|
||||
|
||||
KeAcquireInStackQueuedSpinLock(&stat->lock, &lock_queue);
|
||||
stat->limit_bits = conf_io->limit_bits;
|
||||
RtlCopyMemory(stat->limits, conf_io->limits, sizeof(stat->limits));
|
||||
{
|
||||
const UINT16 limit_bits = conf_io->limit_bits;
|
||||
|
||||
stat->limit_bits = limit_bits;
|
||||
|
||||
if (limit_bits != 0) {
|
||||
RtlCopyMemory(stat->limits, conf_io->limits, sizeof(stat->limits));
|
||||
}
|
||||
}
|
||||
KeReleaseInStackQueuedSpinLock(&lock_queue);
|
||||
}
|
||||
|
||||
@ -503,7 +519,7 @@ fort_stat_flow_associate (PFORT_STAT stat, UINT64 flow_id,
|
||||
if (NT_SUCCESS(status)) {
|
||||
// Set stream transport layer contexts
|
||||
fort_stat_flow_transport_set_contexts(
|
||||
stat, flow_id, flow_context, is_udp, speed_limit);
|
||||
stat, flow_id, flow_context, is_udp, speed_limit, is_reauth);
|
||||
|
||||
fort_stat_proc_inc(stat, proc_index);
|
||||
} else {
|
||||
@ -547,7 +563,7 @@ fort_stat_flow_delete (PFORT_STAT stat, UINT64 flow_context)
|
||||
KeReleaseInStackQueuedSpinLock(&lock_queue);
|
||||
}
|
||||
|
||||
static void
|
||||
static BOOL
|
||||
fort_stat_flow_classify (PFORT_STAT stat, UINT64 flow_context,
|
||||
UINT32 data_len, BOOL inbound)
|
||||
{
|
||||
@ -555,35 +571,44 @@ fort_stat_flow_classify (PFORT_STAT stat, UINT64 flow_context,
|
||||
const UINT16 proc_index = (UINT16) (flow_context >> 48);
|
||||
const UCHAR group_index = (UCHAR) (flow_context >> 40);
|
||||
const UCHAR stat_version = (UCHAR) (flow_context >> 32);
|
||||
BOOL limited = FALSE;
|
||||
|
||||
if (stat->closing)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
KeAcquireInStackQueuedSpinLock(&stat->lock, &lock_queue);
|
||||
if (stat_version == stat->version) {
|
||||
PFORT_STAT_PROC proc = &stat->procs[proc_index];
|
||||
UINT32 *proc_bytes = inbound ? &proc->traf.in_bytes
|
||||
: &proc->traf.out_bytes;
|
||||
|
||||
// Add traffic to process
|
||||
if (inbound) {
|
||||
proc->traf.in_bytes += data_len;
|
||||
} else {
|
||||
proc->traf.out_bytes += data_len;
|
||||
}
|
||||
*proc_bytes += data_len;
|
||||
|
||||
if (fort_stat_group_speed_limit(stat, group_index)) {
|
||||
PFORT_STAT_GROUP group = &stat->groups[group_index];
|
||||
const PFORT_CONF_LIMIT group_limit = &stat->limits[group_index];
|
||||
const UINT32 limit_bytes = inbound ? group_limit->in_bytes
|
||||
: group_limit->out_bytes;
|
||||
|
||||
// Add traffic to app. group
|
||||
if (inbound) {
|
||||
group->traf.in_bytes += data_len;
|
||||
} else {
|
||||
group->traf.out_bytes += data_len;
|
||||
if (limit_bytes != 0) {
|
||||
PFORT_STAT_GROUP group = &stat->groups[group_index];
|
||||
UINT32 *group_bytes = inbound ? &group->traf.in_bytes
|
||||
: &group->traf.out_bytes;
|
||||
|
||||
if (*group_bytes < limit_bytes) {
|
||||
// Add traffic to app. group
|
||||
*group_bytes += data_len;
|
||||
} else {
|
||||
limited = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stat->is_dirty = TRUE;
|
||||
}
|
||||
KeReleaseInStackQueuedSpinLock(&lock_queue);
|
||||
|
||||
return limited;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -604,6 +629,7 @@ fort_stat_dpc_traf_flush (PFORT_STAT stat, PCHAR out)
|
||||
const UINT32 proc_bits_len = FORT_LOG_STAT_PROC_SIZE(stat->proc_count);
|
||||
PFORT_STAT_TRAF out_traf = (PFORT_STAT_TRAF) (out + proc_bits_len);
|
||||
PUCHAR out_proc_bits = (PUCHAR) out;
|
||||
UINT16 i;
|
||||
|
||||
PFORT_STAT_PROC prev_proc = NULL;
|
||||
UINT16 proc_index = stat->proc_head_index;
|
||||
@ -611,7 +637,7 @@ fort_stat_dpc_traf_flush (PFORT_STAT stat, PCHAR out)
|
||||
/* Mark processes as active to start */
|
||||
memset(out_proc_bits, 0xFF, proc_bits_len);
|
||||
|
||||
for (UINT16 i = 0; proc_index != FORT_PROC_BAD_INDEX; ++i) {
|
||||
for (i = 0; proc_index != FORT_PROC_BAD_INDEX; ++i) {
|
||||
PFORT_STAT_PROC proc = &stat->procs[proc_index];
|
||||
const UINT16 next_index = proc->next_index;
|
||||
|
||||
@ -633,5 +659,18 @@ fort_stat_dpc_traf_flush (PFORT_STAT stat, PCHAR out)
|
||||
proc_index = next_index;
|
||||
}
|
||||
|
||||
if (stat->limit_bits) {
|
||||
PFORT_STAT_GROUP group = stat->groups;
|
||||
UINT16 limit_bits = stat->limit_bits;
|
||||
|
||||
for (; limit_bits != 0; ++group) {
|
||||
if (limit_bits & 1) {
|
||||
group->traf_all.QuadPart = 0;
|
||||
}
|
||||
|
||||
limit_bits >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
stat->is_dirty = FALSE;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ int ConfUtil::write(const FirewallConf &conf, QByteArray &buf)
|
||||
int appPathsLen = 0;
|
||||
QStringList appPaths;
|
||||
appperms_arr_t appPerms;
|
||||
appgroups_arr_t appGroupIndexes;
|
||||
appgroups_map_t appGroupIndexes;
|
||||
|
||||
if (!parseAppGroups(conf.appGroupsList(),
|
||||
appPaths, appPathsLen,
|
||||
@ -110,7 +110,7 @@ bool ConfUtil::parseAppGroups(const QList<AppGroup *> &appGroups,
|
||||
QStringList &appPaths,
|
||||
int &appPathsLen,
|
||||
appperms_arr_t &appPerms,
|
||||
appgroups_arr_t &appGroupIndexes)
|
||||
appgroups_map_t &appGroupIndexes)
|
||||
{
|
||||
const int groupsCount = appGroups.size();
|
||||
if (groupsCount > APP_GROUP_MAX) {
|
||||
@ -159,7 +159,7 @@ bool ConfUtil::parseAppGroups(const QList<AppGroup *> &appGroups,
|
||||
|
||||
bool ConfUtil::parseApps(const QString &text, bool blocked,
|
||||
appperms_map_t &appPermsMap,
|
||||
appgroups_arr_t &appGroupIndexes,
|
||||
appgroups_map_t &appGroupIndexes,
|
||||
int groupOffset)
|
||||
{
|
||||
foreach (const QStringRef &line,
|
||||
@ -184,7 +184,7 @@ bool ConfUtil::parseApps(const QString &text, bool blocked,
|
||||
if (appPermsMap.contains(appPath)) {
|
||||
appPerms |= appPermsMap.value(appPath);
|
||||
} else {
|
||||
appGroupIndexes.append(groupOffset);
|
||||
appGroupIndexes.insert(appPath, groupOffset);
|
||||
}
|
||||
|
||||
appPermsMap.insert(appPath, appPerms);
|
||||
@ -215,7 +215,7 @@ void ConfUtil::writeData(char *output, const FirewallConf &conf,
|
||||
const Ip4Range &incRange, const Ip4Range &excRange,
|
||||
const QStringList &appPaths,
|
||||
const appperms_arr_t &appPerms,
|
||||
const appgroups_arr_t &appGroupIndexes)
|
||||
const appgroups_map_t &appGroupIndexes)
|
||||
{
|
||||
PFORT_CONF_IO drvConfIo = (PFORT_CONF_IO) output;
|
||||
PFORT_CONF drvConf = &drvConfIo->conf;
|
||||
@ -241,7 +241,7 @@ void ConfUtil::writeData(char *output, const FirewallConf &conf,
|
||||
writeNumbers(&data, excRange.toArray());
|
||||
|
||||
appGroupsOff = CONF_DATA_OFFSET;
|
||||
writeChars(&data, appGroupIndexes);
|
||||
writeChars(&data, appGroupIndexes.values().toVector());
|
||||
|
||||
appPermsOff = CONF_DATA_OFFSET;
|
||||
writeNumbers(&data, appPerms);
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef CONFUTIL_H
|
||||
#define CONFUTIL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
@ -15,7 +14,7 @@ QT_FORWARD_DECLARE_STRUCT(fort_conf_limit)
|
||||
|
||||
typedef QMap<QString, quint32> appperms_map_t;
|
||||
typedef QVector<quint32> appperms_arr_t;
|
||||
typedef QVector<qint8> appgroups_arr_t;
|
||||
typedef QMap<QString, qint8> appgroups_map_t;
|
||||
|
||||
class ConfUtil : public QObject
|
||||
{
|
||||
@ -42,11 +41,11 @@ private:
|
||||
QStringList &appPaths,
|
||||
int &appPathsLen,
|
||||
appperms_arr_t &appPerms,
|
||||
appgroups_arr_t &appGroupIndexes);
|
||||
appgroups_map_t &appGroupIndexes);
|
||||
|
||||
bool parseApps(const QString &text, bool blocked,
|
||||
appperms_map_t &appPermsMap,
|
||||
appgroups_arr_t &appGroupIndexes,
|
||||
appgroups_map_t &appGroupIndexes,
|
||||
int groupOffset);
|
||||
|
||||
static QString parseAppPath(const QStringRef &line);
|
||||
@ -55,7 +54,7 @@ private:
|
||||
const Ip4Range &incRange, const Ip4Range &excRange,
|
||||
const QStringList &appPaths,
|
||||
const appperms_arr_t &appPerms,
|
||||
const appgroups_arr_t &appGroupIndexes);
|
||||
const appgroups_map_t &appGroupIndexes);
|
||||
|
||||
static quint16 writeLimits(struct fort_conf_limit *limits,
|
||||
const QList<AppGroup *> &appGroups);
|
||||
|
Loading…
Reference in New Issue
Block a user