dcrouter
dcrouter: a traffic router intended to be gating your datacenter.
A comprehensive traffic routing solution that provides unified gateway capabilities for HTTP/HTTPS, TCP/SNI, email (SMTP), and DNS protocols. Designed for enterprises requiring robust traffic management, automatic certificate provisioning, and enterprise-grade email infrastructure.
Table of Contents
- Features
- Installation
- Quick Start
- Architecture
- Configuration
- Email System
- SmartProxy Routing
- Security Features
- API Reference
- Examples
- Troubleshooting
Features
🌐 Universal Traffic Router
- HTTP/HTTPS routing with pattern matching and virtual hosts
- TCP/SNI proxy for any protocol with TLS termination/passthrough
- DNS server with authoritative and dynamic record management
- Multi-protocol support on the same infrastructure
🔒 Enterprise Security
- Automatic TLS certificates via ACME with DNS-01 challenges
- IP reputation checking and real-time threat detection
- Content scanning for spam, viruses, and malicious content
- Comprehensive security logging with correlation tracking
📧 Complete Email Infrastructure
- Multi-domain SMTP server on standard ports (25, 587, 465)
- Pattern-based email routing with three processing modes
- DKIM, SPF, DMARC authentication and verification
- Enterprise deliverability with IP warmup and reputation management
⚡ High Performance
- Connection pooling and efficient resource management
- Load balancing with automatic failover
- Rate limiting at multiple levels
- Real-time metrics and monitoring
💾 Flexible Storage System
- Multiple storage backends: filesystem, custom functions, or memory
- Unified storage interface for all components
- Automatic data migration between backends
- Persistent configuration for domains, routes, and security data
Installation
npm install @serve.zone/dcrouter --save
Prerequisites
- Node.js 18+ with ES modules support
- Valid domain with DNS control (for ACME certificates)
- Cloudflare API token (for DNS challenges)
Quick Start
Basic HTTP/HTTPS Router
import { DcRouter } from '@serve.zone/dcrouter';
const router = new DcRouter({
smartProxyConfig: {
routes: [
{
name: 'web-service',
match: { domains: ['example.com'], ports: [443] },
action: {
type: 'forward',
target: { host: '192.168.1.10', port: 8080 },
tls: { mode: 'terminate', certificate: 'auto' }
}
}
],
acme: {
email: 'admin@example.com',
enabled: true,
useProduction: true
}
}
});
await router.start();
console.log('DcRouter started successfully');
Basic Email Router
import { DcRouter } from '@serve.zone/dcrouter';
const router = new DcRouter({
emailConfig: {
ports: [25, 587, 465],
hostname: 'mail.example.com',
routes: [
{
name: 'local-mail',
match: { recipients: '*@example.com' },
action: {
type: 'process',
process: {
scan: true,
dkim: true,
queue: 'normal'
}
}
}
],
tls: {
keyPath: './certs/key.pem',
certPath: './certs/cert.pem'
}
}
});
await router.start();
Architecture
System Overview
graph TB
subgraph "External Traffic"
HTTP[HTTP/HTTPS Clients]
SMTP[SMTP Clients]
TCP[TCP Clients]
DNS[DNS Queries]
end
subgraph "DcRouter Core"
DcRouter[DcRouter Orchestrator]
SmartProxy[SmartProxy Engine]
EmailServer[Unified Email Server]
DnsServer[DNS Server]
CertManager[Certificate Manager]
end
subgraph "Backend Services"
WebServices[Web Services]
MailServers[Mail Servers]
Databases[Databases]
APIs[Internal APIs]
end
HTTP --> SmartProxy
TCP --> SmartProxy
SMTP --> EmailServer
DNS --> DnsServer
DcRouter --> SmartProxy
DcRouter --> EmailServer
DcRouter --> DnsServer
DcRouter --> CertManager
SmartProxy --> WebServices
SmartProxy --> APIs
EmailServer --> MailServers
EmailServer --> Databases
CertManager -.-> SmartProxy
CertManager -.-> EmailServer
Core Components
DcRouter Orchestrator
Central coordination engine that manages all services and provides unified configuration.
SmartProxy Engine
High-performance HTTP/HTTPS and TCP/SNI proxy with:
- Pattern-based routing
- TLS termination/passthrough
- Load balancing
- Connection pooling
Unified Email Server
Enterprise-grade SMTP server with:
- Multi-domain support
- Pattern-based routing
- Three processing modes
- Complete authentication stack
Certificate Manager
Automatic TLS certificate provisioning via ACME with DNS-01 challenges.
Configuration
Complete Configuration Interface
interface IDcRouterOptions {
// SmartProxy configuration for HTTP/HTTPS/TCP routing
smartProxyConfig?: {
routes: IRouteConfig[];
acme?: IAcmeConfig;
allowSessionTicket?: boolean;
};
// Email system configuration
emailConfig?: {
ports: number[];
hostname: string;
domains?: IEmailDomainConfig[]; // Domain infrastructure setup
routes: IEmailRoute[]; // Route-based email handling
auth?: IAuthConfig;
tls?: ITlsConfig;
maxMessageSize?: number;
rateLimits?: IRateLimitConfig;
useSocketHandler?: boolean; // Enable socket-handler mode (no port binding)
defaults?: { // Global defaults for all domains
dnsMode?: 'forward' | 'internal-dns' | 'external-dns';
dkim?: IDkimConfig;
rateLimits?: IRateLimitConfig;
};
};
// DNS server configuration
dnsServerConfig?: {
port?: number;
authoritative?: boolean;
records?: IDnsRecord[];
};
// DNS domain for automatic DNS-over-HTTPS setup
dnsDomain?: string; // e.g., 'dns.example.com'
// TLS and certificate configuration
tls?: {
contactEmail: string;
domain: string;
};
// DNS challenge configuration
dnsChallenge?: {
cloudflareApiKey: string;
};
// Storage configuration
storage?: {
fsPath?: string; // Filesystem storage path
readFunction?: (key: string) => Promise<string>; // Custom read function
writeFunction?: (key: string, value: string) => Promise<void>; // Custom write function
};
}
Route Configuration
interface IRouteConfig {
name: string;
priority?: number;
match: {
domains?: string[];
ports?: number | number[] | { from: number; to: number }[];
};
action: {
type: 'forward' | 'redirect' | 'serve';
target?: {
host: string;
port: number | 'preserve' | ((context: any) => number);
};
tls?: {
mode: 'terminate' | 'passthrough';
certificate?: 'auto' | string;
};
security?: {
ipAllowList?: string[];
ipBlockList?: string[];
};
};
}
Socket-Handler Mode
DcRouter supports an advanced socket-handler mode that eliminates internal port binding for both DNS and email services. Instead of services listening on internal ports, SmartProxy passes sockets directly to the services.
DNS Socket-Handler
When dnsDomain
is configured, DcRouter automatically:
- Sets up DNS server for UDP on port 53
- Creates SmartProxy routes for DNS-over-HTTPS (DoH) on the specified domain
- Uses socket-handler for HTTPS/DoH traffic (no HTTPS port binding)
const router = new DcRouter({
dnsDomain: 'dns.example.com', // Enables DNS with DoH
smartProxyConfig: {
// DNS routes are automatically created
}
});
This creates:
- UDP DNS service on port 53 (standard DNS queries)
- HTTPS routes for
dns.example.com/dns-query
anddns.example.com/resolve
- Automatic TLS certificates via Let's Encrypt
Email Socket-Handler
When useSocketHandler
is enabled in email config:
- Email server doesn't bind to any ports
- SmartProxy passes sockets directly to email handlers
- Reduces latency and resource usage
const router = new DcRouter({
emailConfig: {
ports: [25, 587, 465],
hostname: 'mail.example.com',
useSocketHandler: true, // Enable socket-handler mode
routes: [/* email routes */]
}
});
Benefits of Socket-Handler Mode
- Performance: Eliminates internal port forwarding overhead
- Security: No exposed internal ports
- Resource Efficiency: Fewer open ports and listeners
- Simplified Networking: Direct socket passing
- Automatic Configuration: Routes created automatically
Traditional vs Socket-Handler Mode
Traditional Mode (default):
External Port → SmartProxy → Internal Port → Service
25 → 10025 → Email
Socket-Handler Mode:
External Port → SmartProxy → Socket Handler → Service
25 → (direct socket) → Email
Email System
Email Domain Configuration
DcRouter separates email infrastructure (which domains to handle) from routing logic (how to handle emails):
DNS Modes
Forward Mode - Simple mail forwarding without local DNS:
{
domain: 'forwarded.com',
dnsMode: 'forward',
dns: {
forward: {
skipDnsValidation: true,
targetDomain: 'mail.target.com'
}
}
}
Internal DNS Mode - Use built-in DNS server (requires dnsDomain
in DcRouter config):
{
domain: 'mail.example.com',
dnsMode: 'internal-dns',
dns: {
internal: {
mxPriority: 10,
ttl: 3600
}
},
dkim: {
selector: 'mail2024',
keySize: 2048,
rotateKeys: true,
rotationInterval: 90
}
}
External DNS Mode - Use existing DNS infrastructure:
{
domain: 'mail.external.com',
dnsMode: 'external-dns',
dns: {
external: {
requiredRecords: ['MX', 'SPF', 'DKIM', 'DMARC']
}
},
rateLimits: {
inbound: {
messagesPerMinute: 100,
connectionsPerIp: 10
}
}
}
DKIM Management
DKIM is always enabled for all domains. Keys are automatically:
- Generated on first use
- Stored persistently via StorageManager
- Rotated based on configuration
- Cleaned up after grace period
Email Route Actions
Forward Action
Routes emails to external SMTP servers.
{
name: 'forward-to-internal',
match: { recipients: '*@company.com' },
action: {
type: 'forward',
forward: {
host: 'internal-mail.company.com',
port: 25,
auth: {
username: 'relay-user',
password: 'relay-pass'
},
addHeaders: {
'X-Forwarded-By': 'dcrouter'
}
}
}
}
Process Action
Full Mail Transfer Agent functionality with scanning and delivery queues.
{
name: 'process-notifications',
match: { recipients: '*@notifications.company.com' },
action: {
type: 'process',
process: {
scan: true,
dkim: true,
queue: 'priority'
}
}
}
Deliver Action
Local delivery for mailbox storage.
{
name: 'deliver-local',
match: { recipients: '*@marketing.company.com' },
action: {
type: 'deliver'
}
}
Reject Action
Reject emails with custom SMTP responses.
{
name: 'reject-spam',
match: {
senders: '*@spam-domain.com',
sizeRange: { min: 1000000 } // > 1MB
},
action: {
type: 'reject',
reject: {
code: 550,
message: 'Message rejected due to policy'
}
}
}
Common Email Routing Patterns
IP-Based Relay
Allow internal networks to relay through the server:
{
name: 'office-relay',
priority: 100,
match: { clientIp: ['192.168.0.0/16', '10.0.0.0/8'] },
action: {
type: 'forward',
forward: { host: 'internal-mail.company.com', port: 25 }
}
}
Domain-Based Routing
Route different domains to different servers:
{
name: 'partner-domain',
match: { recipients: '*@partner.com' },
action: {
type: 'forward',
forward: { host: 'partner-mail.com', port: 587 }
}
}
Authentication-Based Processing
Different handling for authenticated vs unauthenticated senders:
{
name: 'authenticated-users',
match: { authenticated: true },
action: {
type: 'process',
process: { scan: false, dkim: true, queue: 'priority' }
}
},
{
name: 'unauthenticated-reject',
match: { authenticated: false },
action: {
type: 'reject',
reject: { code: 550, message: 'Authentication required' }
}
}
Content-Based Filtering
Filter based on size, subject, or headers:
{
name: 'large-email-reject',
match: { sizeRange: { min: 25000000 } }, // > 25MB
action: {
type: 'reject',
reject: { code: 552, message: 'Message too large' }
}
},
{
name: 'priority-emails',
match: {
headers: { 'X-Priority': 'high' },
subject: /urgent|emergency/i
},
action: {
type: 'process',
process: { queue: 'priority' }
}
}
Email Security Features
Route Matching Patterns
Glob Pattern Matching
// Email address patterns
match: { recipients: '*@example.com' } // All addresses at domain
match: { recipients: 'admin@*' } // Admin at any domain
match: { senders: ['*@trusted.com', '*@partner.com'] } // Multiple patterns
// CIDR IP matching
match: { clientIp: '192.168.0.0/16' } // Private subnet
match: { clientIp: ['10.0.0.0/8', '172.16.0.0/12'] } // Multiple ranges
// Header matching
match: {
headers: {
'X-Priority': 'high',
'Subject': /urgent|emergency/i
}
}
// Size and content matching
match: {
sizeRange: { min: 1000, max: 5000000 }, // 1KB to 5MB
hasAttachments: true,
subject: /invoice|receipt/i
}
Content Scanning
const scanners = [
{
type: 'spam',
threshold: 5.0,
action: 'tag',
headers: ['X-Spam-Score', 'X-Spam-Status']
},
{
type: 'virus',
action: 'reject',
quarantine: true
},
{
type: 'attachment',
blockedExtensions: ['.exe', '.bat', '.scr'],
maxSize: 25 * 1024 * 1024 // 25MB
}
];
SmartProxy Routing
HTTP/HTTPS Routing
const routes = [
// API routing with path-based forwarding
{
name: 'api-gateway',
match: {
domains: ['api.example.com'],
ports: [443]
},
action: {
type: 'forward',
target: {
host: '192.168.1.20',
port: (context) => {
// Route based on path
if (context.path.startsWith('/v1/')) return 8080;
if (context.path.startsWith('/v2/')) return 8081;
return 8080;
}
},
tls: {
mode: 'terminate',
certificate: 'auto'
}
}
},
// Static file serving
{
name: 'static-assets',
match: {
domains: ['cdn.example.com'],
ports: [443]
},
action: {
type: 'serve',
root: '/var/www/static',
tls: {
mode: 'terminate',
certificate: 'auto'
}
}
}
];
TCP/SNI Routing
const tcpRoutes = [
// Database connection routing
{
name: 'database-cluster',
match: {
ports: [{ from: 5432, to: 5439 }]
},
action: {
type: 'forward',
target: {
host: '192.168.1.30',
port: 'preserve'
},
security: {
ipAllowList: ['192.168.1.0/24']
}
}
},
// SNI-based routing for TLS services
{
name: 'secure-service',
match: {
domains: ['secure.example.com'],
ports: [8443]
},
action: {
type: 'forward',
target: {
host: '192.168.1.40',
port: 8443
},
tls: {
mode: 'passthrough'
}
}
}
];
Storage System
StorageManager
DcRouter includes a flexible storage system that supports multiple backends:
Filesystem Storage
const router = new DcRouter({
storage: {
fsPath: '/var/lib/dcrouter/data'
}
});
Custom Storage Backend
const router = new DcRouter({
storage: {
readFunction: async (key) => {
// Read from Redis, S3, etc.
return await myDatabase.get(key);
},
writeFunction: async (key, value) => {
// Write to Redis, S3, etc.
await myDatabase.set(key, value);
}
}
});
Memory Storage (Development)
const router = new DcRouter({
// No storage config = memory storage with warning
});
Storage Usage
The storage system is used for:
- DKIM Keys:
/email/dkim/{domain}/private.key
,/email/dkim/{domain}/public.key
- Email Routes:
/email/routes/{routeId}.json
- Bounce Lists:
/email/bounces/suppression.json
- IP Reputation:
/security/ip-reputation/{ip}.json
- Domain Configs:
/email/domains/{domain}.json
Data Migration
Migrate data between storage backends:
import { StorageManager } from '@serve.zone/dcrouter';
// Export from filesystem
const fsStorage = new StorageManager({ fsPath: './data' });
const keys = await fsStorage.list('/');
const data = {};
for (const key of keys) {
data[key] = await fsStorage.get(key);
}
// Import to cloud storage
const cloudStorage = new StorageManager({
readFunction: cloudRead,
writeFunction: cloudWrite
});
for (const [key, value] of Object.entries(data)) {
await cloudStorage.set(key, value);
}
Security Features
IP Reputation Checking
import { IpReputationChecker } from '@serve.zone/dcrouter';
const ipChecker = new IpReputationChecker({
providers: ['spamhaus', 'barracuda', 'surbl'],
cacheTimeout: 3600000, // 1 hour
threshold: 0.7
});
// Check IP reputation
const result = await ipChecker.checkIp('192.0.2.1');
if (result.isBlocked) {
console.log(`IP blocked: ${result.reason}`);
}
Content Security Scanner
import { ContentScanner } from '@serve.zone/dcrouter';
const scanner = new ContentScanner({
spamThreshold: 5.0,
virusScanning: true,
attachmentFiltering: {
maxSize: 25 * 1024 * 1024,
blockedTypes: ['.exe', '.bat', '.scr']
}
});
const scanResult = await scanner.scanEmail(email);
API Reference
DcRouter Class
Constructor
constructor(options: IDcRouterOptions)
Methods
start(): Promise<void>
Starts all configured services (SmartProxy, email server, DNS server).
stop(): Promise<void>
Gracefully stops all services.
updateRoutes(routes: IRouteConfig[]): Promise<void>
Updates SmartProxy routes dynamically.
updateDomainRules(rules: IDomainRule[]): Promise<void>
Updates email domain routing rules.
getStats(): IStatsResponse
Returns real-time statistics for all services.
Email Service API
sendEmail(options: IEmailOptions): Promise<string>
const emailId = await router.emailService.sendEmail({
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'Test Email',
html: '<p>Hello World</p>',
attachments: []
});
getEmailStatus(emailId: string): IEmailStatus
const status = router.emailService.getEmailStatus(emailId);
console.log(status.status); // 'pending', 'sent', 'delivered', 'bounced'
getDeliveryReport(emailId: string): IDeliveryReport
Detailed delivery information including bounce reasons and tracking data.
Examples
Complete Enterprise Setup
import { DcRouter } from '@serve.zone/dcrouter';
const router = new DcRouter({
// HTTP/HTTPS routing
smartProxyConfig: {
routes: [
// Main website
{
name: 'website',
priority: 100,
match: { domains: ['example.com', 'www.example.com'], ports: [443] },
action: {
type: 'forward',
target: { host: '192.168.1.10', port: 80 },
tls: { mode: 'terminate', certificate: 'auto' }
}
},
// API services
{
name: 'api',
priority: 110,
match: { domains: ['api.example.com'], ports: [443] },
action: {
type: 'forward',
target: { host: '192.168.1.20', port: 8080 },
tls: { mode: 'terminate', certificate: 'auto' }
}
},
// Internal services
{
name: 'internal',
match: { ports: [{ from: 8000, to: 8999 }] },
action: {
type: 'forward',
target: { host: '192.168.1.30', port: 'preserve' },
security: { ipAllowList: ['192.168.0.0/16'] }
}
}
],
// ACME certificate automation
acme: {
email: 'ssl@example.com',
enabled: true,
useProduction: true,
autoRenew: true
}
},
// Enterprise email system
emailConfig: {
ports: [25, 587, 465],
hostname: 'mail.example.com',
// Domain configuration
domains: [
{
domain: 'example.com',
dnsMode: 'external-dns',
dkim: {
selector: 'mail',
rotateKeys: true
}
},
{
domain: 'notifications.example.com',
dnsMode: 'internal-dns',
rateLimits: {
outbound: { messagesPerHour: 10000 }
}
}
],
// Authentication configuration
auth: {
required: true,
methods: ['PLAIN', 'LOGIN']
},
// TLS configuration
tls: {
keyPath: './certs/mail-key.pem',
certPath: './certs/mail-cert.pem'
},
// Email routing rules
routes: [
// Relay from office network
{
name: 'office-relay',
priority: 100,
match: { clientIp: '192.168.0.0/16' },
action: {
type: 'forward',
forward: {
host: 'internal-mail.example.com',
port: 25
}
}
},
// Transactional emails via processing
{
name: 'notifications',
priority: 50,
match: { recipients: '*@notifications.example.com' },
action: {
type: 'process',
process: {
scan: true,
dkim: true,
queue: 'priority'
}
}
},
// Internal emails forwarded to Exchange
{
name: 'internal-mail',
priority: 25,
match: { recipients: '*@example.com' },
action: {
type: 'forward',
forward: {
host: 'exchange.internal.example.com',
port: 25
}
}
},
// Default reject
{
name: 'default-reject',
match: { recipients: '*' },
action: {
type: 'reject',
reject: {
code: 550,
message: 'Relay denied'
}
}
}
]
},
// DNS server for ACME challenges
dnsServerConfig: {
port: 53,
authoritative: true
},
// Cloudflare DNS challenges
dnsChallenge: {
cloudflareApiKey: process.env.CLOUDFLARE_API_KEY
},
// Persistent storage
storage: {
fsPath: '/var/lib/dcrouter/data'
}
});
// Start the router
await router.start();
console.log('Enterprise DcRouter started');
// Monitor statistics
setInterval(() => {
const stats = router.getStats();
console.log('Active connections:', stats.activeConnections);
console.log('Emails processed:', stats.emailsProcessed);
}, 60000);
Email Template System
import { EmailService, TemplateManager } from '@serve.zone/dcrouter';
// Setup email templates
const templateManager = new TemplateManager();
templateManager.addTemplate('welcome', {
subject: 'Welcome to {{company}}!',
html: `
<h1>Welcome {{name}}!</h1>
<p>Thank you for joining {{company}}.</p>
<p>Your account: {{email}}</p>
`,
text: 'Welcome {{name}}! Thank you for joining {{company}}.'
});
// Send templated email
const emailService = new EmailService(router);
await emailService.sendTemplatedEmail('welcome', {
to: 'user@example.com',
templateData: {
name: 'John Doe',
company: 'Example Corp',
email: 'user@example.com'
}
});
Troubleshooting
Common Issues
Certificate Issues
# Check certificate status
curl -I https://your-domain.com
# Verify ACME challenge accessibility
curl http://your-domain.com/.well-known/acme-challenge/test
Email Delivery Issues
# Test SMTP connectivity
telnet your-server.com 25
# Check DKIM record
dig TXT mail._domainkey.your-domain.com
# Verify SPF record
dig TXT your-domain.com
Email Routing Issues
Route Not Matching
- Check route priority order (higher priority = evaluated first)
- Verify glob patterns:
*@example.com
matches domain,admin@*
matches user - Test CIDR notation:
192.168.0.0/16
includes all 192.168.x.x addresses - Confirm authentication state matches your expectations
Common Route Patterns
// Debug route to log all traffic
{
name: 'debug-all',
priority: 1000,
match: { recipients: '*' },
action: { type: 'process', process: { scan: false } }
}
// Catch-all reject (should be lowest priority)
{
name: 'default-reject',
priority: 0,
match: { recipients: '*' },
action: { type: 'reject', reject: { code: 550, message: 'No route' } }
}
DNS Issues
# Test DNS server
dig @your-server.com your-domain.com
# Check DNS propagation
dig your-domain.com @8.8.8.8
Logging and Monitoring
import { SmartLog } from '@push.rocks/smartlog';
// Configure logging
const logger = new SmartLog({
level: 'info',
transport: 'console'
});
// Monitor email events
router.emailServer.on('emailReceived', (email) => {
logger.log('info', `Email received: ${email.from} -> ${email.to}`);
});
router.emailServer.on('emailSent', (result) => {
logger.log('info', `Email sent: ${result.messageId} (${result.status})`);
});
// Monitor proxy events
router.smartProxy.on('connectionEstablished', (connection) => {
logger.log('info', `Connection: ${connection.clientIp} -> ${connection.target}`);
});
Performance Tuning
const performanceConfig = {
// Connection limits
maxConnections: 1000,
connectionTimeout: 30000,
// Email queue settings
emailQueue: {
concurrency: 10,
maxRetries: 3,
retryDelay: 300000
},
// Cache settings
cache: {
ipReputation: { ttl: 3600000 }, // 1 hour
dns: { ttl: 300000 }, // 5 minutes
certificates: { ttl: 86400000 } // 24 hours
}
};
License
MIT License - see LICENSE file for details.
Testing
Comprehensive Test Suite
DcRouter includes a comprehensive test suite covering all aspects of the system:
SMTP Protocol Tests
- Commands: EHLO, HELO, MAIL FROM, RCPT TO, DATA, RSET, NOOP, QUIT, VRFY, EXPN, HELP
- Extensions: SIZE, PIPELINING, STARTTLS
- Connection Management: TLS/plain connections, timeouts, limits, rejection handling
- Error Handling: Syntax errors, invalid sequences, temporary/permanent failures
- Email Processing: Basic sending, multiple recipients, large emails, invalid addresses
- Security: Authentication, rate limiting
- Performance: Throughput testing
- Edge Cases: Very large emails, special characters
Storage and Configuration Tests
- Storage Manager: All backend types (filesystem, custom, memory)
- Integration: Component storage usage and persistence
- DNS Validation: All DNS modes (forward, internal, external)
- DNS Mode Switching: Dynamic configuration changes
- Data Migration: Moving data between storage backends
Running Tests
# Run all tests
pnpm test
# Run specific test categories
tsx test/suite/commands/test.ehlo-command.ts
tsx test/suite/connection/test.tls-connection.ts
tsx test/suite/email-processing/test.basic-email.ts
# Run with verbose output
tstest test/suite/security/test.authentication.ts --verbose
Test Infrastructure
The test suite uses a self-contained pattern where each test:
- Starts its own SMTP server instance
- Runs comprehensive test scenarios
- Cleans up all resources
- Provides detailed logging for debugging
This ensures tests are isolated, reliable, and can run in parallel.
Support
- Documentation: https://docs.serve.zone/dcrouter
- Issues: https://github.com/serve-zone/dcrouter/issues
- Community: https://community.serve.zone