The engine package provides the core attack orchestration system for Miku Miku Beam. It coordinates attack workers, manages concurrent execution, and handles real-time statistics reporting.
Package Overview
import "github.com/sammwyy/mikumikubeam/internal/engine"
The engine package consists of three main components:
- Engine: Orchestrates attack lifecycles and worker coordination
- Registry: Maps attack types to their worker implementations
- AttackWorker Interface: Contract for implementing attack methods
Core Types
AttackKind
Enumerates supported attack types.
Constants:
AttackParams
type AttackParams struct {
Target string
TargetNode targetpkg.Node
Duration time.Duration
PacketDelay time.Duration
PacketSize int
Method AttackKind
Threads int
Verbose bool
}
Common parameters passed to all attack workers.
Proxy
type Proxy struct {
Username string
Password string
Protocol string
Host string
Port int
}
Represents a network proxy for routing attacks.
AttackStats
type AttackStats struct {
Timestamp time.Time
PacketsPerS int64
TotalPackets int64
Proxies int
Log string
}
Live statistics reported by the engine and workers.
When this stat was recorded
Packets sent in the last second
Cumulative packets sent since attack start
Optional log message (e.g., “Miku miku beam from 1.2.3.4:8080 to target.com”)
Engine
type Engine struct {
// contains filtered or unexported fields
}
Coordinates attack lifecycles, manages concurrent workers, and aggregates statistics.
NewEngine
func NewEngine(reg Registry) *Engine
Creates a new Engine with the given worker registry.
Example:
registry := engine.NewRegistry()
registry.Register(engine.AttackHTTPFlood, http.NewFloodWorker())
registry.Register(engine.AttackTCPFlood, tcp.NewFloodWorker())
eng := engine.NewEngine(*registry)
Start
func (e *Engine) Start(
attackID string,
parent context.Context,
params AttackParams,
proxies []Proxy,
userAgents []string,
) (<-chan AttackStats, error)
Launches a new attack with the given ID. If an attack with the same ID is already running, it will be stopped first.
Parameters:
Returns:
Channel that receives statistics updates every second
Error if attack could not be started (always nil in current implementation)
Behavior:
- Creates
params.Threads concurrent worker goroutines (defaults to runtime.NumCPU())
- Each thread fires at intervals defined by
params.PacketDelay
- Randomly selects a proxy and user agent for each packet
- Aggregates statistics and sends updates every 1 second
- Automatically stops after
params.Duration elapses
- Closes the stats channel when the attack ends
Example:
ctx := context.Background()
params := engine.AttackParams{
Target: "https://example.com",
TargetNode: targetNode,
Duration: 30 * time.Second,
PacketDelay: 10 * time.Millisecond,
Method: engine.AttackHTTPFlood,
Threads: 8,
Verbose: true,
}
statsCh, err := eng.Start("attack-1", ctx, params, proxies, userAgents)
if err != nil {
log.Fatal(err)
}
for stat := range statsCh {
fmt.Printf("PPS: %d, Total: %d\n", stat.PacketsPerS, stat.TotalPackets)
if stat.Log != "" {
fmt.Println(stat.Log)
}
}
Stop
func (e *Engine) Stop(attackID string)
Cancels a specific attack by ID. Safe to call if attack doesn’t exist.
Example:
StopAll
func (e *Engine) StopAll()
Cancels all running attacks.
IsRunning
func (e *Engine) IsRunning(attackID string) bool
Checks if a specific attack is currently running.
GetRunningAttacks
func (e *Engine) GetRunningAttacks() []string
Returns a list of all running attack IDs.
Registry
type Registry struct {
// contains filtered or unexported fields
}
Maps AttackKind values to their worker implementations.
NewRegistry
func NewRegistry() *Registry
Creates an empty worker registry.
Register
func (r *Registry) Register(kind AttackKind, w AttackWorker)
Registers a worker implementation for an attack kind.
Example:
registry := engine.NewRegistry()
registry.Register(engine.AttackHTTPFlood, http.NewFloodWorker())
registry.Register(engine.AttackHTTPBypass, http.NewBypassWorker())
registry.Register(engine.AttackHTTPSlowloris, http.NewSlowlorisWorker())
registry.Register(engine.AttackTCPFlood, tcp.NewFloodWorker())
registry.Register(engine.AttackMinecraftPing, game.NewPingWorker())
Get
func (r *Registry) Get(kind AttackKind) (AttackWorker, bool)
Retrieves the worker for a given attack kind. Returns false if not registered.
ListKinds
func (r *Registry) ListKinds() []AttackKind
Returns all registered attack kinds.
Logging Helpers
SendAttackLog
func SendAttackLog(logCh chan<- AttackStats, proxy Proxy, target string)
Sends a standardized attack log message to the stats channel. Non-blocking - safe to call on closed channels.
Log Format:
Miku miku beam from <source> to <target>
Where <source> is either the proxy address or <local> if no proxy is used.
SendAttackLogIfVerbose
func SendAttackLogIfVerbose(
logCh chan<- AttackStats,
proxy Proxy,
target string,
verbose bool,
)
Conditionally sends a log only if verbose is true. Used by workers to respect the AttackParams.Verbose flag.
Example (from worker implementation):
func (w *worker) Fire(ctx context.Context, params core.AttackParams, proxy core.Proxy, userAgent string, logCh chan<- core.AttackStats) error {
// ... perform attack ...
// Send log only if verbose enabled
core.SendAttackLogIfVerbose(logCh, proxy, params.Target, params.Verbose)
return nil
}
Architecture
Concurrency Model
- Thread Pool: Engine spawns
N worker threads (configured via AttackParams.Threads)
- Per-Thread Ticker: Each thread fires at
PacketDelay intervals
- Fire-and-Forget: Worker
Fire() calls are dispatched in goroutines to avoid blocking
- Statistics Aggregation: A dedicated goroutine collects and sends stats every second
Attack Lifecycle
See Also