A high-performance proxy server for IEEE 2030.5 (Smart Energy Profile 2.0) communication, written in Zig. This proxy provides secure mTLS communication, connection pooling, and comprehensive logging for smart grid devices.
- mTLS Support: Full mutual TLS authentication with certificate validation
- IEEE 2030.5 Compliance: Supports standard message types (DER, metering, device control, etc.)
- High Performance:
- Zero-copy XML parsing
- Connection pooling with DNS caching
- Reference-counted async operations
- Buffer pooling for memory efficiency
- Certificate Management:
- LFDI/SFDI extraction
- Hardware identity validation
- Configurable vendor OID support
- Session caching and resumption
- Observability:
- Detailed request/response logging
- XML message type identification
- Performance metrics
- Health check endpoints
- Zig master (latest development version)
- libuv
- OpenSSL 3.x
- libxml2 (not currently required - using built-in zero-copy XML parser)
brew install libuv openssl@3
# libxml2 not currently required
# Ubuntu/Debian
apt-get install libuv1-dev libssl-dev
# libxml2-dev not currently required
# Fedora/RHEL
dnf install libuv-devel openssl-devel
# libxml2-devel not currently required
zig build
For release builds with optimizations:
zig build -Doptimize=ReleaseFast
Create a server.toml
configuration file:
[server]
listen_addr = "0.0.0.0:8443"
health_addr = "127.0.0.1:8081"
[tls]
chain_path = "certs/server-chain.pem"
key_path = "certs/server.key"
root_ca_path = "certs/ca.pem"
[upstream]
backends = [
"http://backend1:8080",
"http://backend2:8080",
]
[logging]
level = "info"
format = "text" # or "json"
detailed_logging = true
log_response_body = true
max_logged_body_size = 1048576
[health_check]
interval_seconds = 10
connection_timeout_ms = 1000
# Optional: Configure vendor-specific OIDs
[[vendors.vendor]]
name = "Acme Energy Systems"
oid = "1.3.6.1.4.1.12345"
device_type = "meter"
[[vendors.vendor]]
name = "Solar Innovations Inc"
oid = "1.3.6.1.4.1.54321"
device_type = "der_device"
The proxy supports configuring vendor-specific OIDs for device identification. Valid device types are:
der_device
- Distributed Energy Resourcemeter
- Smart Metergateway
- Communication Gatewayaggregator
- DER Aggregatorev_charger
- Electric Vehicle Chargerthermostat
- Smart Thermostatcustom
- Custom Device Type
./zig-out/bin/zig-proxy -c server.toml
The proxy expects IEEE 2030.5 compliant certificates with:
-
Standard IEEE 2030.5 policy OIDs:
- Device:
1.3.6.1.4.1.40732.1.1
- Mobile:
1.3.6.1.4.1.40732.1.2
- Post-manufacture:
1.3.6.1.4.1.40732.1.3
- Test:
1.3.6.1.4.1.40732.2.1
- Self-signed:
1.3.6.1.4.1.40732.2.2
- Service provider:
1.3.6.1.4.1.40732.2.3
- Bulk issued:
1.3.6.1.4.1.40732.2.4
- Device:
-
Or configured vendor-specific OIDs
-
Hardware identity in certificate extensions or subject DN
The proxy uses:
- libuv for async I/O and event loop
- OpenSSL for TLS and cryptography
- Zero-copy parsing for performance
- Arena allocators for request-scoped memory
- Reference counting for safe async operations
- Connection pooling for upstream efficiency
- DER (Distributed Energy Resource) messages
- Device capability and status
- Metering and usage data
- Demand response programs
- Tariff and pricing information
- Event and log messages
- File transfer
- Subscription and notification
The proxy includes several performance optimizations:
- Session cache: 20,000 entries with 1-hour timeout
- Connection pool: 300-3000 connections per upstream
- Buffer pool: Pre-allocated 8KB buffers
- Backpressure: Automatic request throttling
- Keep-alive: Connection reuse for efficiency
Health check endpoint: http://health_addr/health
Returns:
- Active connections
- Request rate
- Pool statistics
- Memory usage
src/
├── main.zig # Entry point
├── proxy.zig # Main proxy server
├── connection.zig # Connection handling
├── upstream.zig # Upstream communication
├── connection_pool.zig # Connection pooling
├── mtls/ # mTLS implementation
│ ├── tls.zig # TLS server
│ ├── certificate.zig # Certificate handling
│ └── validation.zig # Certificate validation
├── utils/ # Utilities
│ ├── uv.zig # libuv bindings
│ ├── openssl.zig # OpenSSL bindings
│ └── refcounted.zig # Reference counting
└── xml_parser.zig # XML parsing
Run tests with:
zig build test
For developing and testing, you can run simple backend servers using the included Rust implementation:
# Run multiple backend instances on different ports
nohup cargo run --release --manifest-path ieee2030-backend/Cargo.toml -- 17777 >& 17777.out &
nohup cargo run --release --manifest-path ieee2030-backend/Cargo.toml -- 18888 >& 18888.out &
nohup cargo run --release --manifest-path ieee2030-backend/Cargo.toml -- 19999 >& 19999.out &
which would mock upstream servers in:
[upstream]
backends = [
"http://127.0.0.1:18888",
"http://127.0.0.1:17777",
"http://127.0.0.1:19999",
]
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests
- Submit a pull request
This project is dual-licensed under either:
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.