> 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/agent-plugin/tunnels.md).

# Tunnels

Tunnels allow proxying network traffic through an agent. SOCKS4/5, Local Port Forward, and Reverse Port Forward are supported.

### Tunnel Types

<table><thead><tr><th width="244">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>TUNNEL_TYPE_SOCKS4</code></td><td>SOCKS4 proxy</td></tr><tr><td><code>TUNNEL_TYPE_SOCKS5</code></td><td>SOCKS5 proxy</td></tr><tr><td><code>TUNNEL_TYPE_SOCKS5_AUTH</code></td><td>SOCKS5 proxy with authentication</td></tr><tr><td><code>TUNNEL_TYPE_LOCAL_PORT</code></td><td>Local port forward (Server → Agent → Target)</td></tr><tr><td><code>TUNNEL_TYPE_REVERSE</code></td><td>Reverse port forward (Agent → Server → Target)</td></tr></tbody></table>

### Flow (SOCKS/Local Port Forward)

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

```
┌──────────────────────────────────────────────────────────────────────────────────┐
│                          TUNNEL FLOW (SOCKS/LPORTFWD)                            │
├──────────────────────────────────────────────────────────────────────────────────┤
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          CREATE TUNNEL                                     ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  GUI ──> POST /tunnel/start/socks5 (socks5 start 127.0.0.1:1080)                 │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ TEAMSERVER                                                                  │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  TsTunnelCreateSocks5(AgentId, Info, Lhost, Lport, ...)                     │ │
│  │         │                                                                   │ │
│  │         ├──> Create Tunnel object with agent Callbacks                       │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  TsTunnelStart(TunnelId)                                                    │ │
│  │         │                                                                   │ │
│  │         └──> net.Listen("tcp", "127.0.0.1:1080")                            │ │
│  │              Start Accept() goroutine for incoming connections             │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          CLIENT CONNECTION                                 ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  Browser/App ──> TCP connect to 127.0.0.1:1080                                   │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ TEAMSERVER (TunnelManager)                                                  │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  handleTunChannelCreate()                                                   │ │
│  │         │                                                                   │ │
│  │         ├──> Generate unique channelId                                      │ │
│  │         ├──> proxy.CheckSocks5() ←── Parse SOCKS handshake                  │ │
│  │         ├──> Create TunnelChannel with Pipes                                │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ EXTENDER (Agent Plugin)                                               │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  TunnelCallbacks.ConnectTCP(channelId, host, port)                    │  │ │
│  │  │         │                                                             │  │ │
│  │  │         └──> return TaskData (added to agent queue)                   │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          AGENT RESPONSE                                    ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  Agent ──> COMMAND_TUNNEL_OPEN / COMMAND_TUNNEL_CLOSE                            │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ EXTENDER (Agent Plugin - ProcessTasksResult)                                │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ TEAMSERVER                                                            │  │ │
│  │  │         │                                                             │  │ │
│  │  │         ├──> Success: TsTunnelConnectionResume(channelId)             │  │ │
│  │  │         │         └──> proxy.ReplySocks5Status(SUCCESS)               │  │ │
│  │  │         │              Start relay goroutines                         │  │ │
│  │  │         │                                                             │  │ │
│  │  │         └──> Failed: TsTunnelConnectionHalt(channelId, errorCode)     │  │ │
│  │  │                   └──> proxy.ReplySocks5Status(ERROR)                 │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          DATA FLOW (bidirectional)                         ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  Browser ──write──> Socket ──> pwSrv ──> prSrv ──read──>                         │
│         ──> TunnelCallbacks.WriteTCP(channelId, data)                            │
│                 ──> TaskData ──> Agent ──> Target                                │
│                                                                                  │
│  Target ──> Agent ──> TsTunnelConnectionData(channelId, data)                    │
│         ──> pwTun ──> prTun ──read──> Socket ──write──> Browser                  │
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          CONNECTION CLOSE                                  ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  Browser closes ──> TunnelCallbacks.Close(channelId) ──> TaskData ──> Agent      │
│  Agent closes   ──> TsTunnelConnectionClose(channelId, write) ──> Close Socket   │
│                                                                                  │
└──────────────────────────────────────────────────────────────────────────────────┘
```

### Flow Reverse Port Forward

<figure><img src="/files/2pt1Pl285g7gUkVny20H" alt=""><figcaption></figcaption></figure>

```
┌──────────────────────────────────────────────────────────────────────────────────┐
│                          REVERSE PORT FORWARD FLOW                               │
├──────────────────────────────────────────────────────────────────────────────────┤
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          CREATE RPORTFWD                                   ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  GUI ──> POST /tunnel/start/rportfwd (rportfwd 8080 127.0.0.1:80)                │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ TEAMSERVER                                                                  │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  TsTunnelCreateRportfwd(AgentId, Info, 8080, "127.0.0.1", 80)               │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ EXTENDER (Agent Plugin)                                               │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  TunnelCallbacks.Reverse(tunnelId, 8080)                              │  │ │
│  │  │         │                                                             │  │ │
│  │  │         └──> return TaskData ──> Agent listens on port 8080           │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          REMOTE CLIENT CONNECTION                          ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  Remote Client ──> TCP connect to Agent:8080                                     │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ EXTENDER (Agent Plugin - ProcessTasksResult)                                │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  Agent sends COMMAND_TUNNEL_OPEN(tunnelId, channelId)                       │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ TEAMSERVER                                                            │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  TsTunnelConnectionAccept(tunnelId, channelId)                        │  │ │
│  │  │         │                                                             │  │ │
│  │  │         └──> net.Dial("tcp", "127.0.0.1:80")                          │  │ │
│  │  │              Relay: Agent:8080 ←→ Server ←→ 127.0.0.1:80              │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
└──────────────────────────────────────────────────────────────────────────────────┘
```

### Teamserver API for Tunnel

```go
type Teamserver interface {
    // Create tunnel
    TsTunnelCreate(AgentId string, Type int, Info string, Lhost string, Lport int, Client string, Thost string, Tport int, AuthUser string, AuthPass string) (string, error)
    TsTunnelCreateSocks4(AgentId string, Info string, Lhost string, Lport int) (string, error)
    TsTunnelCreateSocks5(AgentId string, Info string, Lhost string, Lport int, UseAuth bool, Username string, Password string) (string, error)
    TsTunnelCreateLportfwd(AgentId string, Info string, Lhost string, Lport int, Thost string, Tport int) (string, error)
    TsTunnelCreateRportfwd(AgentId string, Info string, Lport int, Thost string, Tport int) (string, error)
    
    // Start/stop
    TsTunnelStart(TunnelId string) (string, error)
    TsTunnelStop(TunnelId string) error
    TsTunnelStopSocks(AgentId string, Port int)
    TsTunnelStopLportfwd(AgentId string, Port int)
    TsTunnelStopRportfwd(AgentId string, Port int)
    
    // Connection management
    TsTunnelChannelExists(channelId int) bool
    TsTunnelGetPipe(AgentId string, channelId int) (*io.PipeReader, *io.PipeWriter, error)
    TsTunnelConnectionData(channelId int, data []byte)
    TsTunnelConnectionResume(AgentId string, channelId int, ioDirect bool)
    TsTunnelConnectionClose(channelId int, writeOnly bool)
    TsTunnelConnectionHalt(channelId int, errorCode byte)
    TsTunnelConnectionAccept(tunnelId int, channelId int)
    TsTunnelPause(channelId int)
    TsTunnelResume(channelId int)

    // Update Reverse Port Forward
    TsTunnelUpdateRportfwd(tunnelId int, result bool) (string, string, error)
}
```
