UI: Add AppBlockedModel.

This commit is contained in:
Nodir Temirkhodjaev 2017-11-17 08:46:35 +05:00
parent ca465860ce
commit 39bec283c7
16 changed files with 271 additions and 70 deletions

View File

@ -25,14 +25,20 @@ void Test::logWriteRead()
// Write
for (int i = 0; i < testCount; ++i) {
QCOMPARE(buf.write(&entry), entrySize);
buf.writeEntryBlocked(&entry);
}
// Read
while (buf.read(&entry)) {
int readCount = 0;
while (buf.peekEntryType() == LogEntry::AppBlocked) {
buf.readEntryBlocked(&entry);
QCOMPARE(entry.type(), LogEntry::AppBlocked);
QCOMPARE(entry.ip(), ip);
QCOMPARE(entry.pid(), pid);
QCOMPARE(entry.kernelPath(), path);
++readCount;
}
QCOMPARE(readCount, testCount);
}

View File

@ -71,7 +71,7 @@ void Test::setConf(Device &device)
void Test::printLogs(LogBuffer &buf)
{
forever {
const LogEntry::LogType logType = buf.readType();
const LogEntry::LogType logType = buf.peekEntryType();
if (logType == LogEntry::TypeNone)
break;
@ -79,8 +79,7 @@ void Test::printLogs(LogBuffer &buf)
LogEntryBlocked entry;
if (!buf.read(&entry))
break;
buf.readEntryBlocked(&entry);
const quint32 pid = entry.pid();
QString kernelPath = entry.kernelPath();

View File

@ -7,10 +7,6 @@ TEMPLATE = app
SOURCES += \
main.cpp \
log/logbuffer.cpp \
log/logentry.cpp \
log/logentryblocked.cpp \
log/logmanager.cpp \
conf/addressgroup.cpp \
conf/appgroup.cpp \
conf/firewallconf.cpp \
@ -19,6 +15,12 @@ SOURCES += \
fortcommon.cpp \
fortmanager.cpp \
fortsettings.cpp \
log/logbuffer.cpp \
log/logentry.cpp \
log/logentryblocked.cpp \
log/logmanager.cpp \
log/model/appblockedmodel.cpp \
log/model/stringlistmodel.cpp \
mainwindow.cpp \
task/taskinfo.cpp \
task/taskmanager.cpp \
@ -40,10 +42,6 @@ SOURCES += \
util/stringutil.cpp
HEADERS += \
log/logbuffer.h \
log/logentry.h \
log/logentryblocked.h \
log/logmanager.h \
conf/addressgroup.h \
conf/appgroup.h \
conf/firewallconf.h \
@ -52,6 +50,12 @@ HEADERS += \
fortcommon.h \
fortmanager.h \
fortsettings.h \
log/logbuffer.h \
log/logentry.h \
log/logentryblocked.h \
log/logmanager.h \
log/model/appblockedmodel.h \
log/model/stringlistmodel.h \
mainwindow.h \
task/taskinfo.h \
task/taskmanager.h \

View File

@ -34,7 +34,7 @@ FortManager::FortManager(FortSettings *fortSettings,
m_firewallConf(new FirewallConf(this)),
m_firewallConfToEdit(nullConf()),
m_driverManager(new DriverManager(this)),
m_logManager(new LogManager(m_driverManager->driverWorker(), m_driverManager)),
m_logManager(new LogManager(m_driverManager->driverWorker(), this)),
m_taskManager(new TaskManager(this, this))
{
setupDriver();

View File

@ -31,7 +31,7 @@ void LogBuffer::prepareFor(int len)
}
}
LogEntry::LogType LogBuffer::readType()
LogEntry::LogType LogBuffer::peekEntryType()
{
if (m_offset >= m_top)
return LogEntry::TypeNone;
@ -43,7 +43,7 @@ LogEntry::LogType LogBuffer::readType()
return static_cast<LogEntry::LogType>(type);
}
int LogBuffer::write(const LogEntryBlocked *logEntry)
void LogBuffer::writeEntryBlocked(const LogEntryBlocked *logEntry)
{
const QString path = logEntry->kernelPath();
const int pathLen = path.size() * sizeof(wchar_t);
@ -62,14 +62,11 @@ int LogBuffer::write(const LogEntryBlocked *logEntry)
}
m_top += entrySize;
return entrySize;
}
int LogBuffer::read(LogEntryBlocked *logEntry)
void LogBuffer::readEntryBlocked(LogEntryBlocked *logEntry)
{
if (m_offset >= m_top)
return 0;
Q_ASSERT(m_offset < m_top);
const char *input = this->input();
@ -89,6 +86,4 @@ int LogBuffer::read(LogEntryBlocked *logEntry)
const int entrySize = FortCommon::logBlockedSize(pathLen);
m_offset += entrySize;
return entrySize;
}

View File

@ -21,7 +21,10 @@ public:
QByteArray &array() { return m_array; }
LogEntry::LogType readType();
LogEntry::LogType peekEntryType();
void writeEntryBlocked(const LogEntryBlocked *logEntry);
void readEntryBlocked(LogEntryBlocked *logEntry);
signals:
@ -31,9 +34,6 @@ public slots:
m_offset = 0;
}
int write(const LogEntryBlocked *logEntry);
int read(LogEntryBlocked *logEntry);
private:
char *output();
const char *input() const;

View File

@ -1,6 +1,9 @@
#include "logentry.h"
LogEntry::LogEntry(QObject *parent) :
QObject(parent)
LogEntry::LogEntry()
{
}
LogEntry::~LogEntry()
{
}

View File

@ -3,11 +3,8 @@
#include <QObject>
class LogEntry : public QObject
class LogEntry
{
Q_OBJECT
Q_PROPERTY(LogType type READ type CONSTANT)
public:
enum LogType {
TypeNone = -1,
@ -15,9 +12,9 @@ public:
AppBlocked = 0x01000000,
UsageStat = 0x02000000
};
Q_ENUM(LogType)
explicit LogEntry(QObject *parent = nullptr);
explicit LogEntry();
virtual ~LogEntry();
virtual LogEntry::LogType type() const = 0;
};

View File

@ -1,9 +1,8 @@
#include "logentryblocked.h"
LogEntryBlocked::LogEntryBlocked(quint32 ip, quint32 pid,
const QString &kernelPath,
QObject *parent) :
LogEntry(parent),
const QString &kernelPath) :
LogEntry(),
m_ip(ip),
m_pid(pid),
m_kernelPath(kernelPath)
@ -12,24 +11,15 @@ LogEntryBlocked::LogEntryBlocked(quint32 ip, quint32 pid,
void LogEntryBlocked::setIp(quint32 ip)
{
if (m_ip != ip) {
m_ip = ip;
emit ipChanged();
}
m_ip = ip;
}
void LogEntryBlocked::setPid(quint32 pid)
{
if (m_pid != pid) {
m_pid = pid;
emit pidChanged();
}
m_pid = pid;
}
void LogEntryBlocked::setKernelPath(const QString &kernelPath)
{
if (m_kernelPath != kernelPath) {
m_kernelPath = kernelPath;
emit kernelPathChanged();
}
m_kernelPath = kernelPath;
}

View File

@ -5,15 +5,9 @@
class LogEntryBlocked : public LogEntry
{
Q_OBJECT
Q_PROPERTY(quint32 ip READ ip WRITE setIp NOTIFY ipChanged)
Q_PROPERTY(quint32 pid READ pid WRITE setPid NOTIFY pidChanged)
Q_PROPERTY(QString kernelPath READ kernelPath WRITE setKernelPath NOTIFY kernelPathChanged)
public:
explicit LogEntryBlocked(quint32 ip = 0, quint32 pid = 0,
const QString &kernelPath = QString(),
QObject *parent = nullptr);
const QString &kernelPath = QString());
virtual LogEntry::LogType type() const { return AppBlocked; }
@ -26,13 +20,6 @@ public:
QString kernelPath() const { return m_kernelPath; }
void setKernelPath(const QString &kernelPath);
signals:
void ipChanged();
void pidChanged();
void kernelPathChanged();
public slots:
private:
quint32 m_ip;
quint32 m_pid;

View File

@ -3,17 +3,24 @@
#include "../driver/driverworker.h"
#include "../fortcommon.h"
#include "logbuffer.h"
#include "logentryblocked.h"
#include "model/appblockedmodel.h"
LogManager::LogManager(DriverWorker *driverWorker,
QObject *parent) :
QObject(parent),
m_logReadingEnabled(false),
m_driverWorker(driverWorker),
m_logBuffer(new LogBuffer(FortCommon::bufferSize(), this))
m_appBlockedModel(new AppBlockedModel(this))
{
setupDriverWorker();
}
QAbstractItemModel *LogManager::appBlockedModel() const
{
return m_appBlockedModel;
}
void LogManager::setErrorMessage(const QString &errorMessage)
{
if (m_errorMessage != errorMessage) {
@ -28,7 +35,7 @@ void LogManager::setLogReadingEnabled(bool enabled)
m_logReadingEnabled = enabled;
if (m_logReadingEnabled) {
readLogAsync(m_logBuffer);
readLogAsync(getFreeBuffer());
} else {
cancelAsyncIo();
readLogAsync(nullptr);
@ -52,17 +59,48 @@ void LogManager::cancelAsyncIo()
m_driverWorker->cancelAsyncIo();
}
LogBuffer *LogManager::getFreeBuffer()
{
if (m_freeBuffers.isEmpty()) {
return new LogBuffer(FortCommon::bufferSize(), this);
} else {
return m_freeBuffers.takeLast();
}
}
void LogManager::processLogBuffer(LogBuffer *logBuffer, bool success,
const QString &errorMessage)
{
Q_ASSERT(logBuffer == m_logBuffer);
if (m_logReadingEnabled) {
readLogAsync(getFreeBuffer());
}
if (success) {
readLogEntries(logBuffer);
logBuffer->reset();
} else {
setErrorMessage(errorMessage);
}
if (m_logReadingEnabled) {
readLogAsync(m_logBuffer);
m_freeBuffers.append(logBuffer);
}
void LogManager::readLogEntries(LogBuffer *logBuffer)
{
LogEntryBlocked entryBlocked;
forever {
switch (logBuffer->peekEntryType()) {
case LogEntry::AppBlocked: {
logBuffer->readEntryBlocked(&entryBlocked);
m_appBlockedModel->addLogEntry(entryBlocked);
break;
}
case LogEntry::UsageStat: {
//break;
}
default:
return;
}
}
}

View File

@ -1,10 +1,13 @@
#ifndef LOGMANAGER_H
#define LOGMANAGER_H
#include <QAbstractItemModel>
#include <QObject>
class AppBlockedModel;
class DriverWorker;
class LogBuffer;
class LogEntry;
class LogManager : public QObject
{
@ -21,6 +24,8 @@ signals:
void errorMessageChanged();
public slots:
QAbstractItemModel *appBlockedModel() const;
void setLogReadingEnabled(bool enabled);
private slots:
@ -35,11 +40,17 @@ private:
void readLogAsync(LogBuffer *logBuffer);
void cancelAsyncIo();
LogBuffer *getFreeBuffer();
void readLogEntries(LogBuffer *logBuffer);
private:
bool m_logReadingEnabled;
DriverWorker *m_driverWorker;
LogBuffer *m_logBuffer;
QList<LogBuffer *> m_freeBuffers;
AppBlockedModel *m_appBlockedModel;
QString m_errorMessage;
};

View File

@ -0,0 +1,51 @@
#include "appblockedmodel.h"
#include "../../util/fileutil.h"
#include "../../util/net/netutil.h"
#include "../../util/osutil.h"
#include "../logentryblocked.h"
#define IP_LIST_COUNT_MAX 64
AppBlockedModel::AppBlockedModel(QObject *parent) :
StringListModel(parent)
{
}
void AppBlockedModel::addLogEntry(const LogEntryBlocked &logEntry)
{
const QString appPath = getEntryPath(logEntry);
const QString ipText = NetUtil::ip4ToText(logEntry.ip());
bool isNewApp = false;
if (!m_appIpList.contains(appPath)) {
m_appIpList.insert(appPath, QStringList());
m_appIpSet.insert(appPath, QSet<QString>());
isNewApp = true;
}
QSet<QString> &ipSet = m_appIpSet[appPath];
if (ipSet.contains(ipText))
return;
ipSet.insert(ipText);
QStringList &ipList = m_appIpList[appPath];
ipList.prepend(ipText);
if (isNewApp) {
insert(appPath);
} else if (ipList.size() > IP_LIST_COUNT_MAX) {
const QString oldIpText = ipList.takeLast();
ipSet.remove(oldIpText);
}
}
QString AppBlockedModel::getEntryPath(const LogEntryBlocked &logEntry)
{
const QString kernelPath = logEntry.kernelPath();
return kernelPath.isEmpty()
? OsUtil::pidToPath(logEntry.pid())
: FileUtil::kernelPathToPath(kernelPath);
}

View File

@ -0,0 +1,32 @@
#ifndef APPBLOCKEDMODEL_H
#define APPBLOCKEDMODEL_H
#include <QHash>
#include <QSet>
#include "stringlistmodel.h"
class LogEntryBlocked;
class AppBlockedModel : public StringListModel
{
Q_OBJECT
public:
explicit AppBlockedModel(QObject *parent = nullptr);
void addLogEntry(const LogEntryBlocked &logEntry);
signals:
public slots:
private:
static QString getEntryPath(const LogEntryBlocked &logEntry);
private:
QHash<QString, QStringList> m_appIpList;
QHash<QString, QSet<QString>> m_appIpSet;
};
#endif // APPBLOCKEDMODEL_H

View File

@ -0,0 +1,55 @@
#include "stringlistmodel.h"
StringListModel::StringListModel(QObject *parent) :
QAbstractListModel(parent)
{
}
int StringListModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_list.size();
}
QVariant StringListModel::data(const QModelIndex &index, int role) const
{
if (role == Qt::DisplayRole && index.isValid()) {
return m_list.at(index.row());
}
return QVariant();
}
void StringListModel::insert(const QString &text, int row)
{
row = adjustRow(row);
beginInsertRows(QModelIndex(), row, row);
m_list.insert(row, text);
endInsertRows();
}
void StringListModel::remove(int row)
{
row = adjustRow(row);
beginRemoveRows(QModelIndex(), row, row);
m_list.removeAt(row);
endRemoveRows();
}
void StringListModel::replace(const QString &text, int row)
{
row = adjustRow(row);
m_list.replace(row, text);
const QModelIndex modelIndex = index(row);
dataChanged(modelIndex, modelIndex);
}
int StringListModel::adjustRow(int row) const
{
return (row < 0) ? (m_list.size() + 1 + row) : row;
}

View File

@ -0,0 +1,33 @@
#ifndef STRINGLISTMODEL_H
#define STRINGLISTMODEL_H
#include <QAbstractListModel>
#include <QStringList>
class StringListModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit StringListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
protected:
void insert(const QString &text, int row = -1);
void remove(int row = -1);
void replace(const QString &text, int row = -1);
signals:
public slots:
private:
int adjustRow(int row) const;
private:
QStringList m_list;
};
#endif // STRINGLISTMODEL_H