Skip to main content
Mole analyzing frames

Frame Types

Complete reference of all frame types in the Muti Metroo protocol.

Frame Header

All frames share a common 14-byte header:

FieldSizeDescription
Type1 byteFrame type (see below)
Flags1 byteFrame flags
Length4 bytesPayload length (big-endian)
StreamID8 bytesStream identifier (big-endian)

Stream Frames

STREAM_OPEN (0x01)

Open a new virtual stream.

Payload:

  • Request ID (8 bytes)
  • Address type (1 byte): 0x01 = IPv4, 0x03 = domain, 0x04 = IPv6
  • Address (4 bytes for IPv4, 16 for IPv6, or 1-byte length + domain string)
  • Destination port (2 bytes)
  • TTL (1 byte)
  • Path length (1 byte)
  • Remaining path (N * 16 bytes, where N is path length)
  • Ephemeral public key (32 bytes): X25519 key for E2E encryption

Sent by: Ingress agent Received by: Exit agent (after routing)

The ephemeral public key is used to establish end-to-end encryption. Transit agents forward this key unchanged.

STREAM_OPEN_ACK (0x02)

Acknowledge successful stream open.

Payload:

  • Request ID (8 bytes)
  • Bound address type (1 byte)
  • Bound address (4 or 16 bytes)
  • Bound port (2 bytes)
  • Ephemeral public key (32 bytes): Exit's X25519 key for E2E encryption

Sent by: Exit agent Received by: Ingress agent

The ephemeral public key allows the ingress agent to compute the same shared secret via ECDH.

STREAM_OPEN_ERR (0x03)

Stream open failed.

Payload:

  • Request ID (8 bytes)
  • Error code (2 bytes, big-endian)
  • Message length (1 byte)
  • Error message (variable length, max 255 chars)

Sent by: Exit agent or transit agent Received by: Ingress agent

STREAM_DATA (0x04)

Stream data payload.

Payload: Encrypted data (max 16 KB)

The payload is encrypted with ChaCha20-Poly1305:

  • Nonce (12 bytes): Counter + direction bit
  • Ciphertext (variable): Encrypted application data
  • Auth tag (16 bytes): Poly1305 authentication

Encryption overhead: 28 bytes per frame

Flags:

  • FIN_WRITE (0x01): Sender half-close (no more writes)
  • FIN_READ (0x02): Receiver half-close (no more reads)

Sent by: Ingress or exit agent Received by: Exit or ingress agent

Transit agents forward encrypted payloads unchanged without decryption.

STREAM_CLOSE (0x05)

Graceful stream close.

Payload: Empty

Sent by: Any agent Received by: Any agent

STREAM_RESET (0x06)

Abort stream with error.

Payload:

  • Error code (2 bytes, big-endian)

Sent by: Any agent Received by: Any agent

Routing Frames

ROUTE_ADVERTISE (0x10)

Advertise CIDR routes.

Payload:

  • Origin agent ID (16 bytes)
  • Display name length (1 byte) + display name (variable)
  • Sequence number (8 bytes)
  • Route count (1 byte)
  • For each route:
    • Address family (1 byte): 0x01 = IPv4, 0x02 = IPv6
    • Prefix length (1 byte)
    • Prefix (4 or 16 bytes)
    • Metric (2 bytes, big-endian)
  • Path length (1 byte) + path agent IDs (N * 16 bytes)
  • SeenBy length (1 byte) + seen agent IDs (N * 16 bytes)

Sent by: Exit agents and transit agents Received by: All connected peers

ROUTE_WITHDRAW (0x11)

Withdraw CIDR routes.

Payload:

  • Origin agent ID (16 bytes)
  • Sequence number (8 bytes)
  • Route count (1 byte)
  • For each route:
    • Address family (1 byte)
    • Prefix length (1 byte)
    • Prefix (4 or 16 bytes)
    • Metric (2 bytes)
  • SeenBy length (1 byte) + seen agent IDs (N * 16 bytes)

Sent by: Exit agents and transit agents Received by: All connected peers

NODE_INFO_ADVERTISE (0x12)

Advertise node metadata.

Payload:

  • Origin agent ID (16 bytes)
  • Sequence number (8 bytes)
  • Display name length (1 byte) + display name
  • Hostname length (1 byte) + hostname
  • OS length (1 byte) + OS
  • Arch length (1 byte) + architecture
  • Version length (1 byte) + version
  • Start time (8 bytes, Unix timestamp)
  • IP count (1 byte) + IP addresses (each: length + string)
  • SeenBy length (1 byte) + seen agent IDs (N * 16 bytes)
  • Peer count (1 byte) + peer connection info (each: 16 + 1+transport + 8 + 1)
  • Public key (32 bytes): Agent's long-term X25519 public key

Sent by: All agents periodically Received by: All connected peers

The public key enables identity verification and potential future features like signed route advertisements.

Control Frames

PEER_HELLO (0x20)

Handshake initiation.

Payload:

  • Protocol version (2 bytes, big-endian)
  • Agent ID (16 bytes)
  • Timestamp (8 bytes, Unix nanoseconds)
  • Display name length (1 byte) + display name
  • Capabilities count (1 byte) + capabilities (each: length + string)

Sent by: Connecting peer Received by: Listening peer

PEER_HELLO_ACK (0x21)

Handshake acknowledgment.

Payload: Same as PEER_HELLO

Sent by: Listening peer Received by: Connecting peer

KEEPALIVE (0x22)

Connection keepalive.

Payload:

  • Timestamp (8 bytes, Unix nanoseconds)

Sent by: Both peers when idle Received by: Both peers

KEEPALIVE_ACK (0x23)

Keepalive acknowledgment.

Payload:

  • Timestamp (8 bytes, echoed from KEEPALIVE)

Sent by: In response to KEEPALIVE Received by: Peer that sent KEEPALIVE

CONTROL_REQUEST (0x24)

Request metrics/status from remote agent.

Payload:

  • Request ID (8 bytes)
  • Control type (1 byte):
    • 0x01 = Metrics
    • 0x02 = Status
    • 0x03 = Peers
    • 0x04 = Routes
    • 0x05 = RPC
  • Target agent ID (16 bytes)
  • Path length (1 byte) + path agent IDs (N * 16 bytes)
  • Data length (4 bytes) + request data (variable)

Sent by: Any agent Received by: Target agent

CONTROL_RESPONSE (0x25)

Response with metrics/status data.

Payload:

  • Request ID (8 bytes)
  • Control type (1 byte)
  • Success (1 byte, 0 or 1)
  • Data length (2 bytes) + response data (variable)

Sent by: Target agent Received by: Requesting agent

Frame Flags

FlagValueDescription
FIN_WRITE0x01Sender half-close (no more writes)
FIN_READ0x02Receiver half-close (no more reads)

Error Codes

Used in STREAM_OPEN_ERR and STREAM_RESET frames:

CodeNameDescription
1NO_ROUTENo route to destination
2CONNECTION_REFUSEDConnection refused by target
3CONNECTION_TIMEOUTConnection attempt timed out
4TTL_EXCEEDEDTTL reached zero before reaching exit
5HOST_UNREACHABLEHost unreachable
6NETWORK_UNREACHABLENetwork unreachable
7DNS_ERRORDNS resolution failed
8EXIT_DISABLEDExit handler not enabled
9RESOURCE_LIMITResource limit exceeded
10CONNECTION_LIMITConnection limit exceeded
11NOT_ALLOWEDConnection not allowed by policy
12FILE_TRANSFER_DENIEDFile transfer denied
13AUTH_REQUIREDAuthentication required
14PATH_NOT_ALLOWEDPath not in allowed list
15FILE_TOO_LARGEFile exceeds size limit
16FILE_NOT_FOUNDFile not found
17WRITE_FAILEDWrite operation failed
18GENERAL_FAILUREGeneral error (e.g., key exchange failure)