Overview
How Drip works internally.
High-Level Architecture
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Internet │ ──────> │ Drip Server │ <────── │ Drip Client │
│ Users │ HTTPS │ (Public) │ TLS 1.3 │ (Private) │
└─────────────┘ └──────────────┘ └─────────────┘
│ │
│ │
▼ ▼
┌──────────────┐ ┌─────────────┐
│ Wildcard │ │ Local │
│ DNS │ │ Service │
└──────────────┘ └─────────────┘Connection Flow
- Client connects to server over TLS 1.3
- Authentication via token in handshake
- Tunnel registration with subdomain request
- Server assigns subdomain and confirms
- Data sessions established for traffic
- Requests forwarded through multiplexed streams
Protocol Details
Frame Types
| Type | Code | Direction | Purpose |
|---|---|---|---|
| Register | 0x01 | Client→Server | Register tunnel |
| RegisterAck | 0x02 | Server→Client | Confirm registration |
| Heartbeat | 0x03 | Client→Server | Keep-alive |
| HeartbeatAck | 0x04 | Server→Client | Ping response |
| Close | 0x05 | Both | Close connection |
| Error | 0x06 | Both | Error message |
| DataConnect | 0x07 | Client→Server | Data session |
| DataConnectAck | 0x08 | Server→Client | Confirm data session |
Frame Structure
[4 bytes: Length (Big Endian)]
[1 byte: Frame Type]
[N bytes: Payload (msgpack/JSON)]Maximum frame size: 1 MB (1,048,576 bytes)
Message Structures
Register Request
json
{
"token": "auth-token",
"custom_subdomain": "myapp",
"tunnel_type": "http",
"local_port": 3000,
"connection_type": "primary",
"ip_access": {
"allow_ips": ["192.168.1.0/24"],
"deny_ips": ["192.168.1.100"]
}
}Register Response
json
{
"subdomain": "myapp",
"port": 0,
"url": "https://myapp.tunnel.example.com",
"message": "Tunnel registered successfully",
"tunnel_id": "abc123",
"supports_data_conn": true,
"recommended_conns": 4
}Timeouts
| Setting | Value |
|---|---|
| Heartbeat interval | 2 seconds |
| Heartbeat timeout | 6 seconds |
| Request timeout | 30 seconds |
| Stream open timeout | 10 seconds |
| Stream close timeout | 5 minutes |
| Reconnect base delay | 1 second |
| Reconnect max delay | 60 seconds |
Server Endpoints
| Endpoint | Purpose | Auth Required |
|---|---|---|
/health | Health check (returns 200 OK) | No |
/stats | Server statistics (JSON) | Yes (metrics-token) |
/metrics | Prometheus metrics | Yes (metrics-token) |
Prometheus Metrics
Available at /metrics endpoint:
| Metric | Type | Description |
|---|---|---|
drip_tunnel_count | Gauge | Active tunnels |
drip_tunnel_registrations_total | Counter | Total registrations |
drip_tunnel_registration_failures_total | Counter | Failed registrations |
drip_tunnels_by_ip | Gauge | Tunnels per IP |
drip_active_connections | Gauge | Active TCP connections |
drip_connections_total | Counter | Total connections |
drip_bytes_received_total | Counter | Total bytes in |
drip_bytes_sent_total | Counter | Total bytes out |
drip_requests_total | Counter | Total HTTP requests |
drip_rate_limit_rejections_total | Counter | Rate limit rejections |
drip_http_request_duration_seconds | Histogram | HTTP request latency |
Error Codes
| Code | Message |
|---|---|
tunnel_not_found | Tunnel doesn't exist |
timeout | Operation timed out |
connection_failed | Connection error |
invalid_request | Malformed request |
auth_failed | Authentication failed |
rate_limited | Rate limit exceeded |