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

  1. Client connects to server over TLS 1.3
  2. Authentication via token in handshake
  3. Tunnel registration with subdomain request
  4. Server assigns subdomain and confirms
  5. Data sessions established for traffic
  6. Requests forwarded through multiplexed streams

Protocol Details

Frame Types

TypeCodeDirectionPurpose
Register0x01Client→ServerRegister tunnel
RegisterAck0x02Server→ClientConfirm registration
Heartbeat0x03Client→ServerKeep-alive
HeartbeatAck0x04Server→ClientPing response
Close0x05BothClose connection
Error0x06BothError message
DataConnect0x07Client→ServerData session
DataConnectAck0x08Server→ClientConfirm 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

SettingValue
Heartbeat interval2 seconds
Heartbeat timeout6 seconds
Request timeout30 seconds
Stream open timeout10 seconds
Stream close timeout5 minutes
Reconnect base delay1 second
Reconnect max delay60 seconds

Server Endpoints

EndpointPurposeAuth Required
/healthHealth check (returns 200 OK)No
/statsServer statistics (JSON)Yes (metrics-token)
/metricsPrometheus metricsYes (metrics-token)

Prometheus Metrics

Available at /metrics endpoint:

MetricTypeDescription
drip_tunnel_countGaugeActive tunnels
drip_tunnel_registrations_totalCounterTotal registrations
drip_tunnel_registration_failures_totalCounterFailed registrations
drip_tunnels_by_ipGaugeTunnels per IP
drip_active_connectionsGaugeActive TCP connections
drip_connections_totalCounterTotal connections
drip_bytes_received_totalCounterTotal bytes in
drip_bytes_sent_totalCounterTotal bytes out
drip_requests_totalCounterTotal HTTP requests
drip_rate_limit_rejections_totalCounterRate limit rejections
drip_http_request_duration_secondsHistogramHTTP request latency

Error Codes

CodeMessage
tunnel_not_foundTunnel doesn't exist
timeoutOperation timed out
connection_failedConnection error
invalid_requestMalformed request
auth_failedAuthentication failed
rate_limitedRate limit exceeded