Skip to content

Navigation Menu

Sign in
Sign up

Architecture

lex edited this page May 28, 2026 · 1 revision

Architecture

Ocular is a Rust workspace with five crates, each with a focused responsibility.


Crate Overview

crates/
├── ocular/ # Binary entry point, CLI parsing, config loading
├── ocular-capture/ # Passive packet capture (libpcap, TCP reassembly)
├── ocular-protocol/ # Wire protocol parsers (RESP, MySQL, PG, AMQP, etc.)
├── ocular-proxy/ # Async TCP proxy with event broadcasting
└── ocular-tui/ # Terminal UI (ratatui)

ocular (Binary)

The main entry point. Handles:

  • CLI argument parsing (cli.rs)
  • Config file loading and validation (main.rs)
  • Interactive setup wizard (wizard.rs)
  • Demo mode with simulated traffic (demo.rs)
  • Dispatching to TUI or CLI mode based on subcommand
// Simplified flow
fn main() {
 let cli = Cli::parse();
 match cli.subcommand {
 Some(Cmd::Proxy(args)) => run_cli_proxy(args),
 Some(Cmd::Capture(args)) => run_cli_capture(args),
 Some(Cmd::Setup) => run_wizard(),
 None => run_tui(config),
 }
}

ocular-capture

Passive packet capture using libpcap. This is the most complex crate from a systems perspective.

Key components:

  • lib.rs — PCAP session management, BPF filter setup, packet dispatch loop
  • stream.rs — TCP stream reassembly with per-connection 4-tuple tracking

How capture works:

  1. Open a PCAP session on the specified interface (e.g. lo0, en0)
  2. Set a BPF filter for the target port (e.g. tcp port 6379)
  3. For each captured packet:
    • Track TCP connections by (src_ip, src_port, dst_ip, dst_port)
    • Reassemble TCP streams from potentially fragmented packets
    • Buffer incomplete responses across TCP segments
    • Hand reassembled data to the protocol parser
  4. Protocol-specific handshake detection (e.g. MySQL auth) to skip non-data packets

Platform differences:

  • macOS: uses /dev/bpf* devices, needs chmod g+r or sudo
  • Linux: uses AF_PACKET socket, needs cap_net_raw capability

ocular-protocol

Pure protocol parsers with no I/O dependencies. Each protocol is a standalone module:

ocular-protocol/src/
├── lib.rs # Protocol enum, from_str, get_handler dispatch
├── handler.rs # ProtocolHandler trait definition
├── handlers.rs # Trait implementations for all protocols
├── resp.rs # Redis RESP parser
├── mysql.rs # MySQL wire protocol
├── postgres.rs # PostgreSQL wire protocol
├── amqp.rs # RabbitMQ AMQP 0-9-1
├── mongodb.rs # MongoDB OP_MSG
├── memcached.rs # Memcached text protocol
├── kafka.rs # Kafka binary protocol
└── http.rs # HTTP/1.x

ProtocolHandler Trait

pub trait ProtocolHandler: Send + Sync {
 fn parse_request(&self, buf: &[u8]) -> Option<String>;
 fn parse_response(&self, buf: &[u8]) -> Option<String>;
 fn format_response_detail(&self, buf: &[u8]) -> Option<String>;
 fn extract_full_command(&self, buf: &[u8]) -> Option<String>;
 // Optional: for protocols needing multi-packet buffering
 fn needs_request_buffering(&self) -> bool { false }
 fn needs_response_buffering(&self) -> bool { false }
 fn request_complete(&self, buf: &[u8]) -> bool { true }
 fn response_complete(&self, buf: &[u8]) -> bool { true }
 // Optional: for capture mode
 fn capture_handshake(&self, buf: &[u8]) -> Option<HandshakeAction>;
 fn message_length(&self, buf: &[u8]) -> Option<usize>;
 fn default_port(&self) -> u16;
}

Adding a new protocol = implementing this trait. See Adding a New Protocol.


ocular-proxy

Async TCP proxy using tokio. Handles:

  • Accepting client connections
  • Bidirectional byte streaming between client and upstream
  • Event broadcasting via tokio::sync::broadcast channels
  • SSL stripping for MySQL (intercepts SSL upgrade request)
  • Request/response buffering for protocols that need it (HTTP, MySQL ResultSet)

Event flow:

Client → Proxy → Upstream
 │
 ├─ parse_request(buf) → ProxyEvent { command, timestamp }
 │
Upstream → Proxy → Client
 │
 ├─ parse_response(buf) → ProxyEvent { response, latency }
 │
 └─ broadcast(event) → TUI / CLI / EventLog

ocular-tui

Terminal UI built on ratatui + crossterm. The largest crate by lines of code (~167K in lib.rs).

Panels:

  • Dashboard — proxy group selector (landing page)
  • Component pane — list of proxies, fuzzy search, CRUD operations
  • Event pane — scrollable event stream with syntax highlighting
  • Detail pane — full payload for selected event

Features:

  • Vim-style navigation (j/k, gg, G, Ngg)
  • Visual selection mode (v → j/k → y to copy)
  • Leader menu (Space + action)
  • Fuzzy filtering (/ to search)
  • Hot-reload config changes
  • Theme support (5 built-in themes)
  • Status indicators (capture active, traffic flowing)

Data Flow Summary

 ┌─────────────────┐
 │ ocular (bin) │
 │ CLI / Config │
 └────────┬────────┘
 │
 ┌──────────────┴──────────────┐
 │ │
 ┌─────────▼──────────┐ ┌──────────▼──────────┐
 │ ocular-proxy │ │ ocular-capture │
 │ (TCP proxy mode) │ │ (libpcap mode) │
 └─────────┬──────────┘ └──────────┬──────────┘
 │ │
 │ raw bytes │ reassembled bytes
 ▼ ▼
 ┌─────────────────────────────────────────────┐
 │ ocular-protocol │
 │ parse_request / parse_response │
 └─────────────────────┬───────────────────────┘
 │
 │ ProxyEvent
 ▼
 ┌───────────────────────┐
 │ │
 ┌─────────▼─────────┐ ┌────────▼─────────┐
 │ ocular-tui │ │ CLI output │
 │ (dashboard) │ │ (JSON/raw) │
 └───────────────────┘ └──────────────────┘

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /