-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
lex edited this page May 28, 2026
·
1 revision
Ocular is a Rust workspace with five crates, each with a focused responsibility.
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)
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), } }
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:
- Open a PCAP session on the specified interface (e.g.
lo0,en0) - Set a BPF filter for the target port (e.g.
tcp port 6379) - 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
- Protocol-specific handshake detection (e.g. MySQL auth) to skip non-data packets
Platform differences:
- macOS: uses
/dev/bpf*devices, needschmod g+ror sudo - Linux: uses
AF_PACKETsocket, needscap_net_rawcapability
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
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.
Async TCP proxy using tokio. Handles:
- Accepting client connections
- Bidirectional byte streaming between client and upstream
- Event broadcasting via
tokio::sync::broadcastchannels - 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
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)
┌─────────────────┐
│ 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) │
└───────────────────┘ └──────────────────┘