Version: 1.0
Status: Production Ready
The ThemisDB Wire Protocol is a high-performance binary protocol for client-server communication. It provides efficient data serialization, TLS/mTLS security, and support for all ThemisDB operations including CRUD, transactions, queries, and real-time streaming.
- Binary Protocol: Efficient binary serialization using Protocol Buffers
- TLS/mTLS Support: Secure communication with optional mutual authentication
- Connection Pooling: Client-side connection pooling for reduced latency
- Keep-Alive: Persistent connections with automatic reconnection
- Multiplexing: Multiple concurrent operations over a single connection
- Streaming: Bidirectional streaming for large result sets and real-time data
┌─────────────────────────────────────┐
│ Application Layer (AQL, CRUD) │
├─────────────────────────────────────┤
│ Wire Protocol (Message Framing) │
├─────────────────────────────────────┤
│ TLS/mTLS (Optional) │
├─────────────────────────────────────┤
│ TCP (Connection Pooling) │
└─────────────────────────────────────┘
All wire protocol messages follow this structure:
┌──────────────┬──────────────┬─────────────────────┐
│ Magic (2B) │ Length (4B) │ Payload (Variable) │
└──────────────┴──────────────┴─────────────────────┘
- Magic Bytes (2 bytes): Protocol identifier
0xDB01(ThemisDB v1) - Length (4 bytes): Big-endian uint32, length of payload in bytes
- Payload (variable): Protocol Buffers encoded message
The wire protocol supports the following operation codes:
| Opcode | Name | Description |
|---|---|---|
| 0x01 | HANDSHAKE | Initial connection handshake and authentication |
| 0x02 | CREATE | Create a new document/entity |
| 0x03 | READ | Read document(s) by ID |
| 0x04 | UPDATE | Update existing document |
| 0x05 | DELETE | Delete document(s) |
| 0x06 | QUERY | Execute AQL query |
| 0x07 | BEGIN_TX | Begin transaction |
| 0x08 | COMMIT_TX | Commit transaction |
| 0x09 | ROLLBACK_TX | Rollback transaction |
| 0x0A | SUBSCRIBE | Subscribe to real-time updates |
| 0x0B | UNSUBSCRIBE | Unsubscribe from updates |
| 0x0C | PING | Keep-alive ping |
| 0x0D | PONG | Keep-alive response |
| 0xFF | ERROR | Error response |
Configure the wire protocol server in your themis.conf:
[wire_protocol]
enabled = true
bind_address = 0.0.0.0
port = 8766
max_connections = 1000
idle_timeout = 300To enable TLS for secure communication:
[wire_protocol]
enabled = true
bind_address = 0.0.0.0
port = 8766
# TLS Configuration
enable_tls = true
tls_cert_path = /path/to/server-cert.pem
tls_key_path = /path/to/server-key.pem
tls_min_version = TLSv1.2 # or TLSv1.3For mutual authentication where clients must also present certificates:
[wire_protocol]
enabled = true
bind_address = 0.0.0.0
port = 8766
# mTLS Configuration
enable_tls = true
enable_mtls = true
tls_cert_path = /path/to/server-cert.pem
tls_key_path = /path/to/server-key.pem
tls_ca_cert_path = /path/to/ca-cert.pem
tls_require_client_cert = trueGenerate self-signed certificates for testing:
# Generate CA certificate
openssl req -x509 -newkey rsa:4096 -keyout ca-key.pem -out ca-cert.pem -days 365 -nodes
# Generate server certificate
openssl req -newkey rsa:4096 -keyout server-key.pem -out server-req.pem -nodes
openssl x509 -req -in server-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 365
# Generate client certificate (for mTLS)
openssl req -newkey rsa:4096 -keyout client-key.pem -out client-req.pem -nodes
openssl x509 -req -in client-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 365The Wire Protocol Connection Pool provides client-side connection pooling:
#include <network/wire_protocol_connection_pool.h>
using namespace themis::network;
// Configure connection pool
WireProtocolConnectionPool::Config config;
config.min_connections_per_target = 2;
config.max_connections_per_target = 20;
config.idle_timeout = std::chrono::seconds(60);
config.connect_timeout = std::chrono::seconds(5);
// Create pool
WireProtocolConnectionPool pool(config);
// Acquire connection
auto conn = pool.acquireConnection("localhost:8766");
// Use connection for I/O via the underlying socket
auto& socket = conn.socket();
// socket.write_some(boost::asio::buffer(request_bytes));
// socket.read_some(boost::asio::buffer(response_buffer));
// Or access the wrapper directly for SSL-specific operations
if (conn.socketWrapper().is_ssl()) {
// SSL-specific logic
}
// Connection automatically returned to pool when conn goes out of scopeTo connect with TLS:
WireProtocolConnectionPool::Config config;
config.enable_ssl = true;
config.ssl_ca_cert_path = "/path/to/ca-cert.pem"; // Optional, uses system CA by default
WireProtocolConnectionPool pool(config);
auto conn = pool.acquireConnection("localhost:8766");To connect with mutual TLS:
WireProtocolConnectionPool::Config config;
config.enable_ssl = true;
config.enable_mtls = true;
config.ssl_cert_path = "/path/to/client-cert.pem";
config.ssl_key_path = "/path/to/client-key.pem";
config.ssl_ca_cert_path = "/path/to/ca-cert.pem";
WireProtocolConnectionPool pool(config);
auto conn = pool.acquireConnection("localhost:8766");After establishing a connection, clients must perform a handshake:
- Client → Server: Send HANDSHAKE message with protocol version and authentication credentials
- Server → Client: Respond with HANDSHAKE_ACK and session token
- Client: Include session token in subsequent requests
The wire protocol supports multiple authentication methods:
- Username/Password: Basic authentication with bcrypt-hashed passwords
- API Key: Bearer token authentication
- JWT: JSON Web Token authentication
- Certificate-based: mTLS certificate authentication (CN as username)
message HandshakeRequest {
string protocol_version = 1; // "1.0"
string client_name = 2; // "ThemisDB Client/1.0"
AuthMethod auth_method = 3; // USERNAME_PASSWORD, API_KEY, JWT, CERTIFICATE
string username = 4; // For USERNAME_PASSWORD
string password = 5; // For USERNAME_PASSWORD
string api_key = 6; // For API_KEY
string jwt_token = 7; // For JWT
}
message HandshakeResponse {
bool success = 1;
string session_token = 2;
string error_message = 3;
ServerInfo server_info = 4;
}Request:
message CreateRequest {
string collection = 1;
bytes document = 2; // JSON-encoded document
string session_token = 3;
}Response:
message CreateResponse {
bool success = 1;
string document_id = 2;
string error_message = 3;
}Request:
message QueryRequest {
string aql_query = 1;
map<string, bytes> bind_vars = 2; // Query parameters
string session_token = 3;
int32 batch_size = 4; // For streaming results
}Response (streaming):
message QueryResponse {
bool success = 1;
repeated bytes results = 2; // Batch of result documents
bool has_more = 3; // More results available
string cursor_id = 4; // For fetching next batch
string error_message = 5;
QueryStats stats = 6;
}- Reduced Latency: Avoid TCP 3-way handshake overhead (~1-2ms per connection)
- TLS Handshake Reuse: Avoid expensive TLS negotiation (~10-50ms)
- Memory Efficiency: Reuse connection buffers and state
- Scalability: Handle thousands of concurrent operations with fewer connections
For typical workloads:
min_connections_per_target: 2-5max_connections_per_target: 10-50 (based on concurrency)idle_timeout: 30-300 secondskeepalive_interval: 15-60 seconds
For high-throughput workloads:
min_connections_per_target: 10max_connections_per_target: 100+idle_timeout: 300+ secondskeepalive_interval: 30 seconds
- Use TLS 1.2 or higher: Disable SSLv3, TLSv1.0, TLSv1.1
- Strong Cipher Suites: Use ECDHE with AES-GCM or ChaCha20-Poly1305
- Certificate Validation: Always verify server certificates in production
- Certificate Rotation: Implement automated certificate renewal
- Client Authentication: Use mTLS for service-to-service communication
- Certificate Management: Use a proper PKI for certificate issuance
- Revocation: Implement CRL or OCSP for certificate revocation
- Short-lived Certificates: Use certificates with shorter validity periods
- Firewall Rules: Restrict wire protocol port to trusted networks
- Rate Limiting: Implement connection and request rate limits
- Monitoring: Log authentication failures and suspicious patterns
- Encryption: Always use TLS in production environments
Problem: Cannot connect to server
Solutions:
- Check server is running:
netstat -an | grep 8766 - Verify firewall rules allow connection
- Check bind address (0.0.0.0 vs 127.0.0.1)
- Review server logs for errors
Problem: SSL/TLS handshake fails
Solutions:
- Verify certificate paths are correct
- Check certificate validity:
openssl x509 -in cert.pem -text -noout - Ensure CA certificate is trusted
- Verify hostname matches certificate CN/SAN
- Check TLS version compatibility
Problem: Handshake rejected by server
Solutions:
- Verify credentials are correct
- Check authentication method is enabled on server
- For mTLS, ensure client certificate is signed by trusted CA
- Review server authentication logs
Problem: Slow connection acquisition
Solutions:
- Increase
max_connections_per_target - Enable connection warmup:
enable_warmup = true - Adjust
acquire_timeoutif needed - Monitor connection pool statistics
The complete Protocol Buffers definition is available at:
proto/themis_wire_v1.proto
- Performance Tips - Connection pooling optimization
- TLS Implementation - TLS setup verification
- Security Guide - Security best practices
- API Documentation - Higher-level API reference
- Protocol Buffers: https://protobuf.dev/
- TLS 1.3 RFC: https://tools.ietf.org/html/rfc8446
- Boost.Asio SSL: https://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/ssl__stream.html