> For the complete documentation index, see [llms.txt](https://adaptix-framework.gitbook.io/adaptix-framework/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://adaptix-framework.gitbook.io/adaptix-framework/development/extenders/listener-extender.md).

# Listener extender

External Listener accepts connections from agents directly over the network (HTTP/HTTPS, DNS, etc.).

### Flow Diagram

<figure><img src="/files/MlfJ5cqYYzPWiI9Xv4kS" alt=""><figcaption></figcaption></figure>

```
┌──────────────────────────────────────────────────────────────────────────────────┐
│                          EXTERNAL LISTENER FLOW                                  │
├──────────────────────────────────────────────────────────────────────────────────┤
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          CREATE LISTENER                                   ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  GUI ──> POST /listener/create                                                   │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ TEAMSERVER                                                                  │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  TsListenerCreate(listenerType, name, config)                               │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ EXTENDER                                                              │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  PluginListener.Create(name, config, customData)                      │  │ │
│  │  │         │                                                             │  │ │
│  │  │         ├──> Configuration validation                                 │  │ │
│  │  │         └──> return ExtenderListener, ListenerData, customData        │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │         │                                                                   │ │
│  │         └──> Save to DBMS, broadcast to clients                             │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          START LISTENER                                    ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  (automatically after Create)                                                    │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ TEAMSERVER                                                                  │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  TsListenerStart(listenerName)                                              │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ EXTENDER                                                              │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  ExtenderListener.Start()                                             │  │ │
│  │  │         │                                                             │  │ │
│  │  │         └──> Start HTTP/DNS server                                    │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          AGENT CONNECTION                                  ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  Agent ──> [HTTP] Request to Listener                                            │
│                       │                                                          │
│                       V                                                          │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ EXTENDER ([HTTP] Handler)                                                   │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  [processRequest(ctx)]                                                      │ │
│  │         │                                                                   │ │
│  │         ├──> Extract AgentID and data                                       │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ TEAMSERVER API calls                                                  │  │ │
│  │  │         │                                                             │  │ │
│  │  │         ├──> if !TsAgentIsExists(agentId):                            │  │ │
│  │  │         │       TsAgentCreate(agentCrc, agentId, data, listener, IP)  │  │ │
│  │  │         │                                                             │  │ │
│  │  │         ├──> TsAgentSetTick(agentId, listener) - last tick update     │  │ │
│  │  │         │                                                             │  │ │
│  │  │         ├──> TsAgentProcessData(agentId, bodyData) - process data     │  │ │
│  │  │         │                                                             │  │ │
│  │  │         └──> TsAgentGetHostedAll(agentId, maxSize) - send tasks       │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │         │                                                                   │ │
│  │         └──> return [HTTP] response to agent                                │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          STOP LISTENER                                     ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  GUI ──> POST /listener/stop                                                     │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ TEAMSERVER                                                                  │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  TsListenerStop(listenerName)                                               │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ EXTENDER                                                              │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  ExtenderListener.Stop()                                              │  │ │
│  │  │         │                                                             │  │ │
│  │  │         └──> Stop server, cleanup resources                           │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
└──────────────────────────────────────────────────────────────────────────────────┘
```

***

### Listener Config (config.yaml)

```yaml
extender_type: "listener"
extender_file: "listener.so"
ax_file: "ax_config.axs"

listener_name: "LISTENER_NAME"
listener_type: "external"   # or "internal"
protocol: "protocol here"
```

### PluginListener Interface

```go
type PluginListener interface {
    // Create listener
    Create(name string, config string, customData []byte) (ExtenderListener, ListenerData, []byte, error)
}

// ExtenderListener - active listener interface
type ExtenderListener interface {
    // Start listener
    Start() error
    
    // Edit configuration
    Edit(config string) (ListenerData, []byte, error)
    
    // Stop listener
    Stop() error
    
    // Get profile for agent generation
    GetProfile() ([]byte, error)
    
    // Handle pivot connections (for internal listener)
    InternalHandler(data []byte) (string, error)
}
```

### AxScript for Listener (ax\_config.axs)

The `.axs` file defines the UI for creating/editing listeners in the GUI.

**Required function:**

```javascript
function ListenerUI(mode_create) {
    // mode_create: true = create, false = edit
    
    // Create UI elements
    let labelHost = form.create_label("Host:");
    let comboHost = form.create_combo();
    comboHost.setEnabled(mode_create);  // Non-editable fields when editing
    
    let spinPort = form.create_spin();
    spinPort.setRange(1, 65535);
    spinPort.setValue(443);
    
    // Layout
    let layout = form.create_gridlayout();
    layout.addWidget(labelHost, 0, 0, 1, 1);
    layout.addWidget(comboHost, 0, 1, 1, 1);
    
    // Container for retrieving values
    let container = form.create_container();
    container.put("host_bind", comboHost);
    container.put("port_bind", spinPort);
    
    let panel = form.create_panel();
    panel.setLayout(layout);
    
    // Required return
    return {
        ui_panel: panel,        // Panel with UI
        ui_container: container, // Container for retrieving values
        ui_height: 400,         // Dialog height
        ui_width: 500           // Dialog width
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://adaptix-framework.gitbook.io/adaptix-framework/development/extenders/listener-extender.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
