- Add socket-handler mode eliminating internal port binding for improved performance - Add `dnsDomain` config option for automatic DNS-over-HTTPS (DoH) setup - Add `useSocketHandler` flag to email config for direct socket processing - Update SmartProxy route generation to support socket-handler actions - Integrate smartdns with manual HTTPS mode for DoH without port binding - Add automatic route creation for DNS paths when dnsDomain is configured - Update documentation with socket-handler configuration and benefits - Improve resource efficiency by eliminating internal port forwarding
9.4 KiB
9.4 KiB
DcRouter Socket-Handler Integration Plan
First line: Remember to reread CLAUDE.md file for guidelines.
Overview
Integrate socket-handler support for both DNS and Mail services in DcRouter, allowing smartproxy to pass sockets directly instead of servers listening on ports.
Core Logic
- DNS: If dnsDomain is set, DnsServer is instantiated with socket-handler for HTTPS/DoH
- Mail: If useSocketHandler is enabled in emailConfig, mail servers accept sockets from smartproxy
- Automatic Routing: Setting these options automatically configures smartproxy routes
Architecture
DNS Architecture
- HTTPS/DoH Traffic: smartproxy → socket-handler → smartdns (no port listening)
- UDP Traffic: Direct to smartdns DnsServer on VM IP:53 (bypasses smartproxy)
- Automatic Setup: Setting dnsDomain triggers all DNS infrastructure
Mail Architecture
- Socket-Handler Mode: smartproxy → socket-handler → mail server (no port listening)
- Traditional Mode: smartproxy → forward → mail server (listening on ports)
- Configurable: useSocketHandler flag determines the mode
Implementation Steps
1. Analyze Current Architecture
- Examine how DcRouter currently integrates services
- Study email server socket handling in SmtpServer
- Check existing smartproxy socket-handler patterns
- Review UnifiedEmailServer connection handling
2. DNS Socket-Handler Implementation
2.1 Create DNS Socket Handler
- Create a custom socket handler that processes DNS-over-HTTPS requests
- Handler should use smartdns without port binding
- Use built-in handleHttpsSocket method from smartdns
- Set manualHttpsMode: true in DnsServer options
2.2 Configure smartdns DnsServer
- Create DnsServer instance with UDP only on VM IP interface
- Set manualHttpsMode: true to disable HTTPS port binding
- Configure to listen on port 53 for UDP traffic only
- Use handleHttpsSocket method for DoH sockets
3. Mail Socket-Handler Implementation
3.1 Modify SmtpServer
- ConnectionManager already has handleConnection method
- Connection handling already works with provided sockets
- Session management works with socket-handler mode
- Backward compatibility maintained
3.2 Update UnifiedEmailServer
- Add useSocketHandler flag to IUnifiedEmailServerOptions
- Modify start() to skip server creation when useSocketHandler is true
- Add handleSocket method to accept sockets from smartproxy
- All email processing works in socket-handler mode
3.3 Create Mail Socket Handler
- Create socket handler for SMTP/submission/SMTPS
- Handle TLS for port 465 (immediate TLS wrapping)
- Pass sockets to UnifiedEmailServer.handleSocket
4. DcRouter Integration
4.1 Configuration Updates
- Add
dnsDomain
property to DcRouter config - Add
useSocketHandler
to email config options - Update interface definitions
4.2 Route Generation Updates
- Modify generateEmailRoutes to create socket-handler actions when enabled
- Create DNS routes with socket-handler actions
- Ensure proper domain and path matching
4.3 Service Lifecycle
- Update setupSmartProxy to handle socket-handler routes
- Services start correctly without port binding
- Socket cleanup handled by connection managers
5. SmartProxy Route Configuration
- DNS routes: match dnsDomain with paths /dns-query and /resolve
- Mail routes: match ports 25, 587, 465 with socket-handler actions
- Configure TLS handling for each protocol appropriately
- Automatic Let's Encrypt via smartproxy certificate: 'auto'
6. Testing (To be done)
6.1 DNS Testing
- Test that DNS server is NOT instantiated when dnsDomain is not set
- Test that DNS server IS instantiated when dnsDomain is set
- Test UDP DNS queries on port 53
- Test DoH queries through smartproxy socket-handler
- Verify HTTP/2 support for DoH
6.2 Mail Testing
- Test traditional port-based mail delivery
- Test socket-handler mail delivery
- Verify STARTTLS works in socket-handler mode
- Test SMTPS (port 465) with socket-handler
- Ensure connection pooling works correctly
6.3 Integration Testing
- Test both DNS and Mail with socket-handlers simultaneously
- Verify no port conflicts
- Test automatic startup/shutdown
- Load test socket-handler performance
Technical Details
DcRouter Configuration
// DcRouter config with socket-handler support
const dcRouterConfig = {
// ... other config
dnsDomain: 'example.com', // Optional - if set, DNS server is enabled
emailConfig: {
ports: [25, 587, 465],
domains: ['mail.example.com'],
useSocketHandler: true, // Enable socket-handler mode for mail
routes: [/* email routing rules */]
}
}
DNS Implementation
Conditional DNS Instantiation
// In DcRouter startup logic
if (config.dnsDomain) {
// Create DNS server instance
this.dnsServer = new DnsServer({
udpPort: 53,
udpBindAddress: vmIpAddress,
httpsPort: undefined, // No HTTPS listening
dnssecZone: config.dnsDomain
});
// Create smartproxy route for DoH
const dnsRoute = {
match: {
domain: config.dnsDomain,
path: ['/dns-query', '/resolve']
},
action: {
type: 'socket-handler',
handler: this.createDnsSocketHandler()
}
};
}
DNS Socket Handler
const createDnsSocketHandler = () => {
return async (socket: net.Socket) => {
// Handle HTTP/2 for DoH
const session = http2.createSession(socket);
session.on('stream', async (stream, headers) => {
if (headers[':path'] === '/dns-query') {
const dnsQuery = await parseDnsQuery(stream);
const response = await dnsServer.resolveQuery(dnsQuery);
stream.respond({ ':status': 200, 'content-type': 'application/dns-message' });
stream.end(response);
}
});
};
}
Mail Implementation
Email Route Generation with Socket-Handler
private generateEmailRoutes(emailConfig: IUnifiedEmailServerOptions): IRouteConfig[] {
const routes: IRouteConfig[] = [];
for (const port of emailConfig.ports) {
const action = emailConfig.useSocketHandler
? {
type: 'socket-handler',
handler: this.createMailSocketHandler(port)
}
: {
type: 'forward',
target: { host: 'localhost', port: mapPort(port) }
};
routes.push({
match: { ports: [port] },
action
});
}
return routes;
}
Mail Socket Handler
const createMailSocketHandler = (port: number) => {
return async (socket: net.Socket) => {
// Determine protocol based on port
const isSecure = port === 465;
if (isSecure) {
// For SMTPS, handle TLS immediately
const tlsSocket = new tls.TLSSocket(socket, {
isServer: true,
cert: tlsCert,
key: tlsKey
});
await this.emailServer.handleSocket(tlsSocket, port);
} else {
// For SMTP/Submission, pass raw socket
await this.emailServer.handleSocket(socket, port);
}
};
}
UnifiedEmailServer Socket Handling
// In UnifiedEmailServer class
public async handleSocket(socket: net.Socket, port: number): Promise<void> {
// Create session for this socket
const session = this.sessionManager.createSession(socket);
// Handle connection based on port
switch (port) {
case 25: // SMTP
case 587: // Submission (STARTTLS)
await this.connectionManager.handleConnection(socket, session);
break;
case 465: // SMTPS (already TLS)
await this.connectionManager.handleSecureConnection(socket, session);
break;
}
}
## Dependencies
- @push.rocks/smartproxy (already integrated)
- @push.rocks/smartdns (to be added)
## Implementation Phases
### Phase 1: DNS Socket-Handler (Priority)
1. Add smartdns dependency
2. Implement DNS socket-handler
3. Add dnsDomain configuration
4. Test DoH functionality
### Phase 2: Mail Socket-Handler
1. Refactor SmtpServer for socket handling
2. Update UnifiedEmailServer
3. Implement mail socket-handlers
4. Add useSocketHandler configuration
5. Test all mail protocols
### Phase 3: Integration & Testing
1. Full integration testing
2. Performance benchmarking
3. Documentation updates
4. Migration guide for existing users
## Notes
### DNS Notes
- UDP traffic bypasses proxy entirely (kernel-level routing)
- DoH provides encrypted DNS over HTTPS through proxy
- Socket handler allows DNS processing without port binding
- DNS functionality is entirely optional - only enabled when dnsDomain is configured
- Setting dnsDomain triggers automatic setup of all DNS infrastructure
- Automatic Let's Encrypt certificate provisioning for configured dnsDomain
### Mail Notes
- Socket-handler mode eliminates internal port binding for mail services
- Traditional port forwarding mode remains available for compatibility
- STARTTLS negotiation handled within socket-handler for ports 25/587
- Port 465 (SMTPS) requires immediate TLS handshake in socket-handler
- Connection pooling and session management work in both modes
- Socket-handler reduces latency by eliminating internal forwarding
### General Benefits
- Reduced resource usage (no internal port binding)
- Better performance (direct socket passing)
- Simplified configuration (automatic route creation)
- Enhanced security (no exposed internal ports)
- Unified approach for all services through smartproxy