feat(socket-handler): implement direct socket passing for DNS and email services

- 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
This commit is contained in:
2025-05-29 16:26:19 +00:00
parent 6c8458f63c
commit b11fea7334
9 changed files with 687 additions and 540 deletions

View File

@ -49,6 +49,7 @@ export interface IUnifiedEmailServerOptions {
domains: string[]; // Domains to handle email for
banner?: string;
debug?: boolean;
useSocketHandler?: boolean; // Use socket-handler mode instead of port listening
// Authentication options
auth?: {
@ -336,6 +337,13 @@ export class UnifiedEmailServer extends EventEmitter {
logger.log('info', 'Automatic DKIM configuration completed');
}
// Skip server creation in socket-handler mode
if (this.options.useSocketHandler) {
logger.log('info', 'UnifiedEmailServer started in socket-handler mode (no port listening)');
this.emit('started');
return;
}
// Ensure we have the necessary TLS options
const hasTlsConfig = this.options.tls?.keyPath && this.options.tls?.certPath;
@ -446,6 +454,54 @@ export class UnifiedEmailServer extends EventEmitter {
}
}
/**
* Handle a socket from smartproxy in socket-handler mode
* @param socket The socket to handle
* @param port The port this connection is for (25, 587, 465)
*/
public async handleSocket(socket: plugins.net.Socket | plugins.tls.TLSSocket, port: number): Promise<void> {
if (!this.options.useSocketHandler) {
logger.log('error', 'handleSocket called but useSocketHandler is not enabled');
socket.destroy();
return;
}
logger.log('info', `Handling socket for port ${port}`);
// Create a temporary SMTP server instance for this connection
// We need a full server instance because the SMTP protocol handler needs all components
const smtpServerOptions = {
port,
hostname: this.options.hostname,
key: this.options.tls?.keyPath ? plugins.fs.readFileSync(this.options.tls.keyPath, 'utf8') : undefined,
cert: this.options.tls?.certPath ? plugins.fs.readFileSync(this.options.tls.certPath, 'utf8') : undefined
};
// Create the SMTP server instance
const smtpServer = createSmtpServer(this, smtpServerOptions);
// Get the connection manager from the server
const connectionManager = (smtpServer as any).connectionManager;
if (!connectionManager) {
logger.log('error', 'Could not get connection manager from SMTP server');
socket.destroy();
return;
}
// Determine if this is a secure connection
// Port 465 uses implicit TLS, so the socket is already secure
const isSecure = port === 465 || socket instanceof plugins.tls.TLSSocket;
// Pass the socket to the connection manager
try {
await connectionManager.handleConnection(socket, isSecure);
} catch (error) {
logger.log('error', `Error handling socket connection: ${error.message}`);
socket.destroy();
}
}
/**
* Stop the unified email server
*/