@@ -9,7 +9,6 @@ const os = require('os');
99const bounces = require ( './bounces' ) ;
1010const Headers = require ( '@zone-eu/mailsplit' ) . Headers ;
1111const SMTPConnection = require ( 'nodemailer/lib/smtp-connection' ) ;
12- const tls = require ( 'tls' ) ;
1312const dkimSign = require ( './dkim-sign' ) ;
1413const StreamHash = require ( './stream-hash' ) ;
1514const EventEmitter = require ( 'events' ) ;
@@ -20,6 +19,7 @@ const mxConnect = require('mx-connect');
2019const addressTools = require ( './address-tools' ) ;
2120const libmime = require ( 'libmime' ) ;
2221const db = require ( './db' ) ;
22+ const tlsRetry = require ( './tls-retry' ) ;
2323const base32 = require ( 'base32.js' ) ;
2424const { gelfCode, emitGelf } = require ( './log-gelf' ) ;
2525
@@ -1097,6 +1097,7 @@ class Sender extends EventEmitter {
10971097 let mxLastError = false ;
10981098 let ignoreMXHosts = [ ] ;
10991099 let ignoreTLS = ! ! this . zone . ignoreTLS || false ;
1100+ let reducedClientHelloHosts = new Set ( ) ;
11001101
11011102 let tryConnect = ( ) => {
11021103 delivery . mxPort = delivery . mxPort || this . zone . port || 25 ;
@@ -1295,6 +1296,7 @@ class Sender extends EventEmitter {
12951296 ) ;
12961297
12971298 delivery . mxHostname = mx . hostname || mx . host ;
1299+ let reducedClientHello = reducedClientHelloHosts . has ( delivery . mxHostname ) ;
12981300
12991301 let options = {
13001302 servername : mx . hostname ,
@@ -1319,11 +1321,7 @@ class Sender extends EventEmitter {
13191321 connectionTimeout : 5 * 60 * 1000 ,
13201322 greetingTimeout : 2 * 60 * 1000 ,
13211323
1322- tls : {
1323- servername : mx . hostname ,
1324- rejectUnauthorized : enforceTLS ,
1325- minVersion : enforceTLS ? 'TLSv1.2' : 'TLSv1'
1326- } ,
1324+ tls : tlsRetry . getTlsOptions ( mx . hostname , enforceTLS , reducedClientHello ) ,
13271325
13281326 transactionLog : true ,
13291327 logger : {
@@ -1370,13 +1368,27 @@ class Sender extends EventEmitter {
13701368 err . temporary = true ;
13711369 }
13721370
1373- if (
1374- ( err . code === 'ETLS' ||
1375- / S S L 2 3 _ G E T _ S E R V E R _ H E L L O | \/ d e p s \/ o p e n s s l | s s l 3 _ c h e c k | s s l 3 _ g e t _ r e c o r d | S S L r o u t i n e s / i. test ( err . message ) ||
1376- err . code === 'ECONNRESET' ) &&
1377- ! ignoreTLS &&
1378- ! enforceTLS
1379- ) {
1371+ let tlsAttempted = tlsRetry . isTlsAttempted ( connection , options . secure ) ;
1372+
1373+ if ( tlsRetry . shouldRetryWithReducedClientHello ( tlsAttempted , reducedClientHello , err ) ) {
1374+ log . info (
1375+ this . logName ,
1376+ 'id=%s %s.%s ERRCONNECT [%s] Failed to connect to %s[%s] using %s, retrying once with a reduced TLS ClientHello. %s' ,
1377+ delivery . sessionId ,
1378+ delivery . id ,
1379+ delivery . seq ,
1380+ connId ,
1381+ mx . hostname ,
1382+ mx . host ,
1383+ options . secure ? 'SSL/TLS' : 'STARTTLS' ,
1384+ err . message
1385+ ) ;
1386+ plugins . handler . runHooks ( 'sender:tlserror' , [ delivery , options , err ] , ( ) => false ) ;
1387+ reducedClientHelloHosts . add ( delivery . mxHostname ) ;
1388+ return tryConnect ( ) ;
1389+ }
1390+
1391+ if ( tlsRetry . shouldRetryWithoutTls ( ignoreTLS , enforceTLS , options . secure , err ) ) {
13801392 // STARTTLS failed, try again, this time without encryption
13811393 log . info (
13821394 this . logName ,
@@ -1482,7 +1494,7 @@ class Sender extends EventEmitter {
14821494 }
14831495 // still have not returned, this means we have an unexpected connection close
14841496 let err = new Error ( 'Unexpected socket close' ) ;
1485- if ( connection . _socket instanceof tls . TLSSocket || ( connection . _socket && connection . _socket . upgrading ) ) {
1497+ if ( tlsRetry . isTlsAttempted ( connection ) ) {
14861498 err . code = 'ETLS' ;
14871499 }
14881500 _onError ( err ) ;
0 commit comments