Plugin API Specification: Aegis
Aegis is designed to support custom protocol classification filters via a modular interface. This document describes the IProtocolAnalyzer interface and registration rules.
1. The IProtocolAnalyzer Interface
All protocol decoding extensions must implement the abstract base class IProtocolAnalyzer.
#pragma once
#include <string_view>
#include <optional>
#include "types.h"
namespace Aegis {
struct AnalysisResult {
AppType app_type;
std::string_view domain; // Points into raw payload memory
bool is_final; // If true, worker will stop calling this analyzer for this flow
};
class IProtocolAnalyzer {
public:
virtual ~IProtocolAnalyzer() = default;
// Returns the unique protocol identifier name
[[nodiscard]] virtual std::string_view name() const noexcept = 0;
// Evaluates a packet frame's payload
[[nodiscard]] virtual std::optional<AnalysisResult> analyze(
const uint8_t* payload,
size_t length,
const Flow& current_flow
) noexcept = 0;
};
} // namespace Aegis
2. Default Built-in Plugins
TLSPlugin: Parses Client Hello record structures to extract the Server Name Indication (SNI) extension.HTTPPlugin: Parses text-based HTTP headers (GET, POST) to locate theHost:field.DNSPlugin: Inspects DNS query frames (port 53) to extract name request strings.
3. Dynamic Plugin Registration
To allow runtime loading without recompiling the main binary:
1. Custom plugins compile as shared object dynamic libraries (.so on Linux, .dll on Windows).
2. The dynamic library must expose an initialization hook:
extern "C" Aegis::IProtocolAnalyzer* createAnalyzer() {
return new MyCustomAnalyzer();
}
extern "C" void destroyAnalyzer(Aegis::IProtocolAnalyzer* analyzer) {
delete analyzer;
}
dlopen/dlsym (on Linux) or LoadLibrary/GetProcAddress (on Windows). Analyzer instances are registered in a flat vector inside the Worker core.