Skip to content

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 the Host: 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;
}
3. Aegis loads these libraries at startup using dlopen/dlsym (on Linux) or LoadLibrary/GetProcAddress (on Windows). Analyzer instances are registered in a flat vector inside the Worker core.